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