Fix GNU EH pointer reads; these should use the native platform pointer size, rather than the DWARF entry's 32/64 word size.
This commit is contained in:
Родитель
2161b2a159
Коммит
f4c680ef57
|
@ -2,7 +2,7 @@
|
|||
|
||||
/* Constants and structures used to generate the CFI test binaries. See also: Resources/Tests/PLCrashAsyncDwarfEncodingTests */
|
||||
|
||||
struct __attribute__((packed)) pl_cie_data_64 {
|
||||
struct __attribute__((packed)) pl_cie_data {
|
||||
uint8_t version; /* Must be set to 1 or 3 -- 1=eh_frame, 3=DWARF3, 4=DWARF4 */
|
||||
|
||||
uint8_t augmentation[7];
|
||||
|
@ -22,6 +22,13 @@ struct __attribute__((packed)) pl_fde_data_64 {
|
|||
uint8_t instructions[];
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) pl_fde_data_32 {
|
||||
uint32_t initial_location;
|
||||
uint32_t address_range;
|
||||
uint8_t instructions[];
|
||||
};
|
||||
|
||||
|
||||
/* 32-bit and 64-bit length headers */
|
||||
struct pl_cfi_header_32 {
|
||||
uint32_t length;
|
||||
|
@ -35,16 +42,21 @@ struct pl_cfi_header_64 {
|
|||
} __attribute__((packed));
|
||||
|
||||
/* Mock entry */
|
||||
typedef struct pl_cfi_entry {
|
||||
union {
|
||||
struct pl_cfi_header_32 hdr_32;
|
||||
struct pl_cfi_header_64 hdr_64;
|
||||
};
|
||||
|
||||
union {
|
||||
struct pl_cie_data_64 cie_64;
|
||||
struct pl_fde_data_64 fde_64;
|
||||
};
|
||||
typedef union pl_cfi_entry {
|
||||
struct {
|
||||
struct pl_cfi_header_64 hdr;
|
||||
union {
|
||||
struct pl_cie_data cie;
|
||||
struct pl_fde_data_64 fde;
|
||||
};
|
||||
} e64;
|
||||
struct {
|
||||
struct pl_cfi_header_32 hdr;
|
||||
union {
|
||||
struct pl_cie_data cie;
|
||||
struct pl_fde_data_32 fde;
|
||||
};
|
||||
} e32;
|
||||
} pl_cfi_entry;
|
||||
|
||||
/* Initial length field size */
|
||||
|
@ -52,8 +64,8 @@ typedef struct pl_cfi_entry {
|
|||
#define PL_CFI_LEN_SIZE_32 (sizeof(uint32_t))
|
||||
|
||||
/* CFE lengths, minus the initial length field. */
|
||||
#define PL_CFI_SIZE_64 (sizeof(pl_cfi_entry) - sizeof(uint32_t) - sizeof(uint64_t))
|
||||
#define PL_CFI_SIZE_32 (sizeof(pl_cfi_entry) - sizeof(uint32_t))
|
||||
#define PL_CFI_SIZE_64 (sizeof(pl_cfi_entry) - PL_CFI_LEN_SIZE_64)
|
||||
#define PL_CFI_SIZE_32 (sizeof(pl_cfi_entry) - PL_CFI_LEN_SIZE_32)
|
||||
|
||||
/* PC values to be used when searching for FDE entries. */
|
||||
#define PL_CFI_EH_FRAME_PC 0x60
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
|
||||
// TODO
|
||||
pl_cfi_entry ef[] __attribute__((section("__PL_DWARF,__eh_frame"))) = {
|
||||
#ifdef __LP64__
|
||||
/* Common CIE entry */
|
||||
{
|
||||
.hdr_64 = {
|
||||
.e64.hdr = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_SIZE_64,
|
||||
.cie_id = 0,
|
||||
},
|
||||
|
||||
.cie_64 = {
|
||||
.e64.cie = {
|
||||
.version = 1, // eh_frame
|
||||
.augmentation[0] = 'z', // Enable GNU EH augmentation handling
|
||||
.augmentation[1] = 'R', // Pointer encoding is included in the augmentation data.
|
||||
|
@ -22,26 +23,61 @@ pl_cfi_entry ef[] __attribute__((section("__PL_DWARF,__eh_frame"))) = {
|
|||
.data_alignment_factor = 0,
|
||||
.return_address_register = 0,
|
||||
|
||||
.augmentation_data[0] = sizeof(ef[0].cie_64.augmentation_data), // augmentation data length; uleb128, must fit in 7 bits.
|
||||
.augmentation_data[0] = sizeof(ef[0].e64.cie.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 = {
|
||||
.e64.hdr = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_SIZE_64,
|
||||
.cie_id = sizeof(ef[0]) + PL_CFI_LEN_SIZE_64, // Offset to the first CIE entry
|
||||
},
|
||||
.fde_64 = {
|
||||
.e64.fde = {
|
||||
.initial_location = PL_CFI_EH_FRAME_PC,
|
||||
.address_range = PL_CFI_EH_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
#else
|
||||
/* Common CIE entry */
|
||||
{
|
||||
.e32.hdr = {
|
||||
.length = PL_CFI_SIZE_32,
|
||||
.cie_id = 0,
|
||||
},
|
||||
|
||||
.e32.cie = {
|
||||
.version = 1, // eh_frame
|
||||
.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].e32.cie.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 */
|
||||
{
|
||||
.e32.hdr = {
|
||||
.length = PL_CFI_SIZE_32,
|
||||
.cie_id = sizeof(ef[0]) + PL_CFI_LEN_SIZE_32, // Offset to the first CIE entry
|
||||
},
|
||||
.e32.fde = {
|
||||
.initial_location = PL_CFI_EH_FRAME_PC,
|
||||
.address_range = PL_CFI_EH_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
/* Terminator */
|
||||
{.hdr_32 = {
|
||||
{.e32.hdr = {
|
||||
.length = 0x0
|
||||
}}
|
||||
|
||||
|
@ -51,15 +87,16 @@ pl_cfi_entry ef[] __attribute__((section("__PL_DWARF,__eh_frame"))) = {
|
|||
|
||||
|
||||
pl_cfi_entry df[] __attribute__((section("__PL_DWARF,__debug_frame"))) = {
|
||||
#ifdef __LP64__
|
||||
/* Common CIE entry */
|
||||
{
|
||||
.hdr_64 = {
|
||||
.e64.hdr = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_SIZE_64,
|
||||
.cie_id = UINT64_MAX,
|
||||
},
|
||||
|
||||
.cie_64 = {
|
||||
.e64.cie = {
|
||||
.version = 1, // eh_frame
|
||||
.augmentation[0] = 'z',
|
||||
.augmentation[1] = 'R',
|
||||
|
@ -69,26 +106,61 @@ pl_cfi_entry df[] __attribute__((section("__PL_DWARF,__debug_frame"))) = {
|
|||
.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].e64.cie.augmentation_data), // uleb128, must fit in 7 bits.
|
||||
.augmentation_data[1] = 0x04, // DW_EH_PE_udata8 FDE pointer size
|
||||
}
|
||||
},
|
||||
|
||||
/* A FDE entry */
|
||||
{
|
||||
.hdr_64 = {
|
||||
.e64.hdr = {
|
||||
.flag64 = UINT32_MAX,
|
||||
.length = PL_CFI_SIZE_64,
|
||||
.cie_id = 0, // Offset to the first CIE entry
|
||||
},
|
||||
.fde_64 = {
|
||||
.e64.fde = {
|
||||
.initial_location = PL_CFI_DEBUG_FRAME_PC,
|
||||
.address_range = PL_CFI_DEBUG_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
#else
|
||||
/* Common CIE entry */
|
||||
{
|
||||
.e32.hdr = {
|
||||
.length = PL_CFI_SIZE_32,
|
||||
.cie_id = UINT32_MAX,
|
||||
},
|
||||
|
||||
.e32.cie = {
|
||||
.version = 1, // eh_frame
|
||||
.augmentation[0] = 'z',
|
||||
.augmentation[1] = 'R',
|
||||
.augmentation[2] = '\0',
|
||||
|
||||
.code_alignment_factor = 0,
|
||||
.data_alignment_factor = 0,
|
||||
.return_address_register = 0,
|
||||
|
||||
.augmentation_data[0] = sizeof(ef[0].e32.cie.augmentation_data), // uleb128, must fit in 7 bits.
|
||||
.augmentation_data[1] = 0x04, // DW_EH_PE_udata8 FDE pointer size
|
||||
}
|
||||
},
|
||||
|
||||
/* A FDE entry */
|
||||
{
|
||||
.e32.hdr = {
|
||||
.length = PL_CFI_SIZE_32,
|
||||
.cie_id = 0, // Offset to the first CIE entry
|
||||
},
|
||||
.e32.fde = {
|
||||
.initial_location = PL_CFI_DEBUG_FRAME_PC,
|
||||
.address_range = PL_CFI_DEBUG_FRAME_PC_RANGE
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
/* Terminator */
|
||||
{.hdr_32 = {
|
||||
{.e32.hdr = {
|
||||
.length = 0x0
|
||||
}}
|
||||
};
|
||||
|
|
Двоичные данные
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
Двоичный файл не отображается.
|
@ -122,7 +122,7 @@ plcrash_error_t plcrash_async_dwarf_cie_info_init (plcrash_async_dwarf_cie_info_
|
|||
}
|
||||
|
||||
if (info->cie_version != 1 && info->cie_version != 3 && info->cie_version != 4) {
|
||||
PLCF_DEBUG("CIE id is not one of 1 (eh_frame) or 3 (DWARF3) or 4 (DWARF4): %" PRIu8, info->cie_version);
|
||||
PLCF_DEBUG("CIE version is not one of 1 (eh_frame) or 3 (DWARF3) or 4 (DWARF4): %" PRIu8, info->cie_version);
|
||||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ 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, dwarf_word_size, cfi_entry, reader->debug_frame);
|
||||
err = plcrash_async_dwarf_fde_info_init(fde_info, reader->mobj, byteorder, reader->address_size, cfi_entry, reader->debug_frame);
|
||||
if (err != PLCRASH_ESUCCESS)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -125,10 +125,14 @@
|
|||
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. */
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + 12, @"Incorrect offset");
|
||||
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_64, @"Incorrect length");
|
||||
/* Should be the second entry in the table, plus the initial length field. */
|
||||
if (_eh_reader.address_size == 8) {
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + PL_CFI_LEN_SIZE_64, @"Incorrect offset");
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_64, @"Incorrect length");
|
||||
} else {
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + PL_CFI_LEN_SIZE_32, @"Incorrect offset");
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_32, @"Incorrect length");
|
||||
}
|
||||
//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);
|
||||
|
@ -145,10 +149,15 @@
|
|||
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. */
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + 12, @"Incorrect offset");
|
||||
/* Should be the second entry in the table, plus the initial length field. */
|
||||
if (_eh_reader.address_size == 8) {
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + PL_CFI_LEN_SIZE_64, @"Incorrect offset");
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_64, @"Incorrect length");
|
||||
} else {
|
||||
STAssertEquals(fde_info.fde_offset, (pl_vm_address_t) (sizeof(pl_cfi_entry)) + PL_CFI_LEN_SIZE_32, @"Incorrect offset");
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_32, @"Incorrect length");
|
||||
}
|
||||
|
||||
STAssertEquals(fde_info.fde_length, (uint64_t)PL_CFI_SIZE_64, @"Incorrect length");
|
||||
//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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче