Implementation and tests for reading regular entries.

This commit is contained in:
Landon Fuller 2013-03-14 16:09:27 -04:00
Родитель 5a18092f4c
Коммит bcf18ce1a9
6 изменённых файлов: 66 добавлений и 20 удалений

Просмотреть файл

@ -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
},
}
},

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -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