// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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
//
//   http://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 is copied from
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Common/Dwarf.cpp
// and modified by Doris

#if defined(__ELF__) && !defined(__FreeBSD__)

/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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
 *
 *   http://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 was edited for ClickHouse.
  */

#include "common/dwarf.h"

#include <cstring>

#include "common/elf.h"
#include "common/logging.h"

#define DW_CHILDREN_no 0

#define DW_FORM_addr 1
#define DW_FORM_block1 0x0a
#define DW_FORM_block2 3
#define DW_FORM_block4 4
#define DW_FORM_block 9
#define DW_FORM_exprloc 0x18
#define DW_FORM_data1 0x0b
#define DW_FORM_ref1 0x11
#define DW_FORM_data2 0x05
#define DW_FORM_ref2 0x12
#define DW_FORM_data4 0x06
#define DW_FORM_ref4 0x13
#define DW_FORM_data8 0x07
#define DW_FORM_ref8 0x14
#define DW_FORM_ref_sig8 0x20
#define DW_FORM_sdata 0x0d
#define DW_FORM_udata 0x0f
#define DW_FORM_ref_udata 0x15
#define DW_FORM_flag 0x0c
#define DW_FORM_flag_present 0x19
#define DW_FORM_sec_offset 0x17
#define DW_FORM_ref_addr 0x10
#define DW_FORM_string 0x08
#define DW_FORM_strp 0x0e
#define DW_FORM_indirect 0x16
#define DW_FORM_strx 0x1a
#define DW_FORM_addrx 0x1b
#define DW_FORM_ref_sup4 0x1c
#define DW_FORM_strp_sup 0x1d
#define DW_FORM_data16 0x1e
#define DW_FORM_line_strp 0x1f
#define DW_FORM_implicit_const 0x21
#define DW_FORM_rnglistx 0x23
#define DW_FORM_loclistx 0x22
#define DW_FORM_ref_sup8 0x24
#define DW_FORM_strx1 0x25
#define DW_FORM_strx2 0x26
#define DW_FORM_strx3 0x27
#define DW_FORM_strx4 0x28
#define DW_FORM_addrx1 0x29
#define DW_FORM_addrx2 0x2a
#define DW_FORM_addrx3 0x2b
#define DW_FORM_addrx4 0x2c

#define DW_TAG_compile_unit 0x11
#define DW_TAG_subprogram 0x2e
#define DW_TAG_try_block 0x32
#define DW_TAG_catch_block 0x25
#define DW_TAG_entry_point 0x03
#define DW_TAG_common_block 0x1a
#define DW_TAG_lexical_block 0x0b

#define DW_AT_stmt_list 0x10
#define DW_AT_comp_dir 0x1b
#define DW_AT_name 0x03
#define DW_AT_high_pc 0x12
#define DW_AT_low_pc 0x11
#define DW_AT_entry_pc 0x52
#define DW_AT_ranges 0x55
#define DW_AT_abstract_origin 0x31
#define DW_AT_call_line 0x59
#define DW_AT_call_file 0x58
#define DW_AT_linkage_name 0x6e
#define DW_AT_specification 0x47
#define DW_AT_str_offsets_base 0x72
#define DW_AT_addr_base 0x73
#define DW_AT_rnglists_base 0x74
#define DW_AT_loclists_base 0x8c
#define DW_AT_GNU_ranges_base 0x2132
#define DW_AT_GNU_addr_base 0x2133

#define DW_LNE_define_file 0x03
#define DW_LNS_copy 0x01
#define DW_LNS_advance_pc 0x02
#define DW_LNS_advance_line 0x03
#define DW_LNS_set_file 0x04
#define DW_LNS_set_column 0x05
#define DW_LNS_negate_stmt 0x06
#define DW_LNS_set_basic_block 0x07
#define DW_LNS_const_add_pc 0x08
#define DW_LNS_fixed_advance_pc 0x09
#define DW_LNS_set_prologue_end 0x0a
#define DW_LNS_set_epilogue_begin 0x0b
#define DW_LNS_set_isa 0x0c
#define DW_LNE_end_sequence 0x01
#define DW_LNE_set_address 0x02
#define DW_LNE_set_discriminator 0x04

#define DW_LNCT_path 0x1
#define DW_LNCT_directory_index 0x2
#define DW_LNCT_timestamp 0x3
#define DW_LNCT_size 0x4
#define DW_LNCT_MD5 0x5

#define DW_RLE_end_of_list 0x0
#define DW_RLE_base_addressx 0x1
#define DW_RLE_startx_endx 0x2
#define DW_RLE_startx_length 0x3
#define DW_RLE_offset_pair 0x4
#define DW_RLE_base_address 0x5
#define DW_RLE_start_end 0x6
#define DW_RLE_start_length 0x7

namespace doris {
#include "common/compile_check_avoid_begin.h"

Dwarf::Dwarf(const std::shared_ptr<Elf>& elf)
        : elf_(elf),
          abbrev_(getSection(".debug_abbrev")),
          addr_(getSection(".debug_addr")),
          aranges_(getSection(".debug_aranges")),
          info_(getSection(".debug_info")),
          line_(getSection(".debug_line")),
          line_str_(getSection(".debug_line_str")),
          loclists_(getSection(".debug_loclists")),
          ranges_(getSection(".debug_ranges")),
          rnglists_(getSection(".debug_rnglists")),
          str_(getSection(".debug_str")),
          str_offsets_(getSection(".debug_str_offsets")) {
    // Optional sections:
    //  - debugAranges_: for fast address range lookup.
    //     If missing .debug_info can be used - but it's much slower (linear
    //     scan).
    //  - debugRanges_ (DWARF 4) / debugRnglists_ (DWARF 5): non-contiguous
    //    address ranges of debugging information entries.
    //    Used for inline function address lookup.
    if (info_.empty() || abbrev_.empty() || line_.empty() || str_.empty()) {
        elf_ = nullptr;
    }
}

Dwarf::Section::Section(std::string_view d) : is64_bit(false), data(d) {}

#define SAFE_CHECK(cond, ...)                                \
    do {                                                     \
        if (!(cond)) LOG(FATAL) << fmt::format(__VA_ARGS__); \
    } while (false)

namespace {
// Maximum number of DIEAbbreviation to cache in a compilation unit. Used to
// speed up inline function lookup.
const uint32_t kMaxAbbreviationEntries = 1000;

// All following read* functions read from a std::string_view, advancing the
// std::string_view, and aborting if there's not enough room.

// Read (bitwise) one object of type T
template <typename T>
    requires std::is_trivial_v<T> && std::is_standard_layout_v<T>
T read(std::string_view& sp) {
    SAFE_CHECK(sp.size() >= sizeof(T), "underflow: expected bytes {}, got bytes {}", sizeof(T),
               sp.size());
    T x;
    memcpy(&x, sp.data(), sizeof(T));
    sp.remove_prefix(sizeof(T));
    return x;
}

// Read (bitwise) an unsigned number of N bytes (N in 1, 2, 3, 4).
template <size_t N>
uint64_t readU64(std::string_view& sp) {
    SAFE_CHECK(sp.size() >= N, "underflow");
    uint64_t x = 0;
    memcpy(&x, sp.data(), N);
    sp.remove_prefix(N);
    return x;
}

// Read ULEB (unsigned) varint value; algorithm from the DWARF spec
uint64_t readULEB(std::string_view& sp, uint8_t& shift, uint8_t& val) {
    uint64_t r = 0;
    shift = 0;
    do {
        val = read<uint8_t>(sp);
        r |= (uint64_t(val & 0x7f) << shift);
        shift += 7;
    } while (val & 0x80);
    return r;
}

uint64_t readULEB(std::string_view& sp) {
    uint8_t shift;
    uint8_t val;
    return readULEB(sp, shift, val);
}

// Read SLEB (signed) varint value; algorithm from the DWARF spec
int64_t readSLEB(std::string_view& sp) {
    uint8_t shift;
    uint8_t val;
    uint64_t r = readULEB(sp, shift, val);

    if (shift < 64 && (val & 0x40)) {
        r |= -(1ULL << shift); // sign extend
    }

    return r;
}

// Read a value of "section offset" type, which may be 4 or 8 bytes
uint64_t readOffset(std::string_view& sp, bool is64_bit) {
    return is64_bit ? read<uint64_t>(sp) : read<uint32_t>(sp);
}

// Read "len" bytes
std::string_view readBytes(std::string_view& sp, uint64_t len) {
    SAFE_CHECK(len <= sp.size(), "invalid string length: {} vs. {}", len, sp.size());
    std::string_view ret(sp.data(), len);
    sp.remove_prefix(len);
    return ret;
}

// Read a null-terminated string
std::string_view readNullTerminated(std::string_view& sp) {
    const char* p = static_cast<const char*>(memchr(sp.data(), 0, sp.size()));
    SAFE_CHECK(p, "invalid null-terminated string");
    std::string_view ret(sp.data(), p - sp.data());
    sp = std::string_view(p + 1, sp.size());
    return ret;
}

// Get a string from the section
std::string_view getStringFromStringSection(std::string_view section, uint64_t offset) {
    SAFE_CHECK(offset < section.size(), "invalid section offset");
    std::string_view sp(section);
    sp.remove_prefix(offset);
    return readNullTerminated(sp);
}

// Skip over padding until sp.data() - start is a multiple of alignment
void skipPadding(std::string_view& sp, const char* start, size_t alignment) {
    size_t remainder = (sp.data() - start) % alignment;
    if (remainder) {
        SAFE_CHECK(alignment - remainder <= sp.size(), "invalid padding");
        sp.remove_prefix(alignment - remainder);
    }
}

} // namespace

Dwarf::Path::Path(std::string_view baseDir, std::string_view subDir, std::string_view file)
        : baseDir_(baseDir), subDir_(subDir), file_(file) {
    // Normalize
    if (file_.empty()) {
        baseDir_ = {};
        subDir_ = {};
        return;
    }

    if (file_[0] == '/') {
        // file_ is absolute
        baseDir_ = {};
        subDir_ = {};
    }

    if (!subDir_.empty() && subDir_[0] == '/') {
        baseDir_ = {}; // subDir_ is absolute
    }

    // Make sure it's never the case that baseDir_ is empty, but subDir_ isn't.
    if (baseDir_.empty()) {
        swap(baseDir_, subDir_);
    }
}

size_t Dwarf::Path::size() const {
    size_t size = 0;
    bool needs_slash = false;

    if (!baseDir_.empty()) {
        size += baseDir_.size();
        needs_slash = baseDir_.back() != '/';
    }

    if (!subDir_.empty()) {
        size += needs_slash;
        size += subDir_.size();
        needs_slash = subDir_.back() != '/';
    }

    if (!file_.empty()) {
        size += needs_slash;
        size += file_.size();
    }

    return size;
}

size_t Dwarf::Path::toBuffer(char* buf, size_t bufSize) const {
    size_t total_size = 0;
    bool needs_slash = false;

    auto append = [&](std::string_view sp) {
        if (bufSize >= 2) {
            size_t to_copy = std::min(sp.size(), bufSize - 1);
            memcpy(buf, sp.data(), to_copy);
            buf += to_copy;
            bufSize -= to_copy;
        }
        total_size += sp.size();
    };

    if (!baseDir_.empty()) {
        append(baseDir_);
        needs_slash = baseDir_.back() != '/';
    }
    if (!subDir_.empty()) {
        if (needs_slash) {
            append("/");
        }
        append(subDir_);
        needs_slash = subDir_.back() != '/';
    }
    if (!file_.empty()) {
        if (needs_slash) {
            append("/");
        }
        append(file_);
    }
    if (bufSize) {
        *buf = '\0';
    }

    SAFE_CHECK(total_size == size(), "Size mismatch");
    return total_size;
}

void Dwarf::Path::toString(std::string& dest) const {
    size_t initial_size = dest.size();
    dest.reserve(initial_size + size());
    if (!baseDir_.empty()) {
        dest.append(baseDir_.begin(), baseDir_.end());
    }
    if (!subDir_.empty()) {
        if (!dest.empty() && dest.back() != '/') {
            dest.push_back('/');
        }
        dest.append(subDir_.begin(), subDir_.end());
    }
    if (!file_.empty()) {
        if (!dest.empty() && dest.back() != '/') {
            dest.push_back('/');
        }
        dest.append(file_.begin(), file_.end());
    }
    SAFE_CHECK(dest.size() == initial_size + size(), "Size mismatch");
}

// Next chunk in section
bool Dwarf::Section::next(std::string_view& chunk) {
    chunk = data;
    if (chunk.empty()) {
        return false;
    }

    // Initial length is a uint32_t value for a 32-bit section, and
    // a 96-bit value (0xffffffff followed by the 64-bit length) for a 64-bit
    // section.
    auto initial_length = read<uint32_t>(chunk);
    is64_bit = (initial_length == uint32_t(-1));
    auto length = is64_bit ? read<uint64_t>(chunk) : initial_length;
    SAFE_CHECK(length <= chunk.size(), "invalid DWARF section");
    chunk = std::string_view(chunk.data(), length);
    data = std::string_view(chunk.end(), data.end() - chunk.end());
    return true;
}

std::string_view Dwarf::getSection(const char* name) const {
    std::optional<Elf::Section> elf_section = elf_->findSectionByName(name);
    if (!elf_section) {
        return {};
    }

#ifdef SHF_COMPRESSED
    if (elf_section->header.sh_flags & SHF_COMPRESSED) {
        return {};
    }
#endif

    return {elf_section->begin(), elf_section->size()};
}

// static
bool Dwarf::readAbbreviation(std::string_view& section, DIEAbbreviation& abbr) {
    // abbreviation code
    abbr.code = readULEB(section);
    if (abbr.code == 0) {
        return false;
    }

    // abbreviation tag
    abbr.tag = readULEB(section);

    // does this entry have children?
    abbr.has_children = (read<uint8_t>(section) != DW_CHILDREN_no);

    // attributes
    const char* attribute_begin = section.data();
    for (;;) {
        SAFE_CHECK(!section.empty(), "invalid attribute section");
        auto attr = readAttributeSpec(section);
        if (attr.name == 0 && attr.form == 0) {
            break;
        }
    }

    abbr.attributes = std::string_view(attribute_begin, section.data() - attribute_begin);
    return true;
}

// static
void Dwarf::readCompilationUnitAbbrs(std::string_view abbrev, CompilationUnit& cu) {
    abbrev.remove_prefix(cu.abbrev_offset);

    DIEAbbreviation abbr;
    while (readAbbreviation(abbrev, abbr)) {
        // Abbreviation code 0 is reserved for null debugging information entries.
        if (abbr.code != 0 && abbr.code <= kMaxAbbreviationEntries) {
            cu.abbr_cache[abbr.code - 1] = abbr;
        }
    }
}

size_t Dwarf::forEachChild(const CompilationUnit& cu, const Die& die,
                           std::function<bool(const Die& die)> f) const {
    size_t next_die_offset = forEachAttribute(cu, die, [&](const Attribute&) { return true; });
    if (!die.abbr.has_children) {
        return next_die_offset;
    }

    auto child_die = getDieAtOffset(cu, next_die_offset);
    while (child_die.code != 0) {
        if (!f(child_die)) {
            return child_die.offset;
        }

        // NOTE: Don't run `f` over grandchildren, just skip over them.
        size_t sibling_offset = forEachChild(cu, child_die, [](const Die&) { return true; });
        child_die = getDieAtOffset(cu, sibling_offset);
    }

    // childDie is now a dummy die whose offset is to the code 0 marking the
    // end of the children. Need to add one to get the offset of the next die.
    return child_die.offset + 1;
}

/*
 * Iterate over all attributes of the given DIE, calling the given callable
 * for each. Iteration is stopped early if any of the calls return false.
 */
size_t Dwarf::forEachAttribute(const CompilationUnit& cu, const Die& die,
                               std::function<bool(const Attribute& die)> f) const {
    auto attrs = die.abbr.attributes;
    auto values = std::string_view {info_.data() + die.offset + die.attr_offset,
                                    cu.offset + cu.size - die.offset - die.attr_offset};
    while (auto spec = readAttributeSpec(attrs)) {
        auto attr = readAttribute(cu, die, spec, values);
        if (!f(attr)) {
            return static_cast<size_t>(-1);
        }
    }
    return values.data() - info_.data();
}

Dwarf::Attribute Dwarf::readAttribute(const CompilationUnit& cu, const Die& die, AttributeSpec spec,
                                      std::string_view& info) const {
    // DWARF 5 introduces new FORMs whose values are relative to some base attrs:
    // DW_AT_str_offsets_base, DW_AT_rnglists_base, DW_AT_addr_base.
    // Debug Fission DWARF 4 uses GNU DW_AT_GNU_ranges_base & DW_AT_GNU_addr_base.
    //
    // The order in which attributes appear in a CU is not defined.
    // The DW_AT_*_base attrs may appear after attributes that need them.
    // The DW_AT_*_base attrs are CU specific; so we read them just after
    // reading the CU header. During this first pass return empty values
    // when encountering a FORM that depends on DW_AT_*_base.
    auto get_string_using_offset_table = [&](uint64_t index) {
        if (!cu.str_offsets_base.has_value()) {
            return std::string_view();
        }
        // DWARF 5: 7.26 String Offsets Table
        // The DW_AT_str_offsets_base attribute points to the first entry following
        // the header. The entries are indexed sequentially from this base entry,
        // starting from 0.
        auto sp = str_offsets_.substr(*cu.str_offsets_base +
                                      index * (cu.is64Bit ? sizeof(uint64_t) : sizeof(uint32_t)));
        uint64_t str_offset = readOffset(sp, cu.is64Bit);
        return getStringFromStringSection(str_, str_offset);
    };

    auto read_debug_addr = [&](uint64_t index) {
        if (!cu.addr_base.has_value()) {
            return uint64_t(0);
        }
        // DWARF 5: 7.27 Address Table
        // The DW_AT_addr_base attribute points to the first entry following the
        // header. The entries are indexed sequentially from this base entry,
        // starting from 0.
        auto sp = addr_.substr(*cu.addr_base + index * sizeof(uint64_t));
        return read<uint64_t>(sp);
    };

    switch (spec.form) {
    case DW_FORM_addr:
        return {spec, die, read<uintptr_t>(info)};
    case DW_FORM_block1:
        return {spec, die, readBytes(info, read<uint8_t>(info))};
    case DW_FORM_block2:
        return {spec, die, readBytes(info, read<uint16_t>(info))};
    case DW_FORM_block4:
        return {spec, die, readBytes(info, read<uint32_t>(info))};
    case DW_FORM_block:
        [[fallthrough]];
    case DW_FORM_exprloc:
        return {spec, die, readBytes(info, readULEB(info))};
    case DW_FORM_data1:
        [[fallthrough]];
    case DW_FORM_ref1:
        return {spec, die, read<uint8_t>(info)};
    case DW_FORM_data2:
        [[fallthrough]];
    case DW_FORM_ref2:
        return {spec, die, read<uint16_t>(info)};
    case DW_FORM_data4:
        [[fallthrough]];
    case DW_FORM_ref4:
        return {spec, die, read<uint32_t>(info)};
    case DW_FORM_data8:
        [[fallthrough]];
    case DW_FORM_ref8:
        [[fallthrough]];
    case DW_FORM_ref_sig8:
        return {spec, die, read<uint64_t>(info)};
    case DW_FORM_sdata:
        return {spec, die, static_cast<uint64_t>(readSLEB(info))};
    case DW_FORM_udata:
        [[fallthrough]];
    case DW_FORM_ref_udata:
        return {spec, die, readULEB(info)};
    case DW_FORM_flag:
        return {spec, die, read<uint8_t>(info)};
    case DW_FORM_flag_present:
        return {spec, die, 1ULL};
    case DW_FORM_sec_offset:
        [[fallthrough]];
    case DW_FORM_ref_addr:
        return {spec, die, readOffset(info, die.is64Bit)};
    case DW_FORM_string:
        return {spec, die, readNullTerminated(info)};
    case DW_FORM_strp:
        return {spec, die, getStringFromStringSection(str_, readOffset(info, die.is64Bit))};
    case DW_FORM_indirect: // form is explicitly specified
        // Update spec with the actual FORM.
        spec.form = readULEB(info);
        return readAttribute(cu, die, spec, info);

    // DWARF 5:
    case DW_FORM_implicit_const: // form is explicitly specified
        // For attributes with this form, the attribute specification contains a
        // third part, which is a signed LEB128 number. The value of this number
        // is used as the value of the attribute, and no value is stored in the
        // .debug_info section.
        return {spec, die, static_cast<uint64_t>(spec.implicitConst)};

    case DW_FORM_addrx:
        return {spec, die, read_debug_addr(readULEB(info))};
    case DW_FORM_addrx1:
        return {spec, die, read_debug_addr(readU64<1>(info))};
    case DW_FORM_addrx2:
        return {spec, die, read_debug_addr(readU64<2>(info))};
    case DW_FORM_addrx3:
        return {spec, die, read_debug_addr(readU64<3>(info))};
    case DW_FORM_addrx4:
        return {spec, die, read_debug_addr(readU64<4>(info))};

    case DW_FORM_line_strp:
        return {spec, die, getStringFromStringSection(line_str_, readOffset(info, die.is64Bit))};

    case DW_FORM_strx:
        return {spec, die, get_string_using_offset_table(readULEB(info))};
    case DW_FORM_strx1:
        return {spec, die, get_string_using_offset_table(readU64<1>(info))};
    case DW_FORM_strx2:
        return {spec, die, get_string_using_offset_table(readU64<2>(info))};
    case DW_FORM_strx3:
        return {spec, die, get_string_using_offset_table(readU64<3>(info))};
    case DW_FORM_strx4:
        return {spec, die, get_string_using_offset_table(readU64<4>(info))};

    case DW_FORM_rnglistx: {
        auto index = readULEB(info);
        if (!cu.rnglists_base.has_value()) {
            return {spec, die, 0ULL};
        }
        const uint64_t offset_size = cu.is64Bit ? sizeof(uint64_t) : sizeof(uint32_t);
        auto sp = rnglists_.substr(*cu.rnglists_base + index * offset_size);
        auto offset = readOffset(sp, cu.is64Bit);
        return {spec, die, *cu.rnglists_base + offset};
    }

    case DW_FORM_loclistx: {
        auto index = readULEB(info);
        if (!cu.loclists_base.has_value()) {
            return {spec, die, 0ULL};
        }
        const uint64_t offset_size = cu.is64Bit ? sizeof(uint64_t) : sizeof(uint32_t);
        auto sp = loclists_.substr(*cu.loclists_base + index * offset_size);
        auto offset = readOffset(sp, cu.is64Bit);
        return {spec, die, *cu.loclists_base + offset};
    }

    case DW_FORM_data16:
        return {spec, die, readBytes(info, 16)};

    case DW_FORM_ref_sup4:
    case DW_FORM_ref_sup8:
    case DW_FORM_strp_sup:
        SAFE_CHECK(false, "Unexpected DWARF5 supplimentary object files");

    default:
        SAFE_CHECK(false, "invalid attribute form");
    }
    return {spec, die, 0ULL};
}

// static
Dwarf::AttributeSpec Dwarf::readAttributeSpec(std::string_view& sp) {
    Dwarf::AttributeSpec spec;
    spec.name = readULEB(sp);
    spec.form = readULEB(sp);
    if (spec.form == DW_FORM_implicit_const) {
        spec.implicitConst = readSLEB(sp);
    }
    return spec;
}

Dwarf::CompilationUnit Dwarf::getCompilationUnit(uint64_t offset) const {
    // SAFE_CHECK(offset < info_.size(), "unexpected offset");
    CompilationUnit cu;
    std::string_view chunk(info_);
    cu.offset = offset;
    chunk.remove_prefix(offset);

    // 1) unit_length
    auto initial_length = read<uint32_t>(chunk);
    cu.is64Bit = (initial_length == uint32_t(-1));
    cu.size = cu.is64Bit ? read<uint64_t>(chunk) : initial_length;
    SAFE_CHECK(cu.size <= chunk.size(), "invalid chunk size");
    cu.size += cu.is64Bit ? 12 : 4;

    // 2) version
    cu.version = read<uint16_t>(chunk);
    SAFE_CHECK(cu.version >= 2 && cu.version <= 5, "invalid info version");

    if (cu.version == 5) {
        // DWARF5: 7.5.1.1 Full and Partial Compilation Unit Headers
        // 3) unit_type (new DWARF 5)
        cu.unit_type = read<uint8_t>(chunk);
        if (cu.unit_type != DW_UT_compile && cu.unit_type != DW_UT_skeleton) {
            return cu;
        }
        // 4) address_size
        cu.addr_size = read<uint8_t>(chunk);
        SAFE_CHECK(cu.addr_size == sizeof(uintptr_t), "invalid address size");

        // 5) debug_abbrev_offset
        cu.abbrev_offset = readOffset(chunk, cu.is64Bit);

        if (cu.unit_type == DW_UT_skeleton) {
            // 6) dwo_id
            read<uint64_t>(chunk);
        }
    } else {
        // DWARF4 has a single type of unit in .debug_info
        cu.unit_type = DW_UT_compile;
        // 3) debug_abbrev_offset
        cu.abbrev_offset = readOffset(chunk, cu.is64Bit);
        // 4) address_size
        cu.addr_size = read<uint8_t>(chunk);
        SAFE_CHECK(cu.addr_size == sizeof(uintptr_t), "invalid address size");
    }
    cu.first_die = chunk.data() - info_.data();
    if (cu.version < 5) {
        return cu;
    }

    Die die = getDieAtOffset(cu, cu.first_die);
    if (die.abbr.tag != DW_TAG_compile_unit) {
        return cu;
    }

    // Read the DW_AT_*_base attributes.
    // Attributes which use FORMs relative to these base attrs
    // will not have valid values during this first pass!
    forEachAttribute(cu, die, [&](const Attribute& attr) {
        switch (attr.spec.name) {
        case DW_AT_addr_base:
        case DW_AT_GNU_addr_base:
            cu.addr_base = std::get<uint64_t>(attr.attr_value);
            break;
        case DW_AT_loclists_base:
            cu.loclists_base = std::get<uint64_t>(attr.attr_value);
            break;
        case DW_AT_rnglists_base:
        case DW_AT_GNU_ranges_base:
            cu.rnglists_base = std::get<uint64_t>(attr.attr_value);
            break;
        case DW_AT_str_offsets_base:
            cu.str_offsets_base = std::get<uint64_t>(attr.attr_value);
            break;
        }
        return true; // continue forEachAttribute
    });
    return cu;
}

// Finds the Compilation Unit starting at offset.
Dwarf::CompilationUnit Dwarf::findCompilationUnit(uint64_t targetOffset) const {
    // SAFE_CHECK(targetOffset < info_.size(), "unexpected target address");
    uint64_t offset = 0;
    while (offset < info_.size()) {
        std::string_view chunk(info_);
        chunk.remove_prefix(offset);

        auto initial_length = read<uint32_t>(chunk);
        auto is64_bit = (initial_length == static_cast<uint32_t>(-1));
        auto size = is64_bit ? read<uint64_t>(chunk) : initial_length;
        SAFE_CHECK(size <= chunk.size(), "invalid chunk size");
        size += is64_bit ? 12 : 4;

        if (offset + size > targetOffset) {
            break;
        }
        offset += size;
    }
    return getCompilationUnit(offset);
}

Dwarf::DIEAbbreviation Dwarf::getAbbreviation(uint64_t code, uint64_t offset) const {
    // Linear search in the .debug_abbrev section, starting at offset
    std::string_view section = abbrev_;
    section.remove_prefix(offset);

    Dwarf::DIEAbbreviation abbr;
    while (readAbbreviation(section, abbr)) {
        if (abbr.code == code) {
            return abbr;
        }
    }

    SAFE_CHECK(false, "could not find abbreviation code");
}

Dwarf::AttributeValue Dwarf::readAttributeValue(std::string_view& sp, uint64_t form,
                                                bool is64_bit) const {
    switch (form) {
    case DW_FORM_addr:
        return uint64_t(read<uintptr_t>(sp));
    case DW_FORM_block1:
        return readBytes(sp, read<uint8_t>(sp));
    case DW_FORM_block2:
        return readBytes(sp, read<uint16_t>(sp));
    case DW_FORM_block4:
        return readBytes(sp, read<uint32_t>(sp));
    case DW_FORM_block:
        [[fallthrough]];
    case DW_FORM_exprloc:
        return readBytes(sp, readULEB(sp));
    case DW_FORM_data1:
        [[fallthrough]];
    case DW_FORM_ref1:
        return uint64_t(read<uint8_t>(sp));
    case DW_FORM_data2:
        [[fallthrough]];
    case DW_FORM_ref2:
        return uint64_t(read<uint16_t>(sp));
    case DW_FORM_data4:
        [[fallthrough]];
    case DW_FORM_ref4:
        return uint64_t(read<uint32_t>(sp));
    case DW_FORM_data8:
        [[fallthrough]];
    case DW_FORM_ref8:
        return read<uint64_t>(sp);
    case DW_FORM_sdata:
        return uint64_t(readSLEB(sp));
    case DW_FORM_udata:
        [[fallthrough]];
    case DW_FORM_ref_udata:
        return readULEB(sp);
    case DW_FORM_flag:
        return uint64_t(read<uint8_t>(sp));
    case DW_FORM_flag_present:
        return uint64_t(1);
    case DW_FORM_sec_offset:
        [[fallthrough]];
    case DW_FORM_ref_addr:
        return readOffset(sp, is64_bit);
    case DW_FORM_string:
        return readNullTerminated(sp);
    case DW_FORM_strp:
        return getStringFromStringSection(str_, readOffset(sp, is64_bit));
    case DW_FORM_indirect: // form is explicitly specified
        return readAttributeValue(sp, readULEB(sp), is64_bit);
    default:
        SAFE_CHECK(false, "invalid attribute form");
        return uint64_t(1);
        ;
    }
}

/**
 * Find @address in .debug_aranges and return the offset in
 * .debug_info for compilation unit to which this address belongs.
 */
bool Dwarf::findDebugInfoOffset(uintptr_t address, std::string_view aranges, uint64_t& offset) {
    Section aranges_section(aranges);
    std::string_view chunk;
    while (aranges_section.next(chunk)) {
        auto version = read<uint16_t>(chunk);
        SAFE_CHECK(version == 2, "invalid aranges version");

        offset = readOffset(chunk, aranges_section.is64Bit());
        auto address_size = read<uint8_t>(chunk);
        SAFE_CHECK(address_size == sizeof(uintptr_t), "invalid address size");
        auto segment_size = read<uint8_t>(chunk);
        SAFE_CHECK(segment_size == 0, "segmented architecture not supported");

        // Padded to a multiple of 2 addresses.
        // Strangely enough, this is the only place in the DWARF spec that requires
        // padding.
        skipPadding(chunk, aranges.data(), 2 * sizeof(uintptr_t));
        for (;;) {
            auto start = read<uintptr_t>(chunk);
            auto length = read<uintptr_t>(chunk);

            if (start == 0 && length == 0) {
                break;
            }

            // Is our address in this range?
            if (address >= start && address < start + length) {
                return true;
            }
        }
    }
    return false;
}

Dwarf::Die Dwarf::getDieAtOffset(const CompilationUnit& cu, uint64_t offset) const {
    SAFE_CHECK(offset < info_.size(), "unexpected offset {}, info size {}", offset, info_.size());
    Die die;
    std::string_view sp {info_.data() + offset, cu.offset + cu.size - offset};
    die.offset = offset;
    die.is64Bit = cu.is64Bit;
    auto code = readULEB(sp);
    die.code = code;
    if (code == 0) {
        return die;
    }
    die.attr_offset = sp.data() - info_.data() - offset;
    die.abbr = !cu.abbr_cache.empty() && die.code < kMaxAbbreviationEntries
                       ? cu.abbr_cache[die.code - 1]
                       : getAbbreviation(die.code, cu.abbrev_offset);

    return die;
}

/**
 * Find the @locationInfo for @address in the compilation unit represented
 * by the @sp .debug_info entry.
 * Returns whether the address was found.
 * Advances @sp to the next entry in .debug_info.
 */
bool Dwarf::findLocation(uintptr_t address, const LocationInfoMode mode, CompilationUnit& cu,
                         LocationInfo& info, std::vector<SymbolizedFrame>& inline_frames) const {
    Die die = getDieAtOffset(cu, cu.first_die);
    // Partial compilation unit (DW_TAG_partial_unit) is not supported.
    SAFE_CHECK(die.abbr.tag == DW_TAG_compile_unit, "expecting compile unit entry");

    // Offset in .debug_line for the line number VM program for this CU
    std::optional<uint64_t> line_offset = 0;
    std::string_view compilation_directory;
    std::optional<std::string_view> main_file_name;
    std::optional<uint64_t> base_addr_cu;

    forEachAttribute(cu, die, [&](const Attribute& attr) {
        switch (attr.spec.name) {
        case DW_AT_stmt_list:
            // Offset in .debug_line for the line number VM program for this
            // compilation unit
            line_offset = std::get<uint64_t>(attr.attr_value);
            break;
        case DW_AT_comp_dir:
            // Compilation directory
            compilation_directory = std::get<std::string_view>(attr.attr_value);
            break;
        case DW_AT_name:
            // File name of main file being compiled
            main_file_name = std::get<std::string_view>(attr.attr_value);
            break;
        case DW_AT_low_pc:
        case DW_AT_entry_pc:
            // 2.17.1: historically DW_AT_low_pc was used. DW_AT_entry_pc was
            // introduced in DWARF3. Support either to determine the base address of
            // the CU.
            base_addr_cu = std::get<uint64_t>(attr.attr_value);
            break;
        }
        // Iterate through all attributes until find all above.
        return true;
    });

    if (main_file_name) {
        info.has_main_file = true;
        info.main_file = Path(compilation_directory, "", *main_file_name);
    }

    if (!line_offset) {
        return false;
    }

    std::string_view line_section(line_);
    line_section.remove_prefix(*line_offset);
    LineNumberVM line_vm(line_section, compilation_directory, str_, line_str_);

    // Execute line number VM program to find file and line
    info.has_file_and_line = line_vm.findAddress(address, info.file, info.line);

    bool check_inline = (mode == LocationInfoMode::FULL_WITH_INLINE);

    if (info.has_file_and_line && check_inline) {
        // Re-get the compilation unit with abbreviation cached.
        cu.abbr_cache.clear();
        cu.abbr_cache.resize(kMaxAbbreviationEntries);
        readCompilationUnitAbbrs(abbrev_, cu);

        // Find the subprogram that matches the given address.
        Die subprogram;
        findSubProgramDieForAddress(cu, die, address, base_addr_cu, subprogram);

        // Subprogram is the DIE of caller function.
        if (/*check_inline &&*/ subprogram.abbr.has_children) {
            // Use an extra location and get its call file and call line, so that
            // they can be used for the second last location when we don't have
            // enough inline frames for all inline functions call stack.
            const size_t max_size = Dwarf::kMaxInlineLocationInfoPerFrame + 1;
            std::vector<CallLocation> call_locations;
            call_locations.reserve(Dwarf::kMaxInlineLocationInfoPerFrame + 1);

            findInlinedSubroutineDieForAddress(cu, subprogram, line_vm, address, base_addr_cu,
                                               call_locations, max_size);
            size_t num_found = call_locations.size();

            if (num_found > 0) {
                const auto inner_most_file = info.file;
                const auto inner_most_line = info.line;

                // Earlier we filled in locationInfo:
                // - mainFile: the path to the CU -- the file where the non-inlined
                //   call is made from.
                // - file + line: the location of the inner-most inlined call.
                // Here we already find inlined info so mainFile would be redundant.
                info.has_main_file = false;
                info.main_file = Path {};
                // @findInlinedSubroutineDieForAddress fills inlineLocations[0] with the
                // file+line of the non-inlined outer function making the call.
                // locationInfo.name is already set by the caller by looking up the
                // non-inlined function @address belongs to.
                info.has_file_and_line = true;
                info.file = call_locations[0].file;
                info.line = call_locations[0].line;

                // The next inlined subroutine's call file and call line is the current
                // caller's location.
                for (size_t i = 0; i < num_found - 1; ++i) {
                    call_locations[i].file = call_locations[i + 1].file;
                    call_locations[i].line = call_locations[i + 1].line;
                }
                // CallLocation for the inner-most inlined function:
                // - will be computed if enough space was available in the passed
                //   buffer.
                // - will have a .name, but no !.file && !.line
                // - its corresponding file+line is the one returned by LineVM based
                //   on @address.
                // Use the inner-most inlined file+line info we got from the LineVM.
                call_locations[num_found - 1].file = inner_most_file;
                call_locations[num_found - 1].line = inner_most_line;

                // Fill in inline frames in reverse order (as expected by the caller).
                std::reverse(call_locations.begin(), call_locations.end());
                for (const auto& call_location : call_locations) {
                    SymbolizedFrame inline_frame;
                    inline_frame.found = true;
                    inline_frame.addr = address;
                    if (!call_location.name.empty()) {
                        inline_frame.name = call_location.name.data();
                    } else {
                        inline_frame.name = nullptr;
                    }
                    inline_frame.location.has_file_and_line = true;
                    inline_frame.location.file = call_location.file;
                    inline_frame.location.line = call_location.line;
                    inline_frames.push_back(inline_frame);
                }
            }
        }
    }

    return info.has_file_and_line;
}

void Dwarf::findSubProgramDieForAddress(const CompilationUnit& cu, const Die& die, uint64_t address,
                                        std::optional<uint64_t> base_addr_cu,
                                        Die& subprogram) const {
    forEachChild(cu, die, [&](const Die& child_die) {
        if (child_die.abbr.tag == DW_TAG_subprogram) {
            std::optional<uint64_t> low_pc;
            std::optional<uint64_t> high_pc;
            std::optional<bool> is_high_pc_addr;
            std::optional<uint64_t> range_offset;
            forEachAttribute(cu, child_die, [&](const Attribute& attr) {
                switch (attr.spec.name) {
                case DW_AT_ranges:
                    range_offset = std::get<uint64_t>(attr.attr_value);
                    break;
                case DW_AT_low_pc:
                    low_pc = std::get<uint64_t>(attr.attr_value);
                    break;
                case DW_AT_high_pc:
                    // The value of the DW_AT_high_pc attribute can be
                    // an address (DW_FORM_addr*) or an offset (DW_FORM_data*).
                    is_high_pc_addr = attr.spec.form == DW_FORM_addr ||   //
                                      attr.spec.form == DW_FORM_addrx ||  //
                                      attr.spec.form == DW_FORM_addrx1 || //
                                      attr.spec.form == DW_FORM_addrx2 || //
                                      attr.spec.form == DW_FORM_addrx3 || //
                                      attr.spec.form == DW_FORM_addrx4;
                    high_pc = std::get<uint64_t>(attr.attr_value);
                    break;
                }
                // Iterate through all attributes until find all above.
                return true;
            });
            bool pc_match = low_pc && high_pc && is_high_pc_addr && address >= *low_pc &&
                            (address < (*is_high_pc_addr ? *high_pc : *low_pc + *high_pc));
            bool range_match =
                    range_offset && isAddrInRangeList(cu, address, base_addr_cu,
                                                      range_offset.value(), cu.addr_size);
            if (pc_match || range_match) {
                subprogram = child_die;
                return false;
            }
        }

        findSubProgramDieForAddress(cu, child_die, address, base_addr_cu, subprogram);

        // Iterates through children until find the inline subprogram.
        return true;
    });
}

/**
 * Find DW_TAG_inlined_subroutine child DIEs that contain @address and
 * then extract:
 * - Where was it called from (DW_AT_call_file & DW_AT_call_line):
 *   the statement or expression that caused the inline expansion.
 * - The inlined function's name. As a function may be inlined multiple
 *   times, common attributes like DW_AT_linkage_name or DW_AT_name
 *   are only stored in its "concrete out-of-line instance" (a
 *   DW_TAG_subprogram) which we find using DW_AT_abstract_origin.
 */
void Dwarf::findInlinedSubroutineDieForAddress(const CompilationUnit& cu, const Die& die,
                                               const LineNumberVM& line_vm, uint64_t address,
                                               std::optional<uint64_t> base_addr_cu,
                                               std::vector<CallLocation>& locations,
                                               const size_t max_size) const {
    if (locations.size() >= max_size) {
        return;
    }

    forEachChild(cu, die, [&](const Die& child_die) {
        // Between a DW_TAG_subprogram and and DW_TAG_inlined_subroutine we might
        // have arbitrary intermediary "nodes", including DW_TAG_common_block,
        // DW_TAG_lexical_block, DW_TAG_try_block, DW_TAG_catch_block and
        // DW_TAG_with_stmt, etc.
        // We can't filter with locationhere since its range may be not specified.
        // See section 2.6.2: A location list containing only an end of list entry
        // describes an object that exists in the source code but not in the
        // executable program.
        if (child_die.abbr.tag == DW_TAG_try_block || child_die.abbr.tag == DW_TAG_catch_block ||
            child_die.abbr.tag == DW_TAG_entry_point || child_die.abbr.tag == DW_TAG_common_block ||
            child_die.abbr.tag == DW_TAG_lexical_block) {
            findInlinedSubroutineDieForAddress(cu, child_die, line_vm, address, base_addr_cu,
                                               locations, max_size);
            return true;
        }

        std::optional<uint64_t> low_pc;
        std::optional<uint64_t> high_pc;
        std::optional<bool> is_high_pc_addr;
        std::optional<uint64_t> abstract_origin;
        std::optional<uint64_t> abstract_origin_ref_type;
        std::optional<uint64_t> call_file;
        std::optional<uint64_t> call_line;
        std::optional<uint64_t> range_offset;
        forEachAttribute(cu, child_die, [&](const Attribute& attr) {
            switch (attr.spec.name) {
            case DW_AT_ranges:
                range_offset = std::get<uint64_t>(attr.attr_value);
                break;
            case DW_AT_low_pc:
                low_pc = std::get<uint64_t>(attr.attr_value);
                break;
            case DW_AT_high_pc:
                // The value of the DW_AT_high_pc attribute can be
                // an address (DW_FORM_addr*) or an offset (DW_FORM_data*).
                is_high_pc_addr = attr.spec.form == DW_FORM_addr ||   //
                                  attr.spec.form == DW_FORM_addrx ||  //
                                  attr.spec.form == DW_FORM_addrx1 || //
                                  attr.spec.form == DW_FORM_addrx2 || //
                                  attr.spec.form == DW_FORM_addrx3 || //
                                  attr.spec.form == DW_FORM_addrx4;
                high_pc = std::get<uint64_t>(attr.attr_value);
                break;
            case DW_AT_abstract_origin:
                abstract_origin_ref_type = attr.spec.form;
                abstract_origin = std::get<uint64_t>(attr.attr_value);
                break;
            case DW_AT_call_line:
                call_line = std::get<uint64_t>(attr.attr_value);
                break;
            case DW_AT_call_file:
                call_file = std::get<uint64_t>(attr.attr_value);
                break;
            }
            // Iterate through all until find all above attributes.
            return true;
        });

        // 2.17 Code Addresses and Ranges
        // Any debugging information entry describing an entity that has a
        // machine code address or range of machine code addresses,
        // which includes compilation units, module initialization, subroutines,
        // ordinary blocks, try/catch blocks, labels and the like, may have
        //  - A DW_AT_low_pc attribute for a single address,
        //  - A DW_AT_low_pc and DW_AT_high_pc pair of attributes for a
        //    single contiguous range of addresses, or
        //  - A DW_AT_ranges attribute for a non-contiguous range of addresses.
        // TODO: Support DW_TAG_entry_point and DW_TAG_common_block that don't
        // have DW_AT_low_pc/DW_AT_high_pc pairs and DW_AT_ranges.
        // TODO: Support relocated address which requires lookup in relocation map.
        bool pc_match = low_pc && high_pc && is_high_pc_addr && address >= *low_pc &&
                        (address < (*is_high_pc_addr ? *high_pc : *low_pc + *high_pc));
        bool range_match = range_offset && isAddrInRangeList(cu, address, base_addr_cu,
                                                             range_offset.value(), cu.addr_size);
        if (!pc_match && !range_match) {
            // Address doesn't match. Keep searching other children.
            return true;
        }

        if (!abstract_origin || !abstract_origin_ref_type || !call_line || !call_file) {
            // We expect a single sibling DIE to match on addr, but it's missing
            // required fields. Stop searching for other DIEs.
            return false;
        }

        CallLocation location;
        location.file = line_vm.getFullFileName(*call_file);
        location.line = *call_line;

        /// Something wrong with receiving debug info about inline.
        /// If set to true we stop parsing DWARF.
        bool die_for_inline_broken = false;

        auto get_function_name = [&](const CompilationUnit& srcu, uint64_t die_offset) {
            Die decl_die = getDieAtOffset(srcu, die_offset);
            auto& die_to_look_for_name = decl_die;

            Die def_die;
            // Jump to the actual function definition instead of declaration for name
            // and line info.
            // DW_AT_specification: Incomplete, non-defining, or separate declaration
            // corresponding to a declaration
            auto offset = getAttribute<uint64_t>(srcu, decl_die, DW_AT_specification);
            if (offset) {
                /// FIXME: actually it's a bug in our DWARF parser.
                ///
                /// Most of the times compilation unit offset (srcu.offset) is some big number inside .debug_info (like 434782255).
                /// Offset of DIE definition is some small relative number to srcu.offset (like 3518).
                /// However in some unknown cases offset looks like global, non relative number (like 434672579) and in this
                /// case we obviously doing something wrong parsing DWARF.
                ///
                /// What is important -- this bug? reproduces only with -flto=thin in release mode.
                /// Also llvm-dwarfdump --verify ./clickhouse says that our DWARF is ok, so it's another prove
                /// that we just doing something wrong.
                ///
                /// FIXME: Currently we just give up parsing DWARF for inlines when we got into this situation.
                if (srcu.offset + offset.value() >= info_.size()) {
                    die_for_inline_broken = true;
                } else {
                    def_die = getDieAtOffset(srcu, srcu.offset + offset.value());
                    die_to_look_for_name = def_die;
                }
            }

            std::string_view name;

            if (die_for_inline_broken) {
                return name;
            }

            // The file and line will be set in the next inline subroutine based on
            // its DW_AT_call_file and DW_AT_call_line.
            forEachAttribute(srcu, die_to_look_for_name, [&](const Attribute& attr) {
                switch (attr.spec.name) {
                case DW_AT_linkage_name:
                    name = std::get<std::string_view>(attr.attr_value);
                    break;
                case DW_AT_name:
                    // NOTE: when DW_AT_linkage_name and DW_AT_name match, dwarf
                    // emitters omit DW_AT_linkage_name (to save space). If present
                    // DW_AT_linkage_name should always be preferred (mangled C++ name
                    // vs just the function name).
                    if (name.empty()) {
                        name = std::get<std::string_view>(attr.attr_value);
                    }
                    break;
                }
                return true;
            });
            return name;
        };

        // DW_AT_abstract_origin is a reference. There a 3 types of references:
        // - the reference can identify any debugging information entry within the
        //   compilation unit (DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4,
        //   DW_FORM_ref8, DW_FORM_ref_udata). This type of reference is an offset
        //   from the first byte of the compilation header for the compilation unit
        //   containing the reference.
        // - the reference can identify any debugging information entry within a
        //   .debug_info section; in particular, it may refer to an entry in a
        //   different compilation unit (DW_FORM_ref_addr)
        // - the reference can identify any debugging information type entry that
        //   has been placed in its own type unit.
        //   Not applicable for DW_AT_abstract_origin.
        location.name = (*abstract_origin_ref_type != DW_FORM_ref_addr)
                                ? get_function_name(cu, cu.offset + *abstract_origin)
                                : get_function_name(findCompilationUnit(*abstract_origin),
                                                    *abstract_origin);

        /// FIXME: see comment above
        if (die_for_inline_broken) {
            return false;
        }

        locations.push_back(location);

        findInlinedSubroutineDieForAddress(cu, child_die, line_vm, address, base_addr_cu, locations,
                                           max_size);

        return false;
    });
}

bool Dwarf::findAddress(uintptr_t address, LocationInfo& locationInfo, LocationInfoMode mode,
                        std::vector<SymbolizedFrame>& inline_frames) const {
    locationInfo = LocationInfo();

    if (mode == LocationInfoMode::DISABLED) {
        return false;
    }

    if (!elf_) { // No file.
        return false;
    }

    if (!aranges_.empty()) {
        // Fast path: find the right .debug_info entry by looking up the
        // address in .debug_aranges.
        uint64_t offset = 0;
        if (findDebugInfoOffset(address, aranges_, offset)) {
            // Read compilation unit header from .debug_info
            auto unit = getCompilationUnit(offset);
            if (unit.unit_type != DW_UT_compile && unit.unit_type != DW_UT_skeleton) {
                return false;
            }
            findLocation(address, mode, unit, locationInfo, inline_frames);
            return locationInfo.has_file_and_line;
        } else if (mode == LocationInfoMode::FAST) {
            // NOTE: Clang (when using -gdwarf-aranges) doesn't generate entries
            // in .debug_aranges for some functions, but always generates
            // .debug_info entries.  Scanning .debug_info is slow, so fall back to
            // it only if such behavior is requested via LocationInfoMode.
            return false;
        } else {
            SAFE_CHECK(mode == LocationInfoMode::FULL || mode == LocationInfoMode::FULL_WITH_INLINE,
                       "unexpected mode");
            // Fall back to the linear scan.
        }
    }

    // Slow path (linear scan): Iterate over all .debug_info entries
    // and look for the address in each compilation unit.
    uint64_t offset = 0;
    while (offset < info_.size() && !locationInfo.has_file_and_line) {
        auto unit = getCompilationUnit(offset);
        offset += unit.size;
        if (unit.unit_type != DW_UT_compile && unit.unit_type != DW_UT_skeleton) {
            continue;
        }
        findLocation(address, mode, unit, locationInfo, inline_frames);
    }

    return locationInfo.has_file_and_line;
}

bool Dwarf::isAddrInRangeList(const CompilationUnit& cu, uint64_t address,
                              std::optional<uint64_t> base_addr, size_t offset,
                              uint8_t addr_size) const {
    SAFE_CHECK(addr_size == 4 || addr_size == 8, "wrong address size");
    if (cu.version <= 4 && !ranges_.empty()) {
        const bool is64_bit_addr = addr_size == 8;
        std::string_view sp = ranges_;
        sp.remove_prefix(offset);
        const uint64_t max_addr = is64_bit_addr ? std::numeric_limits<uint64_t>::max()
                                                : std::numeric_limits<uint32_t>::max();
        while (!sp.empty()) {
            uint64_t begin = readOffset(sp, is64_bit_addr);
            uint64_t end = readOffset(sp, is64_bit_addr);
            // The range list entry is a base address selection entry.
            if (begin == max_addr) {
                base_addr = end;
                continue;
            }
            // The range list entry is an end of list entry.
            if (begin == 0 && end == 0) {
                break;
            }

            // Check if the given address falls in the range list entry.
            // 2.17.3 Non-Contiguous Address Ranges
            // The applicable base address of a range list entry is determined by the
            // closest preceding base address selection entry (see below) in the same
            // range list. If there is no such selection entry, then the applicable
            // base address defaults to the base address of the compilation unit.
            if (base_addr && address >= begin + *base_addr && address < end + *base_addr) {
                return true;
            }
        }
    }

    if (cu.version == 5 && !rnglists_.empty() && cu.addr_base.has_value()) {
        auto rnglists = rnglists_;
        rnglists.remove_prefix(offset);

        while (!rnglists.empty()) {
            auto kind = read<uint8_t>(rnglists);
            switch (kind) {
            case DW_RLE_end_of_list:
                return false;
            case DW_RLE_base_addressx: {
                auto index = readULEB(rnglists);
                auto sp = addr_.substr(*cu.addr_base + index * sizeof(uint64_t));
                base_addr = read<uint64_t>(sp);
            } break;

            case DW_RLE_startx_endx: {
                auto index_start = readULEB(rnglists);
                auto index_end = readULEB(rnglists);
                auto sp_start = addr_.substr(*cu.addr_base + index_start * sizeof(uint64_t));
                auto start = read<uint64_t>(sp_start);

                auto sp_end = addr_.substr(*cu.addr_base + index_end * sizeof(uint64_t));
                auto end = read<uint64_t>(sp_end);
                if (address >= start && address < end) {
                    return true;
                }
            } break;

            case DW_RLE_startx_length: {
                auto index_start = readULEB(rnglists);
                auto length = readULEB(rnglists);
                auto sp_start = addr_.substr(*cu.addr_base + index_start * sizeof(uint64_t));
                auto start = read<uint64_t>(sp_start);

                auto sp_end = addr_.substr(*cu.addr_base + index_start * sizeof(uint64_t) + length);
                auto end = read<uint64_t>(sp_end);
                if (start != end && address >= start && address < end) {
                    return true;
                }
            } break;

            case DW_RLE_offset_pair: {
                auto offset_start = readULEB(rnglists);
                auto offset_end = readULEB(rnglists);
                if (base_addr && address >= (*base_addr + offset_start) &&
                    address < (*base_addr + offset_end)) {
                    return true;
                }
            } break;

            case DW_RLE_base_address:
                base_addr = read<uint64_t>(rnglists);
                break;

            case DW_RLE_start_end: {
                uint64_t start = read<uint64_t>(rnglists);
                uint64_t end = read<uint64_t>(rnglists);
                if (address >= start && address < end) {
                    return true;
                }
            } break;

            case DW_RLE_start_length: {
                uint64_t start = read<uint64_t>(rnglists);
                uint64_t end = start + readULEB(rnglists);
                if (address >= start && address < end) {
                    return true;
                }
            } break;

            default:
                SAFE_CHECK(false, "Unexpected debug_rnglists entry kind");
            }
        }
    }
    return false;
}

Dwarf::LineNumberVM::LineNumberVM(std::string_view data, std::string_view compilationDirectory,
                                  std::string_view debugStr, std::string_view debugLineStr)
        : compilationDirectory_(compilationDirectory),
          debugStr_(debugStr),
          debugLineStr_(debugLineStr) {
    Section section(data);
    SAFE_CHECK(section.next(data_), "invalid line number VM");
    is64Bit_ = section.is64Bit();
    init();
    reset();
}

void Dwarf::LineNumberVM::reset() {
    address_ = 0;
    file_ = 1;
    line_ = 1;
    column_ = 0;
    isStmt_ = defaultIsStmt_;
    basicBlock_ = false;
    endSequence_ = false;
    prologueEnd_ = false;
    epilogueBegin_ = false;
    isa_ = 0;
    discriminator_ = 0;
}

struct LineNumberAttribute {
    uint64_t content_type_code;
    uint64_t form_code;
    std::variant<uint64_t, std::string_view> attr_value;
};

LineNumberAttribute readLineNumberAttribute(bool is64_bit, std::string_view& format,
                                            std::string_view& entries, std::string_view debugStr,
                                            std::string_view debugLineStr) {
    uint64_t content_type_code = readULEB(format);
    uint64_t form_code = readULEB(format);
    std::variant<uint64_t, std::string_view> attr_value;

    switch (content_type_code) {
    case DW_LNCT_path: {
        switch (form_code) {
        case DW_FORM_string:
            attr_value = readNullTerminated(entries);
            break;
        case DW_FORM_line_strp: {
            auto off = readOffset(entries, is64_bit);
            attr_value = getStringFromStringSection(debugLineStr, off);
        } break;
        case DW_FORM_strp:
            attr_value = getStringFromStringSection(debugStr, readOffset(entries, is64_bit));
            break;
        case DW_FORM_strp_sup:
            SAFE_CHECK(false, "Unexpected DW_FORM_strp_sup");
            break;
        default:
            SAFE_CHECK(false, "Unexpected form for DW_LNCT_path");
            break;
        }
    } break;

    case DW_LNCT_directory_index: {
        switch (form_code) {
        case DW_FORM_data1:
            attr_value = read<uint8_t>(entries);
            break;
        case DW_FORM_data2:
            attr_value = read<uint16_t>(entries);
            break;
        case DW_FORM_udata:
            attr_value = readULEB(entries);
            break;
        default:
            SAFE_CHECK(false, "Unexpected form for DW_LNCT_directory_index");
            break;
        }
    } break;

    case DW_LNCT_timestamp: {
        switch (form_code) {
        case DW_FORM_udata:
            attr_value = readULEB(entries);
            break;
        case DW_FORM_data4:
            attr_value = read<uint32_t>(entries);
            break;
        case DW_FORM_data8:
            attr_value = read<uint64_t>(entries);
            break;
        case DW_FORM_block:
            attr_value = readBytes(entries, readULEB(entries));
            break;
        default:
            SAFE_CHECK(false, "Unexpected form for DW_LNCT_timestamp");
        }
    } break;

    case DW_LNCT_size: {
        switch (form_code) {
        case DW_FORM_udata:
            attr_value = readULEB(entries);
            break;
        case DW_FORM_data1:
            attr_value = read<uint8_t>(entries);
            break;
        case DW_FORM_data2:
            attr_value = read<uint16_t>(entries);
            break;
        case DW_FORM_data4:
            attr_value = read<uint32_t>(entries);
            break;
        case DW_FORM_data8:
            attr_value = read<uint64_t>(entries);
            break;
        default:
            SAFE_CHECK(false, "Unexpected form for DW_LNCT_size");
            break;
        }
    } break;

    case DW_LNCT_MD5: {
        switch (form_code) {
        case DW_FORM_data16:
            attr_value = readBytes(entries, 16);
            break;
        default:
            SAFE_CHECK(false, "Unexpected form for DW_LNCT_MD5");
            break;
        }
    } break;

    default:
        // TODO: skip over vendor data as specified by the form instead.
        SAFE_CHECK(false, "Unexpected vendor content type code");
        break;
    }
    return {
            .content_type_code = content_type_code,
            .form_code = form_code,
            .attr_value = attr_value,
    };
}

void Dwarf::LineNumberVM::init() {
    version_ = read<uint16_t>(data_);
    SAFE_CHECK(version_ >= 2 && version_ <= 5, "invalid version in line number VM: {}", version_);
    if (version_ == 5) {
        auto address_size = read<uint8_t>(data_);
        SAFE_CHECK(address_size == sizeof(uintptr_t), "Unexpected Line Number Table address_size");
        auto segment_selector_size = read<uint8_t>(data_);
        SAFE_CHECK(segment_selector_size == 0, "Segments not supported");
    }
    uint64_t header_length = readOffset(data_, is64Bit_);
    SAFE_CHECK(header_length <= data_.size(), "invalid line number VM header length");
    std::string_view header(data_.data(), header_length);
    data_ = std::string_view(header.end(), data_.end() - header.end());

    minLength_ = read<uint8_t>(header);
    if (version_ >= 4) { // Version 2 and 3 records don't have this
        uint8_t max_ops_per_instruction = read<uint8_t>(header);
        SAFE_CHECK(max_ops_per_instruction == 1, "VLIW not supported");
    }
    defaultIsStmt_ = read<uint8_t>(header);
    lineBase_ = read<int8_t>(header); // yes, signed
    lineRange_ = read<uint8_t>(header);
    opcodeBase_ = read<uint8_t>(header);
    SAFE_CHECK(opcodeBase_ != 0, "invalid opcode base");
    standardOpcodeLengths_ = reinterpret_cast<const uint8_t*>(header.data());
    header.remove_prefix(opcodeBase_ - 1);

    if (version_ <= 4) {
        // We don't want to use heap, so we don't keep an unbounded amount of state.
        // We'll just skip over include directories and file names here, and
        // we'll loop again when we actually need to retrieve one.
        std::string_view sp;
        const char* tmp = header.data();
        v4_.includeDirectoryCount = 0;
        while (!(sp = readNullTerminated(header)).empty()) {
            ++v4_.includeDirectoryCount;
        }
        v4_.includeDirectories = {tmp, header.data()};

        tmp = header.data();
        FileName fn;
        v4_.fileNameCount = 0;
        while (readFileName(header, fn)) {
            ++v4_.fileNameCount;
        }
        v4_.fileNames = {tmp, header.data()};
    } else if (version_ == 5) {
        v5_.directoryEntryFormatCount = read<uint8_t>(header);
        const char* tmp = header.data();
        for (uint8_t i = 0; i < v5_.directoryEntryFormatCount; i++) {
            // A sequence of directory entry format descriptions. Each description
            // consists of a pair of ULEB128 values:
            readULEB(header); // A content type code
            readULEB(header); // A form code using the attribute form codes
        }
        v5_.directoryEntryFormat = {tmp, header.data()};
        v5_.directoriesCount = readULEB(header);
        tmp = header.data();
        for (uint64_t i = 0; i < v5_.directoriesCount; i++) {
            std::string_view format = v5_.directoryEntryFormat;
            for (uint8_t f = 0; f < v5_.directoryEntryFormatCount; f++) {
                readLineNumberAttribute(is64Bit_, format, header, debugStr_, debugLineStr_);
            }
        }
        v5_.directories = {tmp, header.data()};

        v5_.fileNameEntryFormatCount = read<uint8_t>(header);
        tmp = header.data();
        for (uint8_t i = 0; i < v5_.fileNameEntryFormatCount; i++) {
            // A sequence of file entry format descriptions. Each description
            // consists of a pair of ULEB128 values:
            readULEB(header); // A content type code
            readULEB(header); // A form code using the attribute form codes
        }
        v5_.fileNameEntryFormat = {tmp, header.data()};
        v5_.fileNamesCount = readULEB(header);
        tmp = header.data();
        for (uint64_t i = 0; i < v5_.fileNamesCount; i++) {
            std::string_view format = v5_.fileNameEntryFormat;
            for (uint8_t f = 0; f < v5_.fileNameEntryFormatCount; f++) {
                readLineNumberAttribute(is64Bit_, format, header, debugStr_, debugLineStr_);
            }
        }
        v5_.fileNames = {tmp, header.data()};
    }
}

bool Dwarf::LineNumberVM::next(std::string_view& program) {
    Dwarf::LineNumberVM::StepResult ret;
    do {
        ret = step(program);
    } while (ret == CONTINUE);

    return (ret == COMMIT);
}

Dwarf::LineNumberVM::FileName Dwarf::LineNumberVM::getFileName(uint64_t index) const {
    if (version_ <= 4) {
        SAFE_CHECK(index != 0, "invalid file index 0");
        FileName fn;
        if (index <= v4_.fileNameCount) {
            std::string_view file_names = v4_.fileNames;
            for (; index; --index) {
                if (!readFileName(file_names, fn)) {
                    abort();
                }
            }
            return fn;
        }

        index -= v4_.fileNameCount;

        std::string_view program = data_;
        for (; index; --index) {
            SAFE_CHECK(nextDefineFile(program, fn), "invalid file index");
        }

        return fn;
    } else {
        FileName fn;
        SAFE_CHECK(index < v5_.fileNamesCount, "invalid file index");
        std::string_view file_names = v5_.fileNames;
        for (uint64_t i = 0; i < v5_.fileNamesCount; i++) {
            std::string_view format = v5_.fileNameEntryFormat;
            for (uint8_t f = 0; f < v5_.fileNameEntryFormatCount; f++) {
                auto attr = readLineNumberAttribute(is64Bit_, format, file_names, debugStr_,
                                                    debugLineStr_);
                if (i == index) {
                    switch (attr.content_type_code) {
                    case DW_LNCT_path:
                        fn.relativeName = std::get<std::string_view>(attr.attr_value);
                        break;
                    case DW_LNCT_directory_index:
                        fn.directoryIndex = std::get<uint64_t>(attr.attr_value);
                        break;
                    }
                }
            }
        }
        return fn;
    }
}

std::string_view Dwarf::LineNumberVM::getIncludeDirectory(uint64_t index) const {
    if (version_ <= 4) {
        if (index == 0) {
            // In DWARF <= 4 the current directory is not represented in the
            // directories field and a directory index of 0 implicitly referred to
            // that directory as found in the DW_AT_comp_dir attribute of the
            // compilation unit debugging information entry.
            return {};
        }

        SAFE_CHECK(index <= v4_.includeDirectoryCount, "invalid include directory");

        std::string_view include_directories = v4_.includeDirectories;
        std::string_view dir;
        for (; index; --index) {
            dir = readNullTerminated(include_directories);
            if (dir.empty()) {
                abort(); // BUG
            }
        }

        return dir;
    } else {
        SAFE_CHECK(index < v5_.directoriesCount, "invalid file index");
        std::string_view directories = v5_.directories;
        for (uint64_t i = 0; i < v5_.directoriesCount; i++) {
            std::string_view format = v5_.directoryEntryFormat;
            for (uint8_t f = 0; f < v5_.directoryEntryFormatCount; f++) {
                auto attr = readLineNumberAttribute(is64Bit_, format, directories, debugStr_,
                                                    debugLineStr_);
                if (i == index && attr.content_type_code == DW_LNCT_path) {
                    return std::get<std::string_view>(attr.attr_value);
                }
            }
        }
        // This could only happen if DWARF5's directory_entry_format doesn't contain
        // a DW_LNCT_path. Highly unlikely, but we shouldn't crash.
        return std::string_view("<directory not found>");
    }
}

bool Dwarf::LineNumberVM::readFileName(std::string_view& program, FileName& fn) {
    fn.relativeName = readNullTerminated(program);
    if (fn.relativeName.empty()) {
        return false;
    }
    fn.directoryIndex = readULEB(program);
    // Skip over file size and last modified time
    readULEB(program);
    readULEB(program);
    return true;
}

bool Dwarf::LineNumberVM::nextDefineFile(std::string_view& program, FileName& fn) const {
    while (!program.empty()) {
        auto opcode = read<uint8_t>(program);

        if (opcode >= opcodeBase_) { // special opcode
            continue;
        }

        if (opcode != 0) { // standard opcode
            // Skip, slurp the appropriate number of LEB arguments
            uint8_t arg_count = standardOpcodeLengths_[opcode - 1];
            while (arg_count--) {
                readULEB(program);
            }
            continue;
        }

        // Extended opcode
        auto length = readULEB(program);
        // the opcode itself should be included in the length, so length >= 1
        SAFE_CHECK(length != 0, "invalid extended opcode length");
        read<uint8_t>(program); // extended opcode
        --length;

        if (opcode == DW_LNE_define_file) {
            SAFE_CHECK(version_ < 5, "DW_LNE_define_file deprecated in DWARF5");
            SAFE_CHECK(readFileName(program, fn), "invalid empty file in DW_LNE_define_file");
            return true;
        }

        program.remove_prefix(length);
    }

    return false;
}

Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step(std::string_view& program) {
    auto opcode = read<uint8_t>(program);

    if (opcode >= opcodeBase_) { // special opcode
        uint8_t adjusted_opcode = opcode - opcodeBase_;
        uint8_t op_advance = adjusted_opcode / lineRange_;

        address_ += minLength_ * op_advance;
        line_ += lineBase_ + adjusted_opcode % lineRange_;

        basicBlock_ = false;
        prologueEnd_ = false;
        epilogueBegin_ = false;
        discriminator_ = 0;
        return COMMIT;
    }

    if (opcode != 0) { // standard opcode
        // Only interpret opcodes that are recognized by the version we're parsing;
        // the others are vendor extensions and we should ignore them.
        switch (opcode) {
        case DW_LNS_copy:
            basicBlock_ = false;
            prologueEnd_ = false;
            epilogueBegin_ = false;
            discriminator_ = 0;
            return COMMIT;
        case DW_LNS_advance_pc:
            address_ += minLength_ * readULEB(program);
            return CONTINUE;
        case DW_LNS_advance_line:
            line_ += readSLEB(program);
            return CONTINUE;
        case DW_LNS_set_file:
            file_ = readULEB(program);
            return CONTINUE;
        case DW_LNS_set_column:
            column_ = readULEB(program);
            return CONTINUE;
        case DW_LNS_negate_stmt:
            isStmt_ = !isStmt_;
            return CONTINUE;
        case DW_LNS_set_basic_block:
            basicBlock_ = true;
            return CONTINUE;
        case DW_LNS_const_add_pc:
            address_ += minLength_ * ((255 - opcodeBase_) / lineRange_);
            return CONTINUE;
        case DW_LNS_fixed_advance_pc:
            address_ += read<uint16_t>(program);
            return CONTINUE;
        case DW_LNS_set_prologue_end:
            if (version_ == 2) {
                break; // not supported in version 2
            }
            prologueEnd_ = true;
            return CONTINUE;
        case DW_LNS_set_epilogue_begin:
            if (version_ == 2) {
                break; // not supported in version 2
            }
            epilogueBegin_ = true;
            return CONTINUE;
        case DW_LNS_set_isa:
            if (version_ == 2) {
                break; // not supported in version 2
            }
            isa_ = readULEB(program);
            return CONTINUE;
        }

        // Unrecognized standard opcode, slurp the appropriate number of LEB
        // arguments.
        uint8_t arg_count = standardOpcodeLengths_[opcode - 1];
        while (arg_count--) {
            readULEB(program);
        }
        return CONTINUE;
    }

    // Extended opcode
    auto length = readULEB(program);
    // the opcode itself should be included in the length, so length >= 1
    SAFE_CHECK(length != 0, "invalid extended opcode length");
    auto extended_opcode = read<uint8_t>(program);
    --length;

    switch (extended_opcode) {
    case DW_LNE_end_sequence:
        return END;
    case DW_LNE_set_address:
        address_ = read<uintptr_t>(program);
        return CONTINUE;
    case DW_LNE_define_file:
        SAFE_CHECK(version_ < 5, "DW_LNE_define_file deprecated in DWARF5");
        // We can't process DW_LNE_define_file here, as it would require us to
        // use unbounded amounts of state (ie. use the heap).  We'll do a second
        // pass (using nextDefineFile()) if necessary.
        break;
    case DW_LNE_set_discriminator:
        discriminator_ = readULEB(program);
        return CONTINUE;
    }

    // Unrecognized extended opcode
    program.remove_prefix(length);
    return CONTINUE;
}

Dwarf::Path Dwarf::LineNumberVM::getFullFileName(uint64_t index) const {
    auto fn = getFileName(index);
    // DWARF <= 4: the current dir is not represented in the CU's Line Number
    // Program Header and relies on the CU's DW_AT_comp_dir.
    // DWARF 5: the current directory is explicitly present.
    const std::string_view base_dir = version_ == 5 ? "" : compilationDirectory_;
    return Path(base_dir, getIncludeDirectory(fn.directoryIndex), fn.relativeName);
}

bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path& file, uint64_t& line) {
    std::string_view program = data_;

    // Within each sequence of instructions, the address may only increase.
    // Unfortunately, within the same compilation unit, sequences may appear
    // in any order.  So any sequence is a candidate if it starts at an address
    // <= the target address, and we know we've found the target address if
    // a candidate crosses the target address.
    enum State {
        START,
        LOW_SEQ, // candidate
        HIGH_SEQ
    };
    State state = START;
    reset();

    uint64_t prev_file = 0;
    uint64_t prev_line = 0;
    while (!program.empty()) {
        bool seq_end = !next(program);

        if (state == START) {
            if (!seq_end) {
                state = address_ <= target ? LOW_SEQ : HIGH_SEQ;
            }
        }

        if (state == LOW_SEQ) {
            if (address_ > target) {
                // Found it!  Note that ">" is indeed correct (not ">="), as each
                // sequence is guaranteed to have one entry past-the-end (emitted by
                // DW_LNE_end_sequence)
                //
                // NOTE: In DWARF <= 4 the file register is non-zero.
                //   See DWARF 4: 6.2.4 The Line Number Program Header
                //   "The line number program assigns numbers to each of the file
                //   entries in order, beginning with 1, and uses those numbers instead
                //   of file names in the file register."
                // DWARF 5 has a different include directory/file header and 0 is valid.
                if (version_ <= 4 && prev_file == 0) {
                    return false;
                }
                file = getFullFileName(prev_file);
                line = prev_line;
                return true;
            }
            prev_file = file_;
            prev_line = line_;
        }

        if (seq_end) {
            state = START;
            reset();
        }
    }

    return false;
}

#include "common/compile_check_avoid_end.h"
} // namespace doris

#endif
