Implementation and tests for reading regular entries.
This commit is contained in:
Родитель
5a18092f4c
Коммит
bcf18ce1a9
|
@ -7,10 +7,13 @@
|
|||
#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_COMMON_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_COMPACT_COMMON)
|
||||
|
||||
#define PC_COMPACT_PRIVATE (PC_COMPACT_BASE+1)
|
||||
#define PC_COMPACT_PRIVATE_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFE)
|
||||
#define PC_COMPACT_PRIVATE_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_COMPACT_PRIVATE)
|
||||
|
||||
#define PC_REGULAR (BASE_PC+10)
|
||||
#define PC_REGULAR_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_REGULAR)
|
||||
|
||||
struct unwind_sect_compressed_page {
|
||||
struct unwind_info_compressed_second_level_page_header header;
|
||||
|
@ -20,7 +23,7 @@ struct unwind_sect_compressed_page {
|
|||
|
||||
struct unwind_sect_regular_page {
|
||||
struct unwind_info_regular_second_level_page_header header;
|
||||
uint32_t entries[1];
|
||||
struct unwind_info_regular_second_level_entry entries[1];
|
||||
};
|
||||
|
||||
struct unwind_sect {
|
||||
|
@ -44,15 +47,15 @@ struct unwind_sect data __attribute__((section("__TEXT,__unwind_info"))) = {
|
|||
.indexCount = 3 // all tools treat this as indexCount - 1
|
||||
},
|
||||
|
||||
.entries = {
|
||||
{
|
||||
.functionOffset = BASE_PC,
|
||||
.secondLevelPagesSectionOffset = offsetof(struct unwind_sect, regular_page_1)
|
||||
},
|
||||
.entries = {
|
||||
{
|
||||
.functionOffset = PC_COMPACT_COMMON,
|
||||
.secondLevelPagesSectionOffset = offsetof(struct unwind_sect, compressed_page_1)
|
||||
},
|
||||
{
|
||||
.functionOffset = PC_REGULAR,
|
||||
.secondLevelPagesSectionOffset = offsetof(struct unwind_sect, regular_page_1)
|
||||
},
|
||||
{ } // empty/ignored entry
|
||||
},
|
||||
|
||||
|
@ -67,7 +70,10 @@ struct unwind_sect data __attribute__((section("__TEXT,__unwind_info"))) = {
|
|||
.entryCount = 1
|
||||
},
|
||||
.entries = {
|
||||
0x0
|
||||
{
|
||||
.functionOffset = PC_REGULAR,
|
||||
.encoding = PC_REGULAR_ENCODING
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.ios
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.ios
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.sim
Двоичные данные
Resources/Tests/PLCrashAsyncCompactUnwindEncodingTests/test.sim
Двоичный файл не отображается.
|
@ -222,11 +222,35 @@ plcrash_error_t plcrash_async_cfe_reader_find_pc (plcrash_async_cfe_reader_t *re
|
|||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
PLCF_DEBUG("Regular %p!", header);
|
||||
/* Find the entries array */
|
||||
uint32_t entries_offset = byteorder->swap16(header->entryPageOffset);
|
||||
uint32_t entries_count = byteorder->swap16(header->entryCount);
|
||||
|
||||
// TODO - unimplemented!
|
||||
__builtin_trap();
|
||||
break;
|
||||
if (VERIFY_SIZE_T(sizeof(uint32_t), entries_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, entries_offset, entries_count * sizeof(struct unwind_info_regular_second_level_entry))) {
|
||||
PLCF_DEBUG("CFE entries table lies outside the mapped CFE range");
|
||||
return PLCRASH_EINVAL;
|
||||
}
|
||||
|
||||
/* Binary search for the target entry */
|
||||
struct unwind_info_regular_second_level_entry *entries = (struct unwind_info_regular_second_level_entry *) (((uintptr_t)header) + entries_offset);
|
||||
struct unwind_info_regular_second_level_entry *entry = NULL;
|
||||
|
||||
#define CFE_FUN_BINARY_SEARCH_ENTVAL(_tval) (byteorder->swap32(_tval.functionOffset))
|
||||
CFE_FUN_BINARY_SEARCH(pc, entries, entries_count, entry);
|
||||
#undef CFE_FUN_BINARY_SEARCH_ENTVAL
|
||||
|
||||
if (entry == NULL) {
|
||||
PLCF_DEBUG("Could not find a second level regular CFE entry for pc=%" PRIx64, (uint64_t) pc);
|
||||
return PLCRASH_ENOTFOUND;
|
||||
}
|
||||
|
||||
*encoding = byteorder->swap32(entry->encoding);
|
||||
return PLCRASH_ESUCCESS;
|
||||
}
|
||||
|
||||
case UNWIND_SECOND_LEVEL_COMPRESSED: {
|
||||
|
@ -275,7 +299,7 @@ plcrash_error_t plcrash_async_cfe_reader_find_pc (plcrash_async_cfe_reader_t *re
|
|||
if (c_encoding_idx < common_enc_count) {
|
||||
/* Found in the common table. The offset is verified as being within the mapped memory range by
|
||||
* the < common_enc_count check above. */
|
||||
*encoding = common_enc[c_encoding_idx];
|
||||
*encoding = byteorder->swap32(common_enc[c_encoding_idx]);
|
||||
return PLCRASH_ESUCCESS;
|
||||
}
|
||||
|
||||
|
@ -303,7 +327,7 @@ plcrash_error_t plcrash_async_cfe_reader_find_pc (plcrash_async_cfe_reader_t *re
|
|||
}
|
||||
|
||||
/* Extract the encoding */
|
||||
*encoding = encodings[c_encoding_idx];
|
||||
*encoding = byteorder->swap32(encodings[c_encoding_idx]);
|
||||
return PLCRASH_ESUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,16 +46,20 @@
|
|||
#error Unsupported target
|
||||
#endif
|
||||
|
||||
/** The base PC value hard coded in our test CFE data */
|
||||
/* The base PC value hard coded in our test CFE data */
|
||||
#define BASE_PC 0
|
||||
|
||||
/** PC to use for the compact-common test */
|
||||
/* PC to use for the compact-common test */
|
||||
#define PC_COMPACT_COMMON (BASE_PC+1)
|
||||
#define PC_COMPACT_COMMON_ENCODING (UNWIND_X86_64_MODE_DWARF | 0xFF)
|
||||
#define PC_COMPACT_COMMON_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_COMPACT_COMMON)
|
||||
|
||||
/** PC to use for the compact-private test */
|
||||
/* 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)
|
||||
#define PC_COMPACT_PRIVATE_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_COMPACT_PRIVATE)
|
||||
|
||||
/* PC to use for the regular-common test */
|
||||
#define PC_REGULAR (BASE_PC+10)
|
||||
#define PC_REGULAR_ENCODING (UNWIND_X86_64_MODE_DWARF | PC_REGULAR)
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -232,4 +236,16 @@
|
|||
STAssertEquals(encoding, (uint32_t)PC_COMPACT_PRIVATE_ENCODING, @"Incorrect encoding returned");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading of a PC, regular, with a common encoding.
|
||||
*/
|
||||
- (void) testReadRegularEncoding {
|
||||
plcrash_error_t err;
|
||||
|
||||
uint32_t encoding;
|
||||
err = plcrash_async_cfe_reader_find_pc(&_reader, PC_REGULAR, &encoding);
|
||||
STAssertEquals(PLCRASH_ESUCCESS, err, @"Failed to locate CFE entry");
|
||||
STAssertEquals(encoding, (uint32_t)PC_REGULAR_ENCODING, @"Incorrect encoding returned");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче