8000 debug: add interactive debug mode by jow- · Pull Request #203 · jow-/ucode · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

debug: add interactive debug mode #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
108 changes: 69 additions & 39 deletions chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@
#include "ucode/types.h"
#include "ucode/util.h"

#define OFFSETINFO_BITS (sizeof(((uc_offsetinfo_t *)NULL)->entries[0]) * 8)
#define OFFSETINFO_BYTE_BITS 3
#define OFFSETINFO_INSN_BITS (OFFSETINFO_BITS - OFFSETINFO_BYTE_BITS)
#define OFFSETINFO_MAX_BYTES ((1 << OFFSETINFO_BYTE_BITS) - 1)
#define OFFSETINFO_MAX_INSNS ((1 << OFFSETINFO_INSN_BITS) - 1)
#define OFFSETINFO_NUM_BYTES(n) ((n) & OFFSETINFO_MAX_BYTES)
#define OFFSETINFO_NUM_INSNS(n) ((n) >> OFFSETINFO_BYTE_BITS)
#define OFFSETINFO_ENCODE(line, insns) ((line & OFFSETINFO_MAX_BYTES) | (((insns) << OFFSETINFO_BYTE_BITS) & ~OFFSETINFO_MAX_BYTES))
#define OFFSETINFO_MAX_BYTES 127
#define OFFSETINFO_MAX_INSNS 127
#define OFFSETINFO_NUM_BYTES(o) ((o)->bytes & OFFSETINFO_MAX_BYTES)
#define OFFSETINFO_NUM_INSNS(o) ((o)->insns & OFFSETINFO_MAX_INSNS)
#define OFFSETINFO_IS_END(o) ((o)->insns & 0x80)


void
Expand Down Expand Up @@ -69,81 +66,114 @@ uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t offset)

uc_vector_push(chunk, byte);

/* offset info is encoded in bytes, for each byte, the first three bits
* specify the number of source text bytes to advance since the last entry
* and the remaining five bits specify the amount of instructions belonging
* to any given source text offset */
/* Offset info is encoded in byte pairs, the first byte specifies the number
* of source text bytes to advance since the last entry and the second byte
* specifies the amount of instructions belonging to the source text offset.
* Byte and instruction count values are limited to 7 bits (0x00..0x7f),
* the most significant bit in each byte is reserved as flag value; if the
* bit is set in the first byte, it signals the begin of a logical statement
* while a set bit in the second byte denotes the end of the statement. */
if (offset > 0 || offsets->count == 0) {
/* if this offset is farther than seven (2 ** 3 - 1) bytes apart from
/* If this offset is farther than 127 (2 ** 7 - 1) bytes apart from
* the last one, we need to emit intermediate "jump" bytes with zero
* instructions each */
for (i = offset; i > OFFSETINFO_MAX_BYTES; i -= OFFSETINFO_MAX_BYTES) {
/* advance by 7 bytes */
uc_vector_push(offsets, OFFSETINFO_ENCODE(OFFSETINFO_MAX_BYTES, 0));
/* advance by 127 bytes */
uc_vector_push(offsets, { OFFSETINFO_MAX_BYTES, 0 });
}

/* advance by `i` bytes, count one instruction */
uc_vector_push(offsets, OFFSETINFO_ENCODE(i, 1));
uc_vector_push(offsets, { i, 1 });
}

/* update instruction count at current offset entry */
else {
/* since we encode the per-offset instruction count in five bits, we
* can only count up to 31 instructions. If we exceed that limit,
* emit another offset entry with the initial three bits set to zero */
if (OFFSETINFO_NUM_INSNS(offsets->entries[offsets->count - 1]) >= OFFSETINFO_MAX_INSNS) {
uc_offset_t *o = uc_vector_last(offsets);

/* since we encode the per-offset instruction count in seven bits, we
* can only count up to 127 instructions. If we exceed that limit,
* emit another offset entry with the byte offset set to zero */
if (OFFSETINFO_NUM_INSNS(o) >= OFFSETINFO_MAX_INSNS) {
/* advance by 0 bytes, count one instruction */
uc_vector_push(offsets, OFFSETINFO_ENCODE(0, 1));
uc_vector_push(offsets, { 0, 1 });
}
else {
uint8_t *prev = uc_vector_last(offsets);

*prev = OFFSETINFO_ENCODE(
OFFSETINFO_NUM_BYTES(*prev),
OFFSETINFO_NUM_INSNS(*prev) + 1);
o->insns++;
}
}

return chunk->count - 1;
}

void
uc_chunk_pop(uc_chunk_t *chunk)
uc_chunk_stmt_start(uc_chunk_t *chunk, size_t offset)
{
uc_offsetinfo_t *offsets = &chunk->debuginfo.offsets;
int n_insns;
size_t i;

assert(chunk->count > 0);
for (i = offset; i > OFFSETINFO_MAX_BYTES; i -= OFFSETINFO_MAX_BYTES) {
/* advance by 127 bytes */
uc_vector_push(offsets, { OFFSETINFO_MAX_BYTES, 0 });
}

chunk->count--;
/* advance by `i` bytes, set start of statement flag */
uc_vector_push(offsets, { i | 0x80, 0 });
}

n_insns = OFFSETINFO_NUM_INSNS(offsets->entries[offsets->count - 1]);
void
uc_chunk_stmt_end(uc_chunk_t *chunk, size_t offset)
{
uc_offsetinfo_t *offsets = &chunk->debuginfo.offsets;
uc_offset_t *o = offsets->count ? uc_vector_last(offsets) : NULL;
size_t i;

if (n_insns > 0) {
uint8_t *prev = uc_vector_last(offsets);
for (i = offset; i > OFFSETINFO_MAX_BYTES; i -= OFFSETINFO_MAX_BYTES) {
/* advance by 127 bytes */
uc_vector_push(offsets, { OFFSETINFO_MAX_BYTES, 0 });
}

*prev = OFFSETINFO_ENCODE(OFFSETINFO_NUM_BYTES(*prev), n_insns - 1);
if (i > 0 || o == NULL || OFFSETINFO_IS_END(o)) {
/* advance by `i` bytes, set start of statement flag */
uc_vector_push(offsets, { i, 0x80 });
}
else {
offsets->count--;
/* set end flag on last offset entry */
o->insns |= 0x80;
}
}

void
uc_chunk_pop(uc_chunk_t *chunk)
{
assert(chunk->count > 0);

chunk->count--;

for (size_t i = chunk->debuginfo.offsets.count; i > 0; i--) {
uc_offset_t *o = &chunk->debuginfo.offsets.entries[i - 1];

if (o->insns & 127) {
o->insns = ((o->insns & 127) - 1) | (o->insns & 128);
break;
}
}
}

size_t
uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off)
{
uc_offsetinfo_t *offsets = &chunk->debuginfo.offsets;
size_t i, inum = 0, lnum = 0;
size_t i, inum = 0, bnum = 0;

if (!offsets->count)
return 0;

for (i = 0; i < offsets->count && inum < off; i++) {
lnum += OFFSETINFO_NUM_BYTES(offsets->entries[i]);
inum += OFFSETINFO_NUM_INSNS(offsets->entries[i]);
bnum += OFFSETINFO_NUM_BYTES(&offsets->entries[i]);
inum += OFFSETINFO_NUM_INSNS(&offsets->entries[i]);
}

return lnum;
return bnum;
}

void
Expand Down
Loading
Loading
0