HelenOS sources
This source file includes following definitions.
- read_byte
- read_uint16
- read_uint24
- read_uint32
- read_uint64
- read_uint
- read_uleb128
- read_sleb128
- skip_leb128
- read_initial_length
- read_string
- skip_string
- safe_increment
- skip_format
- skip_formatted_entry
- skip_formatted_list
#ifndef DEBUG_UTIL_H_
#define DEBUG_UTIL_H_
#include <assert.h>
#include <stdint.h>
#include <debug/constants.h>
#include <debug/sections.h>
#include <debug.h>
#define DEBUGF dummy_printf
extern bool skip_data(unsigned, const uint8_t **const, const uint8_t *, unsigned);
extern void print_format(const char *, const uint8_t *, const uint8_t *);
extern void print_formatted_list(debug_sections_t *, const char *,
const uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, unsigned);
extern void print_block(const uint8_t **, const uint8_t *, unsigned);
extern void print_formed_data(debug_sections_t *scs, unsigned, const uint8_t **const, const uint8_t *, unsigned);
static inline uint8_t read_byte(const uint8_t **data, const uint8_t *data_end)
{
if (*data >= data_end) {
return 0;
} else {
return *((*data)++);
}
}
struct u16 {
uint16_t val;
} __attribute__((packed));
struct u32 {
uint32_t val;
} __attribute__((packed));
struct u64 {
uint64_t val;
} __attribute__((packed));
static inline uint16_t read_uint16(const uint8_t **data, const uint8_t *data_end)
{
if (*data + 2 > data_end) {
*data = data_end;
return 0;
}
uint16_t v = ((struct u16 *) *data)->val;
*data += 2;
return v;
}
static inline uint32_t read_uint24(const uint8_t **data, const uint8_t *data_end)
{
if (*data + 3 > data_end) {
*data = data_end;
return 0;
}
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t v = (*data)[0] | (*data)[1] << 8 | (*data)[2] << 16;
#else
uint32_t v = (*data)[2] | (*data)[1] << 8 | (*data)[0] << 16;
#endif
*data += 3;
return v;
}
static inline uint32_t read_uint32(const uint8_t **data, const uint8_t *data_end)
{
if (*data + 4 > data_end) {
*data = data_end;
return 0;
}
uint32_t v = ((struct u32 *) *data)->val;
*data += 4;
return v;
}
static inline uint64_t read_uint64(const uint8_t **data, const uint8_t *data_end)
{
if (*data + 8 > data_end) {
*data = data_end;
return 0;
}
uint64_t v = ((struct u64 *) *data)->val;
*data += 8;
return v;
}
static inline uint64_t read_uint(const uint8_t **data, const uint8_t *data_end, unsigned bytes)
{
switch (bytes) {
case 1:
return read_byte(data, data_end);
case 2:
return read_uint16(data, data_end);
case 4:
return read_uint32(data, data_end);
case 8:
return read_uint64(data, data_end);
default:
panic("unimplemented");
}
}
static inline uint64_t read_uleb128(const uint8_t **data, const uint8_t *data_end)
{
uint64_t result = 0;
unsigned shift = 0;
while (*data < data_end) {
uint8_t byte = *((*data)++);
result |= (byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
}
return result;
}
static inline int64_t read_sleb128(const uint8_t **data, const uint8_t *data_end)
{
uint64_t result = 0;
unsigned shift = 0;
while (*data < data_end) {
uint8_t byte = *((*data)++);
result |= (byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0) {
if (shift < 64 && (byte & 0x40) != 0) {
result |= -(1 << shift);
}
break;
}
}
return (int64_t) result;
}
static inline void skip_leb128(const uint8_t **data, const uint8_t *data_end)
{
while (*data < data_end) {
uint8_t byte = *((*data)++);
if ((byte & 0x80) == 0)
break;
}
}
static inline uint64_t read_initial_length(const uint8_t **data, const uint8_t *data_end, unsigned *width)
{
uint32_t initial = read_uint32(data, data_end);
if (initial == 0xffffffffu) {
*width = 8;
return read_uint64(data, data_end);
} else {
*width = 4;
return initial;
}
}
static inline const char *read_string(const uint8_t **data, const uint8_t *data_end)
{
const char *start = (const char *) *data;
while (*data < data_end && **data != 0)
(*data)++;
if (*data < data_end) {
(*data)++;
return start;
} else {
return NULL;
}
}
static inline void skip_string(const uint8_t **data, const uint8_t *data_end)
{
(void) read_string(data, data_end);
}
static inline void safe_increment(const uint8_t **data,
const uint8_t *data_end, ptrdiff_t increment)
{
assert(data_end >= *data);
if (increment >= data_end - *data) {
*data = data_end;
} else {
(*data) += increment;
}
}
static inline void skip_format(const uint8_t **data, const uint8_t *const data_end,
unsigned count)
{
for (unsigned i = 0; i < count; i++) {
(void) read_uleb128(data, data_end);
(void) read_uleb128(data, data_end);
}
}
static inline void skip_formatted_entry(const uint8_t **data, const uint8_t *const data_end,
const uint8_t *format, const uint8_t *format_end, unsigned width)
{
while (format < format_end) {
(void) read_uleb128(&format, format_end);
uint64_t form = read_uleb128(&format, format_end);
skip_data(form, data, data_end, width);
}
}
static inline void skip_formatted_list(const uint8_t **data, const uint8_t *const data_end,
unsigned count, const uint8_t *format, const uint8_t *format_end,
unsigned width)
{
for (unsigned i = 0; i < count; i++) {
skip_formatted_entry(data, data_end, format, format_end, width);
}
}
#endif
HelenOS homepage, sources at GitHub