Skip to content

Commit a5db208

Browse files
committed
[LLDB] Refactor CIE and FDE handling in DWARFCallFrameInfo
- Introduced a new helper function `IsCIEMarker` to determine if a given `cie_id` indicates a CIE (Common Information Entry) or FDE (Frame Description Entry). - New helper function can now correctly identify both 32-bit and 64-bit CIE based on the DWARF specifications. - Updated the `ParseCIE` and `GetFDEIndex` methods to utilize the new helper function for improved clarity and correctness in identifying CIE and FDE entries. - Replaced direct comparisons with `UINT32_MAX` and `UINT64_MAX` with `std::numeric_limits` for better readability.
1 parent ef7de8d commit a5db208

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

lldb/source/Symbol/DWARFCallFrameInfo.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
#include "lldb/Utility/LLDBLog.h"
2121
#include "lldb/Utility/Log.h"
2222
#include "lldb/Utility/Timer.h"
23+
#include <cstdint>
2324
#include <cstring>
25+
#include <limits>
2426
#include <list>
2527
#include <optional>
2628

@@ -147,6 +149,27 @@ GetGNUEHPointer(const DataExtractor &DE, lldb::offset_t *offset_ptr,
147149
return baseAddress + addressValue;
148150
}
149151

152+
// Check if the given cie_id value indicates a CIE (Common Information Entry)
153+
// as opposed to an FDE (Frame Description Entry).
154+
//
155+
// For eh_frame sections: CIE is marked with cie_id == 0
156+
// For debug_frame sections:
157+
// - DWARF32: CIE is marked with cie_id ==
158+
// std::numeric_limits<uint32_t>::max()
159+
// - DWARF64: CIE is marked with cie_id ==
160+
// std::numeric_limits<uint64_t>::max()
161+
static bool IsCIEMarker(uint64_t cie_id, bool is_64bit,
162+
DWARFCallFrameInfo::Type type) {
163+
if (type == DWARFCallFrameInfo::EH)
164+
return cie_id == 0;
165+
166+
// DWARF type
167+
if (is_64bit)
168+
return cie_id == std::numeric_limits<uint64_t>::max();
169+
170+
return cie_id == std::numeric_limits<uint32_t>::max();
171+
}
172+
150173
DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile,
151174
SectionSP &section_sp, Type type)
152175
: m_objfile(objfile), m_section_sp(section_sp), m_type(type) {}
@@ -283,7 +306,7 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
283306
GetCFIData();
284307
uint32_t length = m_cfi_data.GetU32(&offset);
285308
dw_offset_t cie_id, end_offset;
286-
bool is_64bit = (length == UINT32_MAX);
309+
bool is_64bit = (length == std::numeric_limits<uint32_t>::max());
287310
if (is_64bit) {
288311
length = m_cfi_data.GetU64(&offset);
289312
cie_id = m_cfi_data.GetU64(&offset);
@@ -292,8 +315,9 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
292315
cie_id = m_cfi_data.GetU32(&offset);
293316
end_offset = cie_offset + length + 4;
294317
}
295-
if (length > 0 && ((m_type == DWARF && cie_id == UINT32_MAX) ||
296-
(m_type == EH && cie_id == 0ul))) {
318+
319+
// Check if this is a CIE or FDE based on the CIE ID marker
320+
if (length > 0 && IsCIEMarker(cie_id, is_64bit, m_type)) {
297321
size_t i;
298322
// cie.offset = cie_offset;
299323
// cie.length = length;
@@ -470,7 +494,7 @@ void DWARFCallFrameInfo::GetFDEIndex() {
470494
const dw_offset_t current_entry = offset;
471495
dw_offset_t cie_id, next_entry, cie_offset;
472496
uint32_t len = m_cfi_data.GetU32(&offset);
473-
bool is_64bit = (len == UINT32_MAX);
497+
bool is_64bit = (len == std::numeric_limits<uint32_t>::max());
474498
if (is_64bit) {
475499
len = m_cfi_data.GetU64(&offset);
476500
cie_id = m_cfi_data.GetU64(&offset);
@@ -493,11 +517,8 @@ void DWARFCallFrameInfo::GetFDEIndex() {
493517
return;
494518
}
495519

496-
// An FDE entry contains CIE_pointer in debug_frame in same place as cie_id
497-
// in eh_frame. CIE_pointer is an offset into the .debug_frame section. So,
498-
// variable cie_offset should be equal to cie_id for debug_frame.
499-
// FDE entries with cie_id == 0 shouldn't be ignored for it.
500-
if ((cie_id == 0 && m_type == EH) || cie_id == UINT32_MAX || len == 0) {
520+
// Check if this is a CIE or FDE based on the CIE ID marker
521+
if (IsCIEMarker(cie_id, is_64bit, m_type) || len == 0) {
501522
auto cie_sp = ParseCIE(current_entry);
502523
if (!cie_sp) {
503524
// Cannot parse, the reason is already logged
@@ -568,7 +589,7 @@ DWARFCallFrameInfo::ParseFDE(dw_offset_t dwarf_offset,
568589

569590
uint32_t length = m_cfi_data.GetU32(&offset);
570591
dw_offset_t cie_offset;
571-
bool is_64bit = (length == UINT32_MAX);
592+
bool is_64bit = (length == std::numeric_limits<uint32_t>::max());
572593
if (is_64bit) {
573594
length = m_cfi_data.GetU64(&offset);
574595
cie_offset = m_cfi_data.GetU64(&offset);
@@ -577,7 +598,8 @@ DWARFCallFrameInfo::ParseFDE(dw_offset_t dwarf_offset,
577598
}
578599

579600
// FDE entries with zeroth cie_offset may occur for debug_frame.
580-
assert(!(m_type == EH && 0 == cie_offset) && cie_offset != UINT32_MAX);
601+
assert(!(m_type == EH && 0 == cie_offset) &&
602+
cie_offset != std::numeric_limits<uint32_t>::max());
581603

582604
// Translate the CIE_id from the eh_frame format, which is relative to the
583605
// FDE offset, into a __eh_frame section offset

0 commit comments

Comments
 (0)