/*******************************************************************************
 * Copyright (c) 2007 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/

/*
 * This module implements Breakpoints service.
 * The service maintains a list of breakpoints.
 * Each breakpoint consists of one or more conditions that determine
 * when a program's execution should be interrupted.
 */

#include "config.h"
#if SERVICE_Breakpoints

// TODO: breakpoint status reports
// TODO: replant breakpoints when shared lib is loaded or unloaded

#if defined(_WRS_KERNEL)
#  include <vxWorks.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
#include "breakpoints.h"
#include "expressions.h"
#include "channel.h"
#include "protocol.h"
#include "errors.h"
#include "trace.h"
#include "runctrl.h"
#include "context.h"
#include "myalloc.h"
#include "exceptions.h"
#include "symbols.h"
#include "json.h"
#include "link.h"

#ifdef BREAK_INST
#  undef BREAK_INST
#endif

#if defined(_WRS_KERNEL)

#include <private/vxdbgLibP.h>

#elif defined(__i386__)

static unsigned char BREAK_INST[] = { 0xcc };   /* breakpoint instruction */
#define BREAK_SIZE 1    /* breakpoint instruction size */

#else

#error "Unknown CPU"

#endif

typedef struct BreakpointRef BreakpointRef;
typedef struct BreakpointInfo BreakpointInfo;
typedef struct BreakInstruction BreakInstruction;

struct BreakpointRef {
    LINK link_inp;
    LINK link_bp;
    InputStream * inp;
    BreakpointInfo * bp;
};

struct BreakpointInfo {
    LINK link_all;
    LINK link_id;
    LINK refs;
    char id[64];
    int enabled;
    int unsupported;
    int planted;
    int deleted;
    int error;
    char * err_msg;
    char * address;
    char * condition;
};

struct BreakInstruction {
    LINK link_all;
    LINK link_adr;
    Context * ctx;
    int ctx_cnt;
    unsigned long address;
#if defined(_WRS_KERNEL)
    VXDBG_CTX vxdbg_ctx;
    VXDBG_BP_ID vxdbg_id;
#else
    char saved_code[BREAK_SIZE];
#endif    
    int error;
    int skip;
    BreakpointInfo ** refs;
    int ref_size;
    int ref_cnt;
    int planted;
};

static const char * BREAKPOINTS = "Breakpoints";

#define ADDR2INSTR_HASH_SIZE 1023
#define addr2instr_hash(addr) (((addr) + ((addr) >> 8)) % ADDR2INSTR_HASH_SIZE)

#define link_all2bi(A)  ((BreakInstruction *)((char *)(A) - (int)&((BreakInstruction *)0)->link_all))
#define link_adr2bi(A)  ((BreakInstruction *)((char *)(A) - (int)&((BreakInstruction *)0)->link_adr))

#define ID2BP_HASH_SIZE 1023

#define link_all2bp(A)  ((BreakpointInfo *)((char *)(A) - (int)&((BreakpointInfo *)0)->link_all))
#define link_id2bp(A)   ((BreakpointInfo *)((char *)(A) - (int)&((BreakpointInfo *)0)->link_id))

#define INP2BR_HASH_SIZE 127

#define link_inp2br(A)  ((BreakpointRef *)((char *)(A) - (int)&((BreakpointRef *)0)->link_inp))
#define link_bp2br(A)   ((BreakpointRef *)((char *)(A) - (int)&((BreakpointRef *)0)->link_bp))

static LINK breakpoints;
static LINK id2bp[ID2BP_HASH_SIZE];

static LINK instructions;
static LINK addr2instr[ADDR2INSTR_HASH_SIZE];

static LINK inp2br[INP2BR_HASH_SIZE];

static int replanting = 0;

static Context * expression_context = NULL;
static int address_expression_identifier(char * name, Value * v);
static int condition_expression_identifier(char * name, Value * v);
static ExpressionContext bp_address_ctx = { address_expression_identifier, NULL };
static ExpressionContext bp_condition_ctx = { condition_expression_identifier, NULL };

static int id2bp_hash(char * id) {
    unsigned hash = 0;
    while (*id) hash = (hash >> 16) + hash + (unsigned char)*id++;
    return hash % ID2BP_HASH_SIZE;
}

static void plant_instruction(BreakInstruction * bi) {
    assert(!bi->planted);
#if defined(_WRS_KERNEL)
    bi->vxdbg_ctx.ctxId = bi->ctx_cnt == 1 ? bi->ctx->pid : 0;
    bi->vxdbg_ctx.ctxId = 0;
    bi->vxdbg_ctx.ctxType = VXDBG_CTX_TASK;
    if (vxdbgBpAdd(vxdbg_clnt_id,
            &bi->vxdbg_ctx, 0, BP_ACTION_STOP | BP_ACTION_NOTIFY,
            0, 0, (INSTR *)bi->address, 0, 0, &bi->vxdbg_id) != OK) {
        bi->error = errno;
        assert(bi->error != 0);
    }
#else    
    if (context_read_mem(bi->ctx, bi->address, bi->saved_code, BREAK_SIZE) < 0) {
        bi->error = errno;
    }
    else if (context_write_mem(bi->ctx, bi->address, &BREAK_INST, BREAK_SIZE) < 0) {
        bi->error = errno;
    }
#endif
    bi->planted = bi->error == 0;
}

static int verify_instruction(BreakInstruction * bi) {
    assert(bi->planted);
#if defined(_WRS_KERNEL)
    return bi->vxdbg_ctx.ctxId == (bi->ctx_cnt == 1 ? bi->ctx->pid : 0) &&
           bi->vxdbg_ctx.ctxType == VXDBG_CTX_TASK;
#else
    return 1;
#endif
}

static void remove_instruction(BreakInstruction * bi) {
    assert(bi->planted);
    assert(!bi->error);
#ifdef _WRS_KERNEL
    {
        VXDBG_BP_DEL_INFO info;
        memset(&info, 0, sizeof(info));
        info.pClnt = vxdbg_clnt_id;
        info.type = BP_BY_ID_DELETE;
        info.info.id.bpId = bi->vxdbg_id;
        if (vxdbgBpDelete(info) != OK) {
            bi->error = errno;
            assert(bi->error != 0);
        }
    }
#else                
    if (!bi->ctx->exited && bi->ctx->stopped) {
        if (context_write_mem(bi->ctx, bi->address, bi->saved_code, BREAK_SIZE) < 0) {
            bi->error = errno;
        }
    }
#endif
    bi->planted = 0;
}

static BreakInstruction * add_instruction(Context * ctx, unsigned long address) {
    int hash = addr2instr_hash(address);
    BreakInstruction * bi = (BreakInstruction *)loc_alloc_zero(sizeof(BreakInstruction));
    list_add_last(&bi->link_all, &instructions);
    list_add_last(&bi->link_adr, addr2instr + hash);
    context_lock(ctx);
    bi->ctx = ctx;
    bi->address = address;
    return bi;
}

static void clear_instruction_refs(void) {
    LINK * l = instructions.next;
    while (l != &instructions) {
        BreakInstruction * bi = link_all2bi(l);
        bi->ctx_cnt = 1;
        bi->ref_cnt = 0;
        l = l->next;
    }
}

static void delete_unused_instructions(void) {
    LINK * l = instructions.next;
    while (l != &instructions) {
        BreakInstruction * bi = link_all2bi(l);
        l = l->next;
        if (bi->skip) continue;
        if (bi->ref_cnt == 0) {
            list_remove(&bi->link_all);
            list_remove(&bi->link_adr);
            if (bi->planted) {
                if (bi->ctx->exited || !bi->ctx->stopped) {
                    LINK * qp = context_root.next;
                    while (qp != &context_root) {
                        Context * ctx = ctxl2ctxp(qp);
                        qp = qp->next;
                        if (ctx->mem == bi->ctx->mem && !ctx->exited && ctx->stopped) {
                            assert(bi->ctx != ctx);
                            context_unlock(bi->ctx);
                            context_lock(ctx);
                            bi->ctx = ctx;
                            break;
                        }
                    }
                }
                remove_instruction(bi);
            }
            context_unlock(bi->ctx);
            loc_free(bi->refs);
            loc_free(bi);
        }
        else if (!bi->planted) {
            plant_instruction(bi);
        }
        else if (!verify_instruction(bi)) {
            remove_instruction(bi);
            plant_instruction(bi);
        }
    }
}

static BreakInstruction * find_instruction(Context * ctx, unsigned long address) {
    int hash = addr2instr_hash(address);
    LINK * l = addr2instr[hash].next;
    assert(!ctx->exited && ctx->stopped);
    while (l != addr2instr + hash) {
        BreakInstruction * bi = link_adr2bi(l);
        l = l->next;
        if (bi->ctx->mem == ctx->mem && bi->address == address) {
            if (bi->ctx->exited || !bi->ctx->stopped) {
                assert(bi->ctx != ctx);
                context_unlock(bi->ctx);
                context_lock(ctx);
                bi->ctx = ctx;
            }
            return bi;
        }
    }
    return NULL;
}

static int address_expression_identifier(char * name, Value * v) {
    Symbol sym;
    if (v == NULL) return 0;
    memset(v, 0, sizeof(Value));
    if (expression_context == NULL) {
        errno = ERR_INV_CONTEXT;
        return -1;
    }
    if (strcmp(name, "$thread") == 0) {
        string_value(v, thread_id(expression_context));
        return 0;
    }
    if (find_symbol(expression_context, name, &sym) < 0) {
        if (errno != ERR_SYM_NOT_FOUND) return -1;
    }
    else {
        v->type = VALUE_UNS;
        v->value = sym.value;
        return 0;
    }
    errno = ERR_SYM_NOT_FOUND;
    return -1;
}

static void address_expression_error(BreakpointInfo * bp, char * msg) {
    // TODO: per-context address expression error report
    int size;
    if (bp->error) return;
    bp->error = errno;
    if (msg == NULL) msg = get_expression_error_msg();
    assert(bp->err_msg == NULL);
    size = strlen(msg) + strlen(bp->address) + 64;
    bp->err_msg = loc_alloc(size);
    snprintf(bp->err_msg, size, "Invalid breakpoint address '%s': %s", bp->address, msg);
}

static void plant_breakpoint(BreakpointInfo * bp) {
    LINK * qp;
    char * p = NULL;
    Value v;
    int context_sensitive = 0;

    assert(!bp->planted);
    assert(bp->enabled);
    bp->error = 0;
    if (bp->err_msg != NULL) loc_free(bp->err_msg);

    if (bp->address == NULL) {
        bp->error = ERR_INV_EXPRESSION;
        trace(LOG_ALWAYS, "No breakpoint address");
        return;
    }
    expression_context = NULL;
    if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
        if (errno != ERR_INV_CONTEXT) {
            address_expression_error(bp, NULL);
            trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
            return;
        }
        context_sensitive = 1;
    }
    if (!context_sensitive && v.type != VALUE_INT && v.type != VALUE_UNS) {
        errno = ERR_INV_EXPRESSION;
        address_expression_error(bp, "Must be integer number");
        trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
        return;
    }

    for (qp = context_root.next; qp != &context_root; qp = qp->next) {
        BreakInstruction * bi = NULL;
        Context * ctx = ctxl2ctxp(qp);

        if (ctx->exited || ctx->exiting) continue;
        assert(ctx->stopped);
        if (context_sensitive) {
            expression_context = ctx;
            if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
                address_expression_error(bp, NULL);
                trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
                continue;
            }
            if (v.type != VALUE_INT && v.type != VALUE_UNS) {
                errno = ERR_INV_EXPRESSION;
                address_expression_error(bp, "Must be integer number");
                continue;
            }
        }
        if (bp->condition != NULL) {
            /* Optimize away the breakpoint if condition is always false for given context */
            Value c;
            expression_context = ctx;
            if (evaluate_expression(&bp_address_ctx, bp->condition, &c) == 0) {
                switch (c.type) {
                case VALUE_INT:
                case VALUE_UNS:
                    if (c.value == 0) continue;
                    break;
                case VALUE_STR:
                    if (c.str == NULL) continue;
                    break;
                }
            }
        }
        bi = find_instruction(ctx, v.value);
        if (bi == NULL) {
            bi = add_instruction(ctx, v.value);
        }
        else if (bp->planted) {
            int i = 0;
            while (i < bi->ref_cnt && bi->refs[i] != bp) i++;
            if (i < bi->ref_cnt) continue;
        }
        if (bi->ref_cnt >= bi->ref_size) {
            bi->ref_size = bi->ref_size == 0 ? 8 : bi->ref_size * 2;
            bi->refs = (BreakpointInfo **)loc_realloc(bi->refs, sizeof(BreakpointInfo *) * bi->ref_size);
        }
        bi->refs[bi->ref_cnt++] = bp;
        if (bi->ctx != ctx) bi->ctx_cnt++;
        if (bi->error) {
            if (!bp->error) bp->error = bi->error;
        }
        else {
            bp->planted = 1;
        }
    }
    if (bp->planted) bp->error = 0;
}

static void event_replant_breakpoints(void *arg) {
    LINK * l = breakpoints.next;
    replanting = 0;
    clear_instruction_refs();
    while (l != &breakpoints) {
        BreakpointInfo * bp = link_all2bp(l);
        l = l->next;
        if (bp->deleted) {
            list_remove(&bp->link_all);
            list_remove(&bp->link_id);
            loc_free(bp->err_msg);
            loc_free(bp->address);
            loc_free(bp->condition);
            loc_free(bp);
            continue;
        }
        bp->planted = 0;
        if (bp->enabled && !bp->unsupported) {
            plant_breakpoint(bp);
        }
    }
    delete_unused_instructions();
}

static void replant_breakpoints(void) {
    if (list_is_empty(&breakpoints) && list_is_empty(&instructions)) return;
    if (replanting) return;
    replanting = 1;
    post_safe_event(event_replant_breakpoints, NULL);
}

static int str_equ(char * x, char * y) {
    if (x == y) return 1;
    if (x == NULL) return 0;
    if (y == NULL) return 0;
    return strcmp(x, y) == 0;
}

static int copy_breakpoint_info(BreakpointInfo * dst, BreakpointInfo * src) {
    int res = 0;
    if (strcmp(dst->id, src->id) != 0) {
        strcpy(dst->id, src->id);
        res = 1;
    }
    if (dst->enabled != src->enabled) {
        dst->enabled = src->enabled;
        res = 1;
    }
    if (dst->unsupported != src->unsupported) {
        dst->unsupported = src->unsupported;
        res = 1;
    }
    if (!str_equ(dst->address, src->address)) {
        loc_free(dst->address);
        dst->address = src->address;
        res = 1;
    }
    else {
        loc_free(src->address);
    }
    src->address = NULL;
    if (!str_equ(dst->condition, src->condition)) {
        loc_free(dst->condition);
        dst->condition = src->condition;
        res = 1;
    }
    else {
        loc_free(src->condition);
    }
    src->condition = NULL;
    return res;
}

static BreakpointInfo * find_breakpoint(char * id) {
    int hash = id2bp_hash(id);
    LINK * l = id2bp[hash].next;
    while (l != id2bp + hash) {
        BreakpointInfo * bp = link_id2bp(l);
        l = l->next;
        if (strcmp(bp->id, id) == 0) return bp;
    }
    return NULL;
}

static BreakpointRef * find_breakpoint_ref(BreakpointInfo * bp, InputStream * inp) {
    LINK * l;
    if (bp == NULL) return NULL;
    l = bp->refs.next;
    while (l != &bp->refs) {
        BreakpointRef * br = link_bp2br(l);
        assert(br->bp == bp);
        if (br->inp == inp) return br;
        l = l->next;
    }
    return NULL;
}

static void add_breakpoint(InputStream * inp, BreakpointInfo * bp) {
    BreakpointRef * r = NULL;
    BreakpointInfo * i = NULL;
    int chng = 0;
    i = find_breakpoint(bp->id);
    if (i == NULL) {
        int hash = id2bp_hash(bp->id);
        i = (BreakpointInfo *)loc_alloc_zero(sizeof(BreakpointInfo));
        list_init(&i->refs);
        list_add_last(&i->link_all, &breakpoints);
        list_add_last(&i->link_id, id2bp + hash);
    }
    chng = copy_breakpoint_info(i, bp);
    if (i->deleted) {
        i->deleted = 0;
        chng = 1;
    }
    r = find_breakpoint_ref(i, inp);
    if (r == NULL) {
        int inp_hash = (int)inp / 16 % INP2BR_HASH_SIZE;
        r = (BreakpointRef *)loc_alloc_zero(sizeof(BreakpointRef));
        list_add_last(&r->link_inp, inp2br + inp_hash);
        list_add_last(&r->link_bp, &i->refs);
        r->inp = inp;
        r->bp = i;
    }
    else {
        assert(r->bp == i);
        assert(!list_is_empty(&i->refs));
    }
    if (chng) {
        if (i->planted || i->enabled && !i->unsupported) replant_breakpoints();
    }
}

static void remove_breakpoint(BreakpointInfo * bp) {
    assert(list_is_empty(&bp->refs));
    if (bp->planted) {
        bp->deleted = 1;
        replant_breakpoints();
    }
    else {
        list_remove(&bp->link_all);
        list_remove(&bp->link_id);
        loc_free(bp->address);
        loc_free(bp->condition);
        loc_free(bp);
    }
}

static void remove_ref(BreakpointRef * br) {
    BreakpointInfo * bp = br->bp;
    list_remove(&br->link_inp);
    list_remove(&br->link_bp);
    loc_free(br);
    if (list_is_empty(&bp->refs)) remove_breakpoint(bp);
}

static void delete_breakpoint_refs(InputStream * inp) {
    int hash = (int)inp / 16 % INP2BR_HASH_SIZE;
    LINK * l = inp2br[hash].next;
    while (l != &inp2br[hash]) {
        BreakpointRef * br = link_inp2br(l);
        l = l->next;
        if (br->inp == inp) remove_ref(br);
    }
}

static void read_breakpoint_properties(InputStream * inp, BreakpointInfo * bp) {
    memset(bp, 0, sizeof(BreakpointInfo));
    if (inp->read(inp) != '{') exception(ERR_JSON_SYNTAX);
    if (inp->peek(inp) == '}') {
        inp->read(inp);
    }
    else {
        while (1) {
            int ch;
            char name[256];
            json_read_string(inp, name, sizeof(name));
            if (inp->read(inp) != ':') exception(ERR_JSON_SYNTAX);
            if (strcmp(name, "ID") == 0) {
                json_read_string(inp, bp->id, sizeof(bp->id));
            }
            else if (strcmp(name, "Address") == 0) {
                bp->address = json_read_alloc_string(inp);
            }
            else if (strcmp(name, "Condition") == 0) {
                bp->condition = json_read_alloc_string(inp);
            }
            else if (strcmp(name, "Enabled") == 0) {
                bp->enabled = json_read_boolean(inp);
            }
            else {
                bp->unsupported = 1;
                json_skip_object(inp);
            }
            ch = inp->read(inp);
            if (ch == ',') continue;
            if (ch == '}') break;
            exception(ERR_JSON_SYNTAX);
        }
    }
}

static void command_ini_bps(char * token, InputStream * inp, OutputStream * out) {
    delete_breakpoint_refs(inp);
    if (inp->read(inp) != '[') exception(ERR_PROTOCOL);
    if (inp->peek(inp) == ']') {
        inp->read(inp);
    }
    else {
        while (1) {
            int ch;
            BreakpointInfo bp;
            read_breakpoint_properties(inp, &bp);
            add_breakpoint(inp, &bp);
            ch = inp->read(inp);
            if (ch == ',') continue;
            if (ch == ']') break;
            exception(ERR_JSON_SYNTAX);
        }
    }
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

static void command_get_bp_ids(char * token, InputStream * inp, OutputStream * out) {
    // TODO: implement command_get_bp_ids()
    exception(ERR_PROTOCOL);
}

static void command_get_properties(char * token, InputStream * inp, OutputStream * out) {
    // TODO: implement command_get_properties()
    exception(ERR_PROTOCOL);
}

static void command_get_status(char * token, InputStream * inp, OutputStream * out) {
    // TODO: implement command_get_status()
    exception(ERR_PROTOCOL);
}

static void command_bp_add(char * token, InputStream * inp, OutputStream * out) {
    BreakpointInfo bp;
    read_breakpoint_properties(inp, &bp);
    add_breakpoint(inp, &bp);
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

static void command_bp_change(char * token, InputStream * inp, OutputStream * out) {
    BreakpointInfo bp;
    BreakpointInfo * p;
    read_breakpoint_properties(inp, &bp);
    p = find_breakpoint(bp.id);
    if (p != NULL && copy_breakpoint_info(p, &bp)) {
        if (p->planted || p->enabled && !p->unsupported) replant_breakpoints();
    }
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

static void command_bp_enable(char * token, InputStream * inp, OutputStream * out) {
    if (inp->read(inp) != '[') exception(ERR_PROTOCOL);
    if (inp->peek(inp) == ']') {
        inp->read(inp);
    }
    else {
        while (1) {
            int ch;
            char id[256];
            BreakpointInfo * bp;
            json_read_string(inp, id, sizeof(id));
            bp = find_breakpoint(id);
            if (bp != NULL && !bp->enabled) {
                bp->enabled = 1;
                if (!bp->deleted && !bp->unsupported) replant_breakpoints();
            }
            ch = inp->read(inp);
            if (ch == ',') continue;
            if (ch == ']') break;
            exception(ERR_JSON_SYNTAX);
        }
    }
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

static void command_bp_disable(char * token, InputStream * inp, OutputStream * out) {
    if (inp->read(inp) != '[') exception(ERR_PROTOCOL);
    if (inp->peek(inp) == ']') {
        inp->read(inp);
    }
    else {
        while (1) {
            int ch;
            char id[256];
            BreakpointInfo * bp;
            json_read_string(inp, id, sizeof(id));
            bp = find_breakpoint(id);
            if (bp != NULL && bp->enabled) {
                bp->enabled = 0;
                if (bp->planted) replant_breakpoints();
            }
            ch = inp->read(inp);
            if (ch == ',') continue;
            if (ch == ']') break;
            exception(ERR_JSON_SYNTAX);
        }
    }
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

static void command_bp_remove(char * token, InputStream * inp, OutputStream * out) {
    if (inp->read(inp) != '[') exception(ERR_PROTOCOL);
    if (inp->peek(inp) == ']') {
        inp->read(inp);
    }
    else {
        while (1) {
            int ch;
            char id[256];
            BreakpointRef * br;
            json_read_string(inp, id, sizeof(id));
            br = find_breakpoint_ref(find_breakpoint(id), inp);
            if (br != NULL) remove_ref(br);
            ch = inp->read(inp);
            if (ch == ',') continue;
            if (ch == ']') break;
            exception(ERR_JSON_SYNTAX);
        }
    }
    if (inp->read(inp) != 0) exception(ERR_JSON_SYNTAX);
    if (inp->read(inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
    

    write_stringz(out, "R");
    write_stringz(out, token);
    write_errno(out, 0);
    out->write(out, MARKER_EOM);
}

int is_stopped_by_breakpoint(Context * ctx) {
    BreakInstruction * bi;

    assert(!ctx->exited);
    assert(ctx->stopped);
#ifdef _WRS_KERNEL
    return ctx->stopped_by_bp;
#else
    if (ctx->signal != SIGTRAP) return 0;
    if (ctx->event != 0) return 0;
    if (ctx->regs_error) return 0;
    if (ctx->stopped_by_bp) return 1;
    bi = find_instruction(ctx, get_regs_PC(ctx->regs) - BREAK_SIZE);
    if (bi == NULL || bi->skip || bi->error) return 0;
    set_regs_PC(ctx->regs, get_regs_PC(ctx->regs) - BREAK_SIZE);
    ctx->regs_dirty = 1;
    ctx->stopped_by_bp = 1;
    return 1;
#endif    
}

static int condition_expression_identifier(char * name, Value * v) {
    return address_expression_identifier(name, v);
}

int evaluate_breakpoint_condition(Context * ctx) {
    int i;
    BreakInstruction * bi = find_instruction(ctx, get_regs_PC(ctx->regs));
    if (bi == NULL) return 0;
    expression_context = ctx;
    for (i = 0; i < bi->ref_cnt; i++) {
        Value v;
        BreakpointInfo * bp = bi->refs[i];
        assert(bp->planted);
        assert(bp->error == 0);
        if (bp->deleted) continue;
        if (bp->unsupported) continue;
        if (!bp->enabled) continue;
        if (bp->condition == NULL) return 1;
        if (evaluate_expression(&bp_condition_ctx, bp->condition, &v) < 0) {
            trace(LOG_ALWAYS, "%s: %s", get_expression_error_msg(), bp->condition);
            return 1;
        }
        switch (v.type) {
        case VALUE_INT:
        case VALUE_UNS:
            if (v.value) return 1;
            break;
        case VALUE_STR:
            if (v.str != NULL) return 1;
            break;
        }
    }
    return 0;
}

#ifndef _WRS_KERNEL

static void safe_restore_breakpoint(void * arg) {
    SkipBreakpointInfo * sb = (SkipBreakpointInfo *)arg;
    BreakInstruction * bi = find_instruction(sb->ctx, sb->address);

    assert(sb->ctx->regs_error || get_regs_PC(sb->ctx->regs) != sb->address);
    if (bi != NULL && bi->skip) {
        assert(bi->error == 0);
        bi->skip = 0;
        plant_instruction(bi);
    }
    if (sb->done) sb->done(sb);
    if (sb->out) stream_unlock(sb->out);
    context_unlock(sb->ctx);
    loc_free(sb);
}

static void safe_skip_breakpoint(void * arg) {
    SkipBreakpointInfo * sb = (SkipBreakpointInfo *)arg;

    assert(!sb->ctx->exited);
    assert(sb->ctx->stopped);
    assert(!sb->ctx->intercepted);
    assert(!sb->ctx->regs_error);
    assert(sb->address == get_regs_PC(sb->ctx->regs));
    
    if (sb->error == 0) {
        BreakInstruction * bi = find_instruction(sb->ctx, sb->address);
        if (bi != NULL && !bi->skip) {
            if (bi->error) {
                sb->error = bi->error;
            }
            else {
                remove_instruction(bi);
                bi->skip = 1;
            }
        }
    }
    if (sb->error == 0) {
        post_safe_event(safe_restore_breakpoint, sb);
        if (context_single_step(sb->ctx) < 0) {
            sb->error = errno;
        }
        else if (sb->pending_intercept) {
            sb->ctx->pending_intercept = 1;
        }
    }
    else {
        if (sb->done) sb->done(sb);
        if (sb->out) stream_unlock(sb->out);
        context_unlock(sb->ctx);
        loc_free(sb);
    }
}

#endif

/*
 * When a context is stopped by breakpoint, it is necessary to disable
 * the breakpoint temporarily before the context can be resumed.
 * This function function removes break instruction, then does single step
 * over breakpoint location, then restores break intruction.
 * Return: NULL if it is OK to resume context from current state,
 * SkipBreakpointInfo pointer if context needs to step over a breakpoint.
 */
SkipBreakpointInfo * skip_breakpoint(Context * ctx) {
    BreakInstruction * bi;
    SkipBreakpointInfo * sb;

    assert(!ctx->exited);
    assert(ctx->stopped);

#ifdef _WRS_KERNEL
    /* VxWork debug library can skip breakpoint when neccesary, no code is needed here */
    return NULL;
#else
    if (ctx->exited || ctx->exiting) return NULL;
    assert(!ctx->regs_error);
    bi = find_instruction(ctx, get_regs_PC(ctx->regs));
    if (bi == NULL || bi->error) return NULL;
    assert(!bi->skip);
    sb = (SkipBreakpointInfo *)loc_alloc_zero(sizeof(SkipBreakpointInfo));
    context_lock(ctx);
    sb->ctx = ctx;
    sb->address = get_regs_PC(ctx->regs);
    post_safe_event(safe_skip_breakpoint, sb);
    return sb;
#endif
}

static void event_context_created_or_exited(Context * ctx) {
    if (ctx->parent == NULL) replant_breakpoints();
}

static void channel_close_listener(InputStream * inp, OutputStream * out) {
    delete_breakpoint_refs(inp);
}

void ini_breakpoints_service(void) {
    int i;
    static ContextEventListener listener = {
        event_context_created_or_exited,
        event_context_created_or_exited,
        NULL,
        NULL,
        NULL,
        NULL
    };
    add_context_event_listener(&listener);
    list_init(&breakpoints);
    list_init(&instructions);
    for (i = 0; i < ADDR2INSTR_HASH_SIZE; i++) list_init(addr2instr + i);
    for (i = 0; i < ID2BP_HASH_SIZE; i++) list_init(id2bp + i);
    for (i = 0; i < INP2BR_HASH_SIZE; i++) list_init(inp2br + i);
    add_channel_close_listener(channel_close_listener);
    add_command_handler(BREAKPOINTS, "set", command_ini_bps);
    add_command_handler(BREAKPOINTS, "add", command_bp_add);
    add_command_handler(BREAKPOINTS, "change", command_bp_change);
    add_command_handler(BREAKPOINTS, "enable", command_bp_enable);
    add_command_handler(BREAKPOINTS, "disable", command_bp_disable);
    add_command_handler(BREAKPOINTS, "remove", command_bp_remove);
    add_command_handler(BREAKPOINTS, "getBreakpointIDs", command_get_bp_ids);
    add_command_handler(BREAKPOINTS, "getProperties", command_get_properties);
    add_command_handler(BREAKPOINTS, "getStatus", command_get_status);
}

#endif
