mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[DWARFCallFrameInfo] Add Type enum to differentiate eh/debug_frame sections
Summary: instead of using a boolean to differentiate between the two section types, use an enum to make the intent clearer. I also remove the RegisterKind argument from the constructor, as this can be deduced from the Type argument. Reviewers: clayborg, jasonmolenda Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D34681 llvm-svn: 306521
This commit is contained in:
@@ -34,8 +34,9 @@ namespace lldb_private {
|
||||
|
||||
class DWARFCallFrameInfo {
|
||||
public:
|
||||
DWARFCallFrameInfo(ObjectFile &objfile, lldb::SectionSP §ion,
|
||||
lldb::RegisterKind reg_kind, bool is_eh_frame);
|
||||
enum Type { EH, DWARF };
|
||||
|
||||
DWARFCallFrameInfo(ObjectFile &objfile, lldb::SectionSP §ion, Type type);
|
||||
|
||||
~DWARFCallFrameInfo() = default;
|
||||
|
||||
@@ -142,21 +143,24 @@ private:
|
||||
|
||||
ObjectFile &m_objfile;
|
||||
lldb::SectionSP m_section_sp;
|
||||
lldb::RegisterKind m_reg_kind;
|
||||
Flags m_flags;
|
||||
Flags m_flags = 0;
|
||||
cie_map_t m_cie_map;
|
||||
|
||||
DataExtractor m_cfi_data;
|
||||
bool m_cfi_data_initialized; // only copy the section into the DE once
|
||||
bool m_cfi_data_initialized = false; // only copy the section into the DE once
|
||||
|
||||
FDEEntryMap m_fde_index;
|
||||
bool m_fde_index_initialized; // only scan the section for FDEs once
|
||||
bool m_fde_index_initialized = false; // only scan the section for FDEs once
|
||||
std::mutex m_fde_index_mutex; // and isolate the thread that does it
|
||||
|
||||
bool m_is_eh_frame;
|
||||
Type m_type;
|
||||
|
||||
CIESP
|
||||
ParseCIE(const uint32_t cie_offset);
|
||||
|
||||
lldb::RegisterKind GetRegisterKind() const {
|
||||
return m_type == EH ? lldb::eRegisterKindEHFrame : lldb::eRegisterKindDWARF;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
@@ -2502,7 +2502,7 @@ size_t ObjectFileMachO::ParseSymtab() {
|
||||
if (text_section_sp.get() && eh_frame_section_sp.get() &&
|
||||
m_type != eTypeDebugInfo) {
|
||||
DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
|
||||
eRegisterKindEHFrame, true);
|
||||
DWARFCallFrameInfo::EH);
|
||||
DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
|
||||
eh_frame.GetFunctionAddressAndSizeVector(functions);
|
||||
addr_t text_base_addr = text_section_sp->GetFileAddress();
|
||||
|
||||
@@ -151,15 +151,8 @@ GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr,
|
||||
}
|
||||
|
||||
DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile,
|
||||
SectionSP §ion_sp,
|
||||
lldb::RegisterKind reg_kind,
|
||||
bool is_eh_frame)
|
||||
: m_objfile(objfile), m_section_sp(section_sp),
|
||||
m_reg_kind(reg_kind), // The flavor of registers that the CFI data uses
|
||||
// (enum RegisterKind)
|
||||
m_flags(), m_cie_map(), m_cfi_data(), m_cfi_data_initialized(false),
|
||||
m_fde_index(), m_fde_index_initialized(false),
|
||||
m_is_eh_frame(is_eh_frame) {}
|
||||
SectionSP §ion_sp, Type type)
|
||||
: m_objfile(objfile), m_section_sp(section_sp), m_type(type) {}
|
||||
|
||||
bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) {
|
||||
FDEEntryMap::Entry fde_entry;
|
||||
@@ -266,8 +259,8 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
|
||||
cie_id = m_cfi_data.GetU32(&offset);
|
||||
end_offset = cie_offset + length + 4;
|
||||
}
|
||||
if (length > 0 && ((!m_is_eh_frame && cie_id == UINT32_MAX) ||
|
||||
(m_is_eh_frame && cie_id == 0ul))) {
|
||||
if (length > 0 && ((m_type == DWARF && cie_id == UINT32_MAX) ||
|
||||
(m_type == EH && cie_id == 0ul))) {
|
||||
size_t i;
|
||||
// cie.offset = cie_offset;
|
||||
// cie.length = length;
|
||||
@@ -303,7 +296,7 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
|
||||
|
||||
// m_cfi_data uses address size from target architecture of the process
|
||||
// may ignore these fields?
|
||||
if (!m_is_eh_frame && cie_sp->version >= CFI_VERSION4) {
|
||||
if (m_type == DWARF && cie_sp->version >= CFI_VERSION4) {
|
||||
cie_sp->address_size = m_cfi_data.GetU8(&offset);
|
||||
cie_sp->segment_size = m_cfi_data.GetU8(&offset);
|
||||
}
|
||||
@@ -312,7 +305,7 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
|
||||
cie_sp->data_align = (int32_t)m_cfi_data.GetSLEB128(&offset);
|
||||
|
||||
cie_sp->return_addr_reg_num =
|
||||
!m_is_eh_frame && cie_sp->version >= CFI_VERSION3
|
||||
m_type == DWARF && cie_sp->version >= CFI_VERSION3
|
||||
? static_cast<uint32_t>(m_cfi_data.GetULEB128(&offset))
|
||||
: m_cfi_data.GetU8(&offset);
|
||||
|
||||
@@ -482,7 +475,7 @@ void DWARFCallFrameInfo::GetFDEIndex() {
|
||||
// in eh_frame. CIE_pointer is an offset into the .debug_frame section.
|
||||
// So, variable cie_offset should be equal to cie_id for debug_frame.
|
||||
// FDE entries with cie_id == 0 shouldn't be ignored for it.
|
||||
if ((cie_id == 0 && m_is_eh_frame) || cie_id == UINT32_MAX || len == 0) {
|
||||
if ((cie_id == 0 && m_type == EH) || cie_id == UINT32_MAX || len == 0) {
|
||||
auto cie_sp = ParseCIE(current_entry);
|
||||
if (!cie_sp) {
|
||||
// Cannot parse, the reason is already logged
|
||||
@@ -496,7 +489,7 @@ void DWARFCallFrameInfo::GetFDEIndex() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_is_eh_frame)
|
||||
if (m_type == DWARF)
|
||||
cie_offset = cie_id;
|
||||
|
||||
if (cie_offset > m_cfi_data.GetByteSize()) {
|
||||
@@ -564,12 +557,12 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
|
||||
}
|
||||
|
||||
// FDE entries with zeroth cie_offset may occur for debug_frame.
|
||||
assert(!(m_is_eh_frame && 0 == cie_offset) && cie_offset != UINT32_MAX);
|
||||
assert(!(m_type == EH && 0 == cie_offset) && cie_offset != UINT32_MAX);
|
||||
|
||||
// Translate the CIE_id from the eh_frame format, which
|
||||
// is relative to the FDE offset, into a __eh_frame section
|
||||
// offset
|
||||
if (m_is_eh_frame) {
|
||||
if (m_type == EH) {
|
||||
unwind_plan.SetSourceName("eh_frame CFI");
|
||||
cie_offset = current_entry + (is_64bit ? 12 : 4) - cie_offset;
|
||||
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
|
||||
@@ -644,7 +637,7 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
|
||||
*cie_initial_row = cie->initial_row;
|
||||
UnwindPlan::RowSP row(cie_initial_row);
|
||||
|
||||
unwind_plan.SetRegisterKind(m_reg_kind);
|
||||
unwind_plan.SetRegisterKind(GetRegisterKind());
|
||||
unwind_plan.SetReturnAddressRegister(cie->return_addr_reg_num);
|
||||
|
||||
std::vector<UnwindPlan::RowSP> stack;
|
||||
|
||||
@@ -52,14 +52,14 @@ void UnwindTable::Initialize() {
|
||||
|
||||
SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
|
||||
if (sect.get()) {
|
||||
m_eh_frame_up.reset(new DWARFCallFrameInfo(m_object_file, sect,
|
||||
eRegisterKindEHFrame, true));
|
||||
m_eh_frame_up.reset(
|
||||
new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::EH));
|
||||
}
|
||||
|
||||
sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true);
|
||||
if (sect) {
|
||||
m_debug_frame_up.reset(
|
||||
new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindDWARF, false));
|
||||
new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::DWARF));
|
||||
}
|
||||
|
||||
sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true);
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
protected:
|
||||
llvm::SmallString<128> m_inputs_folder;
|
||||
|
||||
void TestBasic(bool eh_frame, llvm::StringRef symbol);
|
||||
void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);
|
||||
};
|
||||
|
||||
#define ASSERT_NO_ERROR(x) \
|
||||
@@ -94,7 +94,8 @@ static UnwindPlan::Row GetExpectedRow2() {
|
||||
return row;
|
||||
}
|
||||
|
||||
void DWARFCallFrameInfoTest::TestBasic(bool eh_frame, llvm::StringRef symbol) {
|
||||
void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type,
|
||||
llvm::StringRef symbol) {
|
||||
llvm::SmallString<128> yaml = m_inputs_folder;
|
||||
llvm::sys::path::append(yaml, "basic-call-frame-info.yaml");
|
||||
llvm::SmallString<128> obj = m_inputs_folder;
|
||||
@@ -116,13 +117,13 @@ void DWARFCallFrameInfoTest::TestBasic(bool eh_frame, llvm::StringRef symbol) {
|
||||
SectionList *list = module_sp->GetSectionList();
|
||||
ASSERT_NE(nullptr, list);
|
||||
|
||||
auto section_sp = list->FindSectionByType(
|
||||
eh_frame ? eSectionTypeEHFrame : eSectionTypeDWARFDebugFrame, false);
|
||||
auto section_sp = list->FindSectionByType(type == DWARFCallFrameInfo::EH
|
||||
? eSectionTypeEHFrame
|
||||
: eSectionTypeDWARFDebugFrame,
|
||||
false);
|
||||
ASSERT_NE(nullptr, section_sp);
|
||||
|
||||
DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp,
|
||||
eh_frame ? eRegisterKindEHFrame : eRegisterKindDWARF,
|
||||
eh_frame);
|
||||
DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp, type);
|
||||
|
||||
const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(
|
||||
ConstString(symbol), eSymbolTypeAny);
|
||||
@@ -137,11 +138,13 @@ void DWARFCallFrameInfoTest::TestBasic(bool eh_frame, llvm::StringRef symbol) {
|
||||
}
|
||||
|
||||
TEST_F(DWARFCallFrameInfoTest, Basic_dwarf3) {
|
||||
TestBasic(false, "debug_frame3");
|
||||
TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame3");
|
||||
}
|
||||
|
||||
TEST_F(DWARFCallFrameInfoTest, Basic_dwarf4) {
|
||||
TestBasic(false, "debug_frame4");
|
||||
TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame4");
|
||||
}
|
||||
|
||||
TEST_F(DWARFCallFrameInfoTest, Basic_eh) { TestBasic(true, "eh_frame"); }
|
||||
TEST_F(DWARFCallFrameInfoTest, Basic_eh) {
|
||||
TestBasic(DWARFCallFrameInfo::EH, "eh_frame");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user