} bh__arena_internal;
BH_DEF void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size);
+BH_DEF void bh_arena_clear(bh_arena* alloc);
BH_DEF void bh_arena_free(bh_arena* alloc);
BH_DEF bh_allocator bh_arena_allocator(bh_arena* alloc);
BH_DEF BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL;
}
+BH_DEF void bh_arena_clear(bh_arena* alloc) {
+ bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena;
+ walker = walker->next_arena;
+ if (walker != NULL) {
+ bh__arena_internal *trailer = walker;
+ while (walker != NULL) {
+ walker = walker->next_arena;
+ bh_free(alloc->backing, trailer);
+ trailer = walker;
+ }
+ }
+
+ alloc->current_arena = alloc->first_arena;
+ alloc->size = sizeof(ptr);
+}
+
BH_DEF void bh_arena_free(bh_arena* alloc) {
bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena;
bh__arena_internal *trailer = walker;
arrptr = (bh__arr *) bh_alloc(alloc, sizeof(*arrptr) + elemsize * cap);
if (arrptr == NULL) return 0;
+ memset(arrptr + 1, 0, elemsize * cap);
+
arrptr->allocator = alloc;
arrptr->capacity = cap;
arrptr->length = 0;
if (arrptr->capacity < cap) {
void* p;
+ i32 oldcap = arrptr->capacity;
i32 newcap = arrptr->capacity;
while (newcap < cap) newcap = BH_ARR_GROW_FORMULA(newcap);
p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * newcap);
if (p) {
+ memset(bh_pointer_add(((bh__arr *) p + 1), elemsize * oldcap), 0, elemsize * (newcap - oldcap - 1));
+
arrptr = (bh__arr *) p;
arrptr->capacity = newcap;
} else {
unsigned int bytes_read;
};
-static void send_empty_response(debug_state_t *debug, unsigned int message_number) {
+static void send_response_header(debug_state_t *debug, unsigned int message_number) {
+ unsigned int RESPONSE_HEADER = 0xffffffff;
+ send(debug->client_fd, &RESPONSE_HEADER, 4, 0);
send(debug->client_fd, &message_number, 4, 0);
}
-static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
- u32 msg_id = *(unsigned int *) &ctx->data[ctx->offset];
- ctx->offset += sizeof(unsigned int);
+static void send_string(debug_state_t *debug, const char *str) {
+ unsigned int len = strlen(str);
+ send(debug->client_fd, &len, 4, 0);
+ send(debug->client_fd, str, len, 0);
+}
+
+static void send_bytes(debug_state_t *debug, const char *bytes, unsigned int len) {
+ send(debug->client_fd, &len, 4, 0);
+ send(debug->client_fd, bytes, len, 0);
+}
+
+static void send_int(debug_state_t *debug, unsigned int x) {
+ send(debug->client_fd, &x, 4, 0);
+}
- u32 command_id = *(unsigned int *) &ctx->data[ctx->offset];
+static void send_bool(debug_state_t *debug, bool x) {
+ bool v = x ? 1 : 0;
+ send(debug->client_fd, &v, 1, 0);
+}
+
+static int parse_int(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+ int i = *(unsigned int *) &ctx->data[ctx->offset];
ctx->offset += sizeof(unsigned int);
+ return i;
+}
+
+static char *parse_bytes(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+ int len = parse_int(debug, ctx);
+
+ char *buf = bh_alloc_array(debug->tmp_alloc, char, len);
+ memcpy(buf, &ctx->data[ctx->offset], len);
+ ctx->offset += len;
+
+ return buf;
+}
+
+static char *parse_string(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+ int len = parse_int(debug, ctx);
+
+ char *buf = bh_alloc_array(debug->tmp_alloc, char, len + 1);
+ memcpy(buf, &ctx->data[ctx->offset], len);
+ ctx->offset += len;
+
+ buf[len] = 0;
+ return buf;
+}
+
+static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+ u32 msg_id = parse_int(debug, ctx);
+ u32 command_id = parse_int(debug, ctx);
+ printf("[INFO ] Recv command: %d\n", command_id);
switch (command_id) {
case CMD_NOP: {
- send_empty_response(debug, msg_id);
+ // Returns: header
+
+ send_response_header(debug, msg_id);
break;
}
case CMD_RES: {
+ // Returns: nothing
+
// Release the threads
bh_arr_each(debug_thread_state_t *, thread, debug->threads) {
// This logic for "how to resume a thread" should be moved
sem_post(&(*thread)->wait_semaphore);
}
- send_empty_response(debug, msg_id);
+ send_response_header(debug, msg_id);
break;
}
- case CMD_BRK:
+ case CMD_BRK: {
+ //
+ // Returns: header success:bool breakpoint_handle:u32
+
+ char *filename = parse_string(debug, ctx);
+ int line = parse_int(debug, ctx);
+
+ //
+ // TODO: This translation logic will have to be abstracted
+ debug_file_info_t file_info;
+ bool file_found = debug_info_lookup_file_by_name(debug->info, filename, &file_info);
+ if (!file_found) {
+ send_response_header(debug, msg_id);
+ send_bool(debug, false);
+ send_int(debug, -1);
+ return;
+ }
+
+ u32 instr = debug->info->line_to_instruction[file_info.line_buffer_offset + line];
+
+ printf("[INFO ] Setting breakpoint at %s:%d (%xd)\n", filename, line, instr);
+
+ bh_arr_each(debug_thread_state_t *, thread, debug->threads) {
+ bh_arr_push((*thread)->breakpoints, instr);
+ }
+
+ send_response_header(debug, msg_id);
+ send_bool(debug, true);
+ send_int(debug, 0);
break;
+ }
}
}
//
// Check the state of the running program and report any changes.
+
+
+ bh_arena_clear(&debug->tmp_arena);
}
close(debug->client_fd);