//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DWARFDebugRanges.h"
#include "DWARFUnit.h"
#include "lldb/Utility/Stream.h"

using namespace lldb_private;

static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
  switch(addr_size) {
    case 2:
      return 0xffff;
    case 4:
      return 0xffffffff;
    case 8:
      return 0xffffffffffffffff;
  }
  llvm_unreachable("GetBaseAddressMarker unsupported address size.");
}

DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}

void DWARFDebugRanges::Extract(DWARFContext &context) {
  DWARFRangeList range_list;
  lldb::offset_t offset = 0;
  dw_offset_t debug_ranges_offset = offset;
  while (Extract(context, &offset, range_list)) {
    range_list.Sort();
    m_range_map[debug_ranges_offset] = range_list;
    debug_ranges_offset = offset;
  }
}

bool DWARFDebugRanges::Extract(DWARFContext &context,
                               lldb::offset_t *offset_ptr,
                               DWARFRangeList &range_list) {
  range_list.Clear();

  lldb::offset_t range_offset = *offset_ptr;
  const DWARFDataExtractor &debug_ranges_data = context.getOrLoadRangesData();
  uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
  dw_addr_t base_addr = 0;
  dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);

  while (
      debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
    dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
    dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);

    if (!begin && !end) {
      // End of range list
      break;
    }

    if (begin == base_addr_marker) {
      base_addr = end;
      continue;
    }

    // Filter out empty ranges
    if (begin < end)
      range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
  }

  // Make sure we consumed at least something
  return range_offset != *offset_ptr;
}

void DWARFDebugRanges::Dump(Stream &s,
                            const DWARFDataExtractor &debug_ranges_data,
                            lldb::offset_t *offset_ptr,
                            dw_addr_t cu_base_addr) {
  uint32_t addr_size = s.GetAddressByteSize();

  dw_addr_t base_addr = cu_base_addr;
  while (
      debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
    dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
    dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
    // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits of
    // ones
    if (begin == 0xFFFFFFFFull && addr_size == 4)
      begin = LLDB_INVALID_ADDRESS;

    s.Indent();
    if (begin == 0 && end == 0) {
      s.PutCString(" End");
      break;
    } else if (begin == LLDB_INVALID_ADDRESS) {
      // A base address selection entry
      base_addr = end;
      s.Address(base_addr, sizeof(dw_addr_t), " Base address = ");
    } else {
      // Convert from offset to an address
      dw_addr_t begin_addr = begin + base_addr;
      dw_addr_t end_addr = end + base_addr;

      s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t), nullptr);
    }
  }
}

bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
                                  dw_offset_t debug_ranges_offset,
                                  DWARFRangeList &range_list) const {
  dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
  range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
  if (pos != m_range_map.end()) {
    range_list = pos->second;

    // All DW_AT_ranges are relative to the base address of the compile
    // unit. We add the compile unit base address to make sure all the
    // addresses are properly fixed up.
    range_list.Slide(cu->GetBaseAddress());
    return true;
  }
  return false;
}

uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
  lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
  return 0;
}

bool DWARFDebugRngLists::ExtractRangeList(
    const DWARFDataExtractor &data, uint8_t addrSize,
    lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
  rangeList.clear();

  bool error = false;
  while (!error) {
    switch (data.GetU8(offset_ptr)) {
    case DW_RLE_end_of_list:
      return true;

    case DW_RLE_start_length: {
      dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
      dw_addr_t len = data.GetULEB128(offset_ptr);
      rangeList.push_back({DW_RLE_start_length, begin, len});
      break;
    }

    case DW_RLE_start_end: {
      dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
      dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize);
      rangeList.push_back({DW_RLE_start_end, begin, end});
      break;
    }

    case DW_RLE_base_address: {
      dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize);
      rangeList.push_back({DW_RLE_base_address, base, 0});
      break;
    }

    case DW_RLE_offset_pair: {
      dw_addr_t begin = data.GetULEB128(offset_ptr);
      dw_addr_t end = data.GetULEB128(offset_ptr);
      rangeList.push_back({DW_RLE_offset_pair, begin, end});
      break;
    }

    case DW_RLE_base_addressx: {
      dw_addr_t base = data.GetULEB128(offset_ptr);
      rangeList.push_back({DW_RLE_base_addressx, base, 0});
      break;
    }

    case DW_RLE_startx_endx: {
      dw_addr_t start = data.GetULEB128(offset_ptr);
      dw_addr_t end = data.GetULEB128(offset_ptr);
      rangeList.push_back({DW_RLE_startx_endx, start, end});
      break;
    }

    case DW_RLE_startx_length: {
      dw_addr_t start = data.GetULEB128(offset_ptr);
      dw_addr_t length = data.GetULEB128(offset_ptr);
      rangeList.push_back({DW_RLE_startx_length, start, length});
      break;
    }

    default:
      lldbassert(0 && "unknown range list entry encoding");
      error = true;
    }
  }

  return false;
}

static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
                                                uint32_t index) {
  uint32_t index_size = cu->GetAddressByteSize();
  dw_offset_t addr_base = cu->GetAddrBase();
  lldb::offset_t offset = addr_base + index * index_size;
  return cu->GetSymbolFileDWARF()
      .GetDWARFContext()
      .getOrLoadAddrData()
      .GetMaxU64(&offset, index_size);
}

bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
                                    dw_offset_t debug_ranges_offset,
                                    DWARFRangeList &range_list) const {
  range_list.Clear();
  dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
  auto pos = m_range_map.find(debug_ranges_address);
  if (pos != m_range_map.end()) {
    dw_addr_t BaseAddr = cu->GetBaseAddress();
    for (const RngListEntry &E : pos->second) {
      switch (E.encoding) {
      case DW_RLE_start_length:
        range_list.Append(DWARFRangeList::Entry(E.value0, E.value1));
        break;
      case DW_RLE_base_address:
        BaseAddr = E.value0;
        break;
      case DW_RLE_start_end:
        range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0));
        break;
      case DW_RLE_offset_pair:
        range_list.Append(
            DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0));
        break;
      case DW_RLE_base_addressx: {
        BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0);
        break;
      }
      case DW_RLE_startx_endx: {
        dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
        dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1);
        range_list.Append(DWARFRangeList::Entry(start, end - start));
        break;
      }
      case DW_RLE_startx_length: {
        dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
        range_list.Append(DWARFRangeList::Entry(start, E.value1));
        break;
      }
      default:
        llvm_unreachable("unexpected encoding");
      }
    }
    return true;
  }
  return false;
}

void DWARFDebugRngLists::Extract(DWARFContext &context) {
  const DWARFDataExtractor &data = context.getOrLoadRngListsData();
  lldb::offset_t offset = 0;

  uint64_t length = data.GetU32(&offset);
  // FIXME: Handle DWARF64.
  lldb::offset_t end = offset + length;

  // Check version.
  if (data.GetU16(&offset) < 5)
    return;

  uint8_t addrSize = data.GetU8(&offset);

  // We do not support non-zero segment selector size.
  if (data.GetU8(&offset) != 0) {
    lldbassert(0 && "not implemented");
    return;
  }

  uint32_t offsetsAmount = data.GetU32(&offset);
  for (uint32_t i = 0; i < offsetsAmount; ++i)
    Offsets.push_back(data.GetMaxU64(&offset, 4));

  lldb::offset_t listOffset = offset;
  std::vector<RngListEntry> rangeList;
  while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) {
    m_range_map[listOffset] = rangeList;
    listOffset = offset;
  }
}

uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
  return Offsets[Index];
}
