Implementation and tests for compressed encoding tables, using a private (rather than common) encoding reference.
This commit is contained in:
Родитель
92b0e45319
Коммит
cd3eee3570
|
@ -3,13 +3,19 @@
|
|||
|
||||
// Keep in sync with PLCrashAsyncCompactUnwindEncodingTests
|
||||
#define BASE_PC 0
|
||||
#define PC_COMPACT_COMMON (BASE_PC+1)
|
||||
|
||||
#define PC_COMPACT_BASE (BASE_PC+1)
|
||||
|
||||
#define PC_COMPACT_COMMON (PC_COMPACT_BASE+0)
|
||||
#define PC_COMPACT_COMMON_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFF)
|
||||
|
||||
#define PC_COMPACT_PRIVATE (PC_COMPACT_BASE+1)
|
||||
#define PC_COMPACT_PRIVATE_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFE)
|
||||
|
||||
struct unwind_sect_compressed_page {
|
||||
struct unwind_info_compressed_second_level_page_header header;
|
||||
uint32_t entries[1];
|
||||
uint32_t entries[2];
|
||||
uint32_t encodings[1];
|
||||
};
|
||||
|
||||
struct unwind_sect_regular_page {
|
||||
|
@ -65,18 +71,27 @@ struct unwind_sect data __attribute__((section("__TEXT,__unwind_info"))) = {
|
|||
}
|
||||
},
|
||||
|
||||
#define COMPRESSED(foff, enc_index) ((foff & 0x00FFFFFF) | (enc_index << 24))
|
||||
|
||||
.compressed_page_1 = {
|
||||
.header = {
|
||||
.kind = UNWIND_SECOND_LEVEL_COMPRESSED,
|
||||
.entryPageOffset = offsetof(struct unwind_sect_compressed_page, entries),
|
||||
.entryCount = 1
|
||||
.entryCount = 2,
|
||||
.encodingsPageOffset = offsetof(struct unwind_sect_compressed_page, encodings),
|
||||
.encodingsCount = 1
|
||||
},
|
||||
.entries = {
|
||||
#define COMPRESSED(foff, enc_index) ((foff & 0x00FFFFFF) | (enc_index << 24))
|
||||
|
||||
/* Note that these are offsets from the first-level functionOffset */
|
||||
COMPRESSED(0, 0)
|
||||
COMPRESSED(0, 0),
|
||||
COMPRESSED(1, 1)
|
||||
|
||||
#undef COMPRESSED
|
||||
},
|
||||
|
||||
.encodings = {
|
||||
PC_COMPACT_PRIVATE_ENCODING
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.ios
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.ios
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.sim
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.sim
Двоичный файл не отображается.
|
@ -279,9 +279,31 @@ plcrash_error_t plcrash_async_cfe_reader_find_pc (plcrash_async_cfe_reader_t *re
|
|||
return PLCRASH_ESUCCESS;
|
||||
}
|
||||
|
||||
// TODO
|
||||
__builtin_trap();
|
||||
PLCF_DEBUG("FOUND func_offset=%" PRIx32 " idx = %" PRIx32, base_foffset + UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(c_entry), UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(c_entry));
|
||||
/* Map in the encodings table */
|
||||
uint32_t encodings_offset = byteorder->swap16(header->encodingsPageOffset);
|
||||
uint32_t encodings_count = byteorder->swap16(header->encodingsCount);
|
||||
|
||||
if (VERIFY_SIZE_T(sizeof(uint32_t), encodings_count)) {
|
||||
PLCF_DEBUG("CFE second level entry count extends beyond the range of size_t");
|
||||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
if (!plcrash_async_mobject_verify_local_pointer(reader->mobj, header, encodings_offset, encodings_count * sizeof(uint32_t))) {
|
||||
PLCF_DEBUG("CFE compressed encodings table lies outside the mapped CFE range");
|
||||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
uint32_t *encodings = (uint32_t *) (((uintptr_t)header) + encodings_offset);
|
||||
|
||||
/* Verify that the entry is within range */
|
||||
c_encoding_idx -= common_enc_count;
|
||||
if (c_encoding_idx >= encodings_count) {
|
||||
PLCF_DEBUG("Encoding index lies outside the second level encoding table");
|
||||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
/* Extract the encoding */
|
||||
*encoding = encodings[c_encoding_idx];
|
||||
return PLCRASH_ESUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
#define PC_COMPACT_COMMON (BASE_PC+1)
|
||||
#define PC_COMPACT_COMMON_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFF)
|
||||
|
||||
/** PC to use for the compact-private test */
|
||||
#define PC_COMPACT_PRIVATE (BASE_PC+2)
|
||||
#define PC_COMPACT_PRIVATE_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFE)
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
|
@ -216,4 +220,16 @@
|
|||
STAssertEquals(encoding, (uint32_t)PC_COMPACT_COMMON_ENCODING, @"Incorrect encoding returned");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading of a PC, compressed, private encoding.
|
||||
*/
|
||||
- (void) testReadCompressedEncoding {
|
||||
plcrash_error_t err;
|
||||
|
||||
uint32_t encoding;
|
||||
err = plcrash_async_cfe_reader_find_pc(&_reader, PC_COMPACT_PRIVATE, &encoding);
|
||||
STAssertEquals(PLCRASH_ESUCCESS, err, @"Failed to locate CFE entry");
|
||||
STAssertEquals(encoding, (uint32_t)PC_COMPACT_PRIVATE_ENCODING, @"Incorrect encoding returned");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче