Add implementation and tests for PC-based filtering of FDE search results.
This commit is contained in:
Родитель
92319f58b0
Коммит
0ac7d4eee5
|
@ -16,6 +16,12 @@ struct __attribute__((packed)) pl_cie_data_64 {
|
|||
uint8_t initial_instructions[0];
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) pl_fde_data_64 {
|
||||
uint64_t initial_location;
|
||||
uint64_t address_range;
|
||||
uint8_t instructions[];
|
||||
};
|
||||
|
||||
/* 32-bit and 64-bit length headers */
|
||||
struct pl_cfi_header_32 {
|
||||
uint32_t length;
|
||||
|
@ -37,9 +43,17 @@ typedef struct pl_cfi_entry {
|
|||
|
||||
union {
|
||||
struct pl_cie_data_64 cie_64;
|
||||
struct pl_fde_data_64 fde_64;
|
||||
};
|
||||
} pl_cfi_entry;
|
||||
|
||||
/* CFE lengths, minus the initial length field. */
|
||||
#define PL_CFI_LEN_64 (sizeof(pl_cfi_entry) - sizeof(uint32_t) - sizeof(uint64_t))
|
||||
#define PL_CFI_LEN_32 (sizeof(pl_cfi_entry) - sizeof(uint32_t))
|
||||
|
||||
/* PC values to be used when searching for FDE entries. */
|
||||
#define PL_CFI_EH_FRAME_PC 0x60
|
||||
#define PL_CFI_EH_FRAME_PC_RANGE 0x10
|
||||
|
||||
#define PL_CFI_DEBUG_FRAME_PC 0x30
|
||||
#define PL_CFI_DEBUG_FRAME_PC_RANGE 0x10
|
||||
|
|
|
@ -14,25 +14,31 @@ pl_cfi_entry ef[] __attribute__((section("__PL_DWARF,__eh_frame"))) = {
|
|||
|
||||
.cie_64 = {
|
||||
.version = 1, // eh_frame
|
||||
.augmentation[0] = 'z',
|
||||
.augmentation[1] = 'R',
|
||||
.augmentation[0] = 'z', // Enable GNU EH augmentation handling
|
||||
.augmentation[1] = 'R', // Pointer encoding is included in the augmentation data.
|
||||
.augmentation[2] = '\0',
|
||||
|
||||
.code_alignment_factor = 0,
|
||||
.data_alignment_factor = 0,
|
||||
.return_address_register = 0,
|
||||
|
||||
.augmentation_data[0] = sizeof(ef[0].cie_64.augmentation_data), // uleb128, must fit in 7 bits.
|
||||
.augmentation_data[0] = sizeof(ef[0].cie_64.augmentation_data), // augmentation data length; uleb128, must fit in 7 bits.
|
||||
.augmentation_data[1] = 0x04, // DW_EH_PE_udata8 FDE pointer size
|
||||
}
|
||||
},
|
||||
|
||||
/* A FDE entry */
|
||||
{.hdr_64 = {
|
||||
{
|
||||
.hdr_64 = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_LEN_64,
|
||||
.cie_id = sizeof(ef[0]), // Offset to the first CIE entry
|
||||
}},
|
||||
},
|
||||
.fde_64 = {
|
||||
.initial_location = PL_CFI_EH_FRAME_PC,
|
||||
.address_range = PL_CFI_EH_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
|
||||
/* Terminator */
|
||||
{.hdr_32 = {
|
||||
|
@ -69,11 +75,17 @@ pl_cfi_entry df[] __attribute__((section("__PL_DWARF,__debug_frame"))) = {
|
|||
},
|
||||
|
||||
/* A FDE entry */
|
||||
{.hdr_64 = {
|
||||
{
|
||||
.hdr_64 = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_LEN_64,
|
||||
.cie_id = 0, // Offset to the first CIE entry
|
||||
}},
|
||||
},
|
||||
.fde_64 = {
|
||||
.initial_location = PL_CFI_DEBUG_FRAME_PC,
|
||||
.address_range = PL_CFI_DEBUG_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
|
||||
/* Terminator */
|
||||
{.hdr_32 = {
|
||||
|
|
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.ios
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.ios
Двоичный файл не отображается.
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.macosx
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.macosx
Двоичный файл не отображается.
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.sim
Двоичные данные
Resources/Tests/PLCrashAsyncDwarfEncodingTests/test.sim
Двоичный файл не отображается.
|
@ -182,19 +182,20 @@ plcrash_error_t plcrash_async_dwarf_frame_reader_find_fde (plcrash_async_dwarf_f
|
|||
}
|
||||
|
||||
/* Decode the FDE */
|
||||
err = plcrash_async_dwarf_fde_info_init(fde_info, reader->mobj, byteorder, reader->address_size, cfi_entry, reader->debug_frame);
|
||||
err = plcrash_async_dwarf_fde_info_init(fde_info, reader->mobj, byteorder, dwarf_word_size, cfi_entry, reader->debug_frame);
|
||||
if (err != PLCRASH_ESUCCESS)
|
||||
return err;
|
||||
|
||||
// TODO
|
||||
return PLCRASH_ESUCCESS;
|
||||
/* Check if our PC is within range */
|
||||
PLCF_DEBUG("Evaluating entry with start %"PRIx64 " end=%" PRIx64 " pc=%" PRIx64, fde_info->pc_start, fde_info->pc_end, pc);
|
||||
if (pc >= fde_info->pc_start && pc < fde_info->pc_end)
|
||||
return PLCRASH_ESUCCESS;
|
||||
|
||||
/* Skip to the next entry */
|
||||
cfi_entry = next_cfi_entry;
|
||||
}
|
||||
|
||||
// TODO
|
||||
return PLCRASH_ESUCCESS;
|
||||
return PLCRASH_ENOTFOUND;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
plcrash_error_t err;
|
||||
plcrash_async_dwarf_fde_info_t fde_info;
|
||||
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_eh_reader, 0x0, 0x0 /* TODO */, &fde_info);
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_eh_reader, 0x0, PL_CFI_EH_FRAME_PC+PL_CFI_EH_FRAME_PC_RANGE-1, &fde_info);
|
||||
STAssertEquals(PLCRASH_ESUCCESS, err, @"FDE search failed");
|
||||
|
||||
/* Should be the second entry in the table, plus the 12 byte length initial length field. */
|
||||
|
@ -132,13 +132,17 @@
|
|||
//STAssertEquals(fde_info.fde_instruction_offset, (pl_vm_address_t)0x0, @"Incorrect instruction offset (should be the first entry)");
|
||||
|
||||
plcrash_async_dwarf_fde_info_free(&fde_info);
|
||||
|
||||
/* Verify that an unknown PC returns ENOTFOUND. */
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_debug_reader, 0x0, PL_CFI_EH_FRAME_PC+PL_CFI_EH_FRAME_PC_RANGE, &fde_info);
|
||||
STAssertEquals(PLCRASH_ENOTFOUND, err, @"FDE should not have been found");
|
||||
}
|
||||
|
||||
- (void) testFindDebugFrameDescriptorEntry {
|
||||
plcrash_error_t err;
|
||||
plcrash_async_dwarf_fde_info_t fde_info;
|
||||
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_debug_reader, 0x0, 0x0 /* TODO */, &fde_info);
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_debug_reader, 0x0, PL_CFI_DEBUG_FRAME_PC+PL_CFI_DEBUG_FRAME_PC_RANGE-1, &fde_info);
|
||||
STAssertEquals(PLCRASH_ESUCCESS, err, @"FDE search failed");
|
||||
|
||||
/* Should be the second entry in the table, plus the 12 byte length initial length field. */
|
||||
|
@ -148,6 +152,10 @@
|
|||
//STAssertEquals(fde_info.fde_instruction_offset, (pl_vm_address_t)0x0, @"Incorrect instruction offset (should be the first entry)");
|
||||
|
||||
plcrash_async_dwarf_fde_info_free(&fde_info);
|
||||
|
||||
/* Verify that an unknown PC freturns ENOTFOUND */
|
||||
err = plcrash_async_dwarf_frame_reader_find_fde(&_debug_reader, 0x0, PL_CFI_DEBUG_FRAME_PC+PL_CFI_DEBUG_FRAME_PC_RANGE, &fde_info);
|
||||
STAssertEquals(PLCRASH_ENOTFOUND, err, @"FDE should not have been found");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef struct plcrash_async_dwarf_fde_info {
|
|||
* the in-memory PC address of a loaded images. */
|
||||
uint64_t pc_start;
|
||||
|
||||
/** The end of the IP range covered by this FDE (inclusive). The address is relative to the image's base address, <em>not</em>
|
||||
/** The end of the IP range covered by this FDE (exclusive). The address is relative to the image's base address, <em>not</em>
|
||||
* the in-memory PC address of a loaded images. */
|
||||
uint64_t pc_end;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче