You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
4.3 KiB
127 lines
4.3 KiB
4 months ago
|
//===-- DWARFDebugMacro.cpp -----------------------------------------------===//
|
||
|
//
|
||
|
// 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 "DWARFDebugMacro.h"
|
||
|
#include "SymbolFileDWARF.h"
|
||
|
|
||
|
#include "lldb/Symbol/DebugMacros.h"
|
||
|
|
||
|
#include "DWARFDataExtractor.h"
|
||
|
|
||
|
using namespace lldb_private;
|
||
|
|
||
|
DWARFDebugMacroHeader
|
||
|
DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
|
||
|
lldb::offset_t *offset) {
|
||
|
DWARFDebugMacroHeader header;
|
||
|
|
||
|
// Skip over the version field in header.
|
||
|
header.m_version = debug_macro_data.GetU16(offset);
|
||
|
|
||
|
uint8_t flags = debug_macro_data.GetU8(offset);
|
||
|
header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0;
|
||
|
|
||
|
if (flags & DEBUG_LINE_OFFSET_MASK) {
|
||
|
if (header.m_offset_is_64_bit)
|
||
|
header.m_debug_line_offset = debug_macro_data.GetU64(offset);
|
||
|
else
|
||
|
header.m_debug_line_offset = debug_macro_data.GetU32(offset);
|
||
|
}
|
||
|
|
||
|
// Skip over the operands table if it is present.
|
||
|
if (flags & OPCODE_OPERANDS_TABLE_MASK)
|
||
|
SkipOperandTable(debug_macro_data, offset);
|
||
|
|
||
|
return header;
|
||
|
}
|
||
|
|
||
|
void DWARFDebugMacroHeader::SkipOperandTable(
|
||
|
const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
|
||
|
uint8_t entry_count = debug_macro_data.GetU8(offset);
|
||
|
for (uint8_t i = 0; i < entry_count; i++) {
|
||
|
// Skip over the opcode number.
|
||
|
debug_macro_data.GetU8(offset);
|
||
|
|
||
|
uint64_t operand_count = debug_macro_data.GetULEB128(offset);
|
||
|
|
||
|
for (uint64_t j = 0; j < operand_count; j++) {
|
||
|
// Skip over the operand form
|
||
|
debug_macro_data.GetU8(offset);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DWARFDebugMacroEntry::ReadMacroEntries(
|
||
|
const DWARFDataExtractor &debug_macro_data,
|
||
|
const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
|
||
|
lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
|
||
|
DebugMacrosSP &debug_macros_sp) {
|
||
|
llvm::dwarf::MacroEntryType type =
|
||
|
static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
|
||
|
while (type != 0) {
|
||
|
lldb::offset_t new_offset = 0, str_offset = 0;
|
||
|
uint32_t line = 0;
|
||
|
const char *macro_str = nullptr;
|
||
|
uint32_t debug_line_file_idx = 0;
|
||
|
|
||
|
switch (type) {
|
||
|
case DW_MACRO_define:
|
||
|
case DW_MACRO_undef:
|
||
|
line = debug_macro_data.GetULEB128(offset);
|
||
|
macro_str = debug_macro_data.GetCStr(offset);
|
||
|
if (type == DW_MACRO_define)
|
||
|
debug_macros_sp->AddMacroEntry(
|
||
|
DebugMacroEntry::CreateDefineEntry(line, macro_str));
|
||
|
else
|
||
|
debug_macros_sp->AddMacroEntry(
|
||
|
DebugMacroEntry::CreateUndefEntry(line, macro_str));
|
||
|
break;
|
||
|
case DW_MACRO_define_strp:
|
||
|
case DW_MACRO_undef_strp:
|
||
|
line = debug_macro_data.GetULEB128(offset);
|
||
|
if (offset_is_64_bit)
|
||
|
str_offset = debug_macro_data.GetU64(offset);
|
||
|
else
|
||
|
str_offset = debug_macro_data.GetU32(offset);
|
||
|
macro_str = debug_str_data.GetCStr(&str_offset);
|
||
|
if (type == DW_MACRO_define_strp)
|
||
|
debug_macros_sp->AddMacroEntry(
|
||
|
DebugMacroEntry::CreateDefineEntry(line, macro_str));
|
||
|
else
|
||
|
debug_macros_sp->AddMacroEntry(
|
||
|
DebugMacroEntry::CreateUndefEntry(line, macro_str));
|
||
|
break;
|
||
|
case DW_MACRO_start_file:
|
||
|
line = debug_macro_data.GetULEB128(offset);
|
||
|
debug_line_file_idx = debug_macro_data.GetULEB128(offset);
|
||
|
debug_macros_sp->AddMacroEntry(
|
||
|
DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
|
||
|
break;
|
||
|
case DW_MACRO_end_file:
|
||
|
// This operation has no operands.
|
||
|
debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
|
||
|
break;
|
||
|
case DW_MACRO_import:
|
||
|
if (offset_is_64_bit)
|
||
|
new_offset = debug_macro_data.GetU64(offset);
|
||
|
else
|
||
|
new_offset = debug_macro_data.GetU32(offset);
|
||
|
debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
|
||
|
sym_file_dwarf->ParseDebugMacros(&new_offset)));
|
||
|
break;
|
||
|
default:
|
||
|
// TODO: Add support for other standard operations.
|
||
|
// TODO: Provide mechanism to hook handling of non-standard/extension
|
||
|
// operands.
|
||
|
return;
|
||
|
}
|
||
|
type = static_cast<llvm::dwarf::MacroEntryType>(
|
||
|
debug_macro_data.GetU8(offset));
|
||
|
}
|
||
|
}
|