Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/machine/x86_64/tcf/cpudefs-mdep.c18
-rw-r--r--agent/machine/x86_64/tcf/dwarfreloc-mdep.h8
-rw-r--r--agent/tcf/framework/myalloc.c2
-rw-r--r--agent/tcf/main/gdb-rsp.c75
-rw-r--r--agent/tcf/services/memoryservice.c82
-rw-r--r--agent/tcf/services/registers.c131
-rw-r--r--agent/tcf/services/symbols_elf.c27
-rw-r--r--server/tcf/services/context-proxy.c6
8 files changed, 240 insertions, 109 deletions
diff --git a/agent/machine/x86_64/tcf/cpudefs-mdep.c b/agent/machine/x86_64/tcf/cpudefs-mdep.c
index fbb7ebd1..55838280 100644
--- a/agent/machine/x86_64/tcf/cpudefs-mdep.c
+++ b/agent/machine/x86_64/tcf/cpudefs-mdep.c
@@ -858,9 +858,9 @@ static int is_func_exit(unsigned char * code) {
int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
- static RegisterDefinition * pc_def = NULL;
- static RegisterDefinition * sp_def = NULL;
- static RegisterDefinition * bp_def = NULL;
+ RegisterDefinition * pc_def = NULL;
+ RegisterDefinition * sp_def = NULL;
+ RegisterDefinition * bp_def = NULL;
ContextAddress reg_pc = 0;
ContextAddress reg_bp = 0;
@@ -873,13 +873,17 @@ int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
size_t word_size = context_word_size(ctx);
int x64 = word_size == 8;
- if (pc_def == NULL) {
- RegisterDefinition * r;
- for (r = get_reg_definitions(ctx); r->name != NULL; r++) {
+ {
+ RegisterDefinition * r = get_reg_definitions(ctx);
+ if (r == NULL) return 0;
+ for (; r->name != NULL; r++) {
if (r->offset == offsetof(REG_SET, REG_IP)) pc_def = r;
if (r->offset == offsetof(REG_SET, REG_SP)) sp_def = r;
if (r->offset == offsetof(REG_SET, REG_BP)) bp_def = r;
}
+ if (pc_def == NULL) return 0;
+ if (sp_def == NULL) return 0;
+ if (bp_def == NULL) return 0;
}
if (read_reg(frame, pc_def, word_size, &reg_pc) < 0) return 0;
@@ -974,7 +978,7 @@ int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
if (reg == pc_def || reg == sp_def || reg == bp_def) continue;
if (reg->dwarf_id < 32 && (reg_mask & ((uint32_t)1 << reg->dwarf_id))) continue;
if (context_read_reg(ctx, reg, 0, reg->size, buf) < 0) continue;
- write_reg_bytes(down, reg, 0, reg->size, buf);
+ if (write_reg_bytes(down, reg, 0, reg->size, buf) < 0) return -1;
}
}
}
diff --git a/agent/machine/x86_64/tcf/dwarfreloc-mdep.h b/agent/machine/x86_64/tcf/dwarfreloc-mdep.h
index 1dd7036d..0b7e274f 100644
--- a/agent/machine/x86_64/tcf/dwarfreloc-mdep.h
+++ b/agent/machine/x86_64/tcf/dwarfreloc-mdep.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010-2018 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010-2020 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
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -22,6 +22,7 @@
#define R_X86_64_PC32 2
#define R_X86_64_32 10
#define R_X86_64_32S 11
+#define R_X86_64_PC64 24
static void elf_relocate(void) {
if (relocs->type == SHT_REL && reloc_type != R_X86_64_NONE) {
@@ -29,6 +30,7 @@ static void elf_relocate(void) {
assert(reloc_addend == 0);
switch (reloc_type) {
case R_X86_64_64:
+ case R_X86_64_PC64:
{
U8_T x = *(U8_T *)((char *)section->data + reloc_offset);
if (section->file->byte_swap) SWAP(x);
@@ -61,6 +63,10 @@ static void elf_relocate(void) {
if (data_size < 4) str_exception(ERR_INV_FORMAT, "Invalid relocation record");
*(U4_T *)data_buf = (U4_T)(sym_value + reloc_addend - (section->addr + reloc_offset));
break;
+ case R_X86_64_PC64:
+ if (data_size < 8) str_exception(ERR_INV_FORMAT, "Invalid relocation record");
+ *(U8_T *)data_buf = (U8_T)(sym_value + reloc_addend - (section->addr + reloc_offset));
+ break;
default:
str_exception(ERR_INV_FORMAT, "Unsupported relocation type");
}
diff --git a/agent/tcf/framework/myalloc.c b/agent/tcf/framework/myalloc.c
index 6869ae0c..61f5ac84 100644
--- a/agent/tcf/framework/myalloc.c
+++ b/agent/tcf/framework/myalloc.c
@@ -26,7 +26,7 @@
#include <tcf/framework/events.h>
#include <tcf/framework/myalloc.h>
-#define ALIGNMENT (sizeof(size_t *))
+#define ALIGNMENT (sizeof(void *) < 8 ? 8 : sizeof(void *))
#if !defined(ENABLE_FastMemAlloc)
# define ENABLE_FastMemAlloc 1
diff --git a/agent/tcf/main/gdb-rsp.c b/agent/tcf/main/gdb-rsp.c
index ab39564b..5335deb2 100644
--- a/agent/tcf/main/gdb-rsp.c
+++ b/agent/tcf/main/gdb-rsp.c
@@ -614,6 +614,10 @@ static void add_res_hex8(GdbClient * c, unsigned n) {
add_res_str(c, s);
}
+static void add_res_hex8_str(GdbClient * c, const char * s) {
+ while (*s) add_res_hex8(c, *s++);
+}
+
static void add_res_ptid(GdbClient * c, unsigned pid, unsigned tid) {
if (c->multiprocess) {
add_res_ch(c, 'p');
@@ -919,17 +923,69 @@ static void monitor_ps(GdbClient * c, const char * args) {
else {
m = tmp_printf("%u: %s\n", (unsigned)p->pid, p->ctx->name ? p->ctx->name : p->ctx->id);
}
- while (*m) add_res_hex8(c, *m++);
+ add_res_hex8_str(c, m);
cnt++;
}
- if (cnt == 0) {
- const char * m = "No processes\n";
- while (*m) add_res_hex8(c, *m++);
+ if (cnt == 0) add_res_hex8_str(c, "No debug targets found\n");
+}
+
+static void monitor_info(GdbClient * c, const char * args) {
+ unsigned pid = 0;
+ char * s = (char *)args;
+ while (*s == ' ') s++;
+ pid = (unsigned)strtol(s, &s, 10);
+ while (*s == ' ') s++;
+ if (*s == 0 && pid != 0) {
+ GdbProcess * prs = find_process_pid(c, pid);
+ if (prs != NULL) {
+ Context * ctx = prs->ctx;
+ add_res_hex8_str(c, tmp_printf("Target %u properties:\n", pid));
+ for (;;) {
+ add_res_hex8_str(c, tmp_printf(" ID : \"%s\"\n", ctx->id));
+ if (ctx->parent != NULL) add_res_hex8_str(c, tmp_printf(" ParentID : \"%s\"\n", ctx->parent->id));
+ if (ctx->name != NULL) add_res_hex8_str(c, tmp_printf(" Name : \"%s\"\n", ctx->name));
+ add_res_hex8_str(c, tmp_printf(" WordSize : %u\n", context_word_size(ctx)));
+ add_res_hex8_str(c, tmp_printf(" BigEndian : %d\n", ctx->big_endian));
+#if ENABLE_ContextExtraProperties
+ {
+ /* Back-end context properties */
+ int cnt = 0;
+ const char ** names = NULL;
+ const char ** values = NULL;
+ if (context_get_extra_properties(ctx, &names, &values, &cnt) == 0) {
+ while (cnt > 0) {
+ if (*values != NULL) add_res_hex8_str(c, tmp_printf(" %-10s: %s\n", *names, *values));
+ names++;
+ values++;
+ cnt--;
+ }
+ }
+ }
+#endif
+ if (ctx->parent == NULL) break;
+ add_res_hex8_str(c, "Parent properties:\n");
+ ctx = ctx->parent;
+ }
+ return;
+ }
}
+ add_res_hex8_str(c, "Invalid target ID.\n");
+ add_res_hex8_str(c, "Available targets:\n");
+ monitor_ps(c, "");
+}
+
+static void monitor_help(GdbClient * c, const char * args) {
+ add_res_hex8_str(c, "Usage: monitor <command> [<arguments>]\n");
+ add_res_hex8_str(c, "Commands:\n");
+ add_res_hex8_str(c, " ps - list of debug targets\n");
+ add_res_hex8_str(c, " info <target ID> - properties of a target\n");
+ add_res_hex8_str(c, " help - print this text\n");
}
static MonitorCommand mon_cmds[] = {
{ "ps", monitor_ps },
+ { "info", monitor_info },
+ { "help", monitor_help },
{ NULL }
};
@@ -1206,7 +1262,7 @@ static int handle_q_command(GdbClient * c) {
}
}
if (m == NULL) m = "Invalid ID";
- while (*m) add_res_hex8(c, *m++);
+ add_res_hex8_str(c, m);
return 0;
}
if (strcmp(w, "Rcmd") == 0) {
@@ -1217,7 +1273,6 @@ static int handle_q_command(GdbClient * c) {
MonitorCommand * mon_cmd = NULL;
unsigned mon_cnt = 0;
unsigned cmd_pos = 0;
- const char * res = NULL;
while (i < max - 1) {
char ch = get_cmd_uint8(c, &s);
if (ch == 0) break;
@@ -1239,18 +1294,16 @@ static int handle_q_command(GdbClient * c) {
}
}
if (mon_cnt > 1) {
- res = "Ambiguous command\n";
+ add_res_hex8_str(c, "Ambiguous command.\n");
}
else if (mon_cmd == NULL) {
- res = "Invalid command\n";
+ add_res_hex8_str(c, "Invalid command.\n");
+ monitor_help(c, "");
}
else {
while (cmd[cmd_pos] == ' ') cmd_pos++;
mon_cmd->func(c, cmd + cmd_pos);
}
- if (res) {
- while (*res) add_res_hex8(c, *res++);
- }
return 0;
}
add_res_str(c, "E02");
diff --git a/agent/tcf/services/memoryservice.c b/agent/tcf/services/memoryservice.c
index d172aa7c..c5431783 100644
--- a/agent/tcf/services/memoryservice.c
+++ b/agent/tcf/services/memoryservice.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007-2019 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007-2020 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
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -253,22 +253,19 @@ static void write_ranges(OutputStream * out, ContextAddress addr, int offs, int
write_stream(out, 0);
}
-static void command_get_context(char * token, Channel * c) {
+static void get_context_cache_client(void * parm) {
+ MemoryCommandArgs * args = (MemoryCommandArgs *)parm;
+ Channel * c = cache_channel();
+ Context * ctx = id2ctx(args->ctx_id);
int err = 0;
- char id[256];
- Context * ctx = NULL;
- json_read_string(&c->inp, id, sizeof(id));
- json_test_char(&c->inp, MARKER_EOA);
- json_test_char(&c->inp, MARKER_EOM);
-
- ctx = id2ctx(id);
+ cache_exit();
if (ctx == NULL) err = ERR_INV_CONTEXT;
else if (ctx->exited) err = ERR_ALREADY_EXITED;
else if (ctx->mem_access == 0) err = ERR_INV_CONTEXT;
write_stringz(&c->out, "R");
- write_stringz(&c->out, token);
+ write_stringz(&c->out, args->token);
write_errno(&c->out, err);
if (err == 0) {
write_context(&c->out, ctx);
@@ -280,20 +277,34 @@ static void command_get_context(char * token, Channel * c) {
write_stream(&c->out, MARKER_EOM);
}
-static void command_get_children(char * token, Channel * c) {
- char id[256];
+static void command_get_context(char * token, Channel * c) {
+ MemoryCommandArgs args;
- json_read_string(&c->inp, id, sizeof(id));
+ memset(&args, 0, sizeof(args));
+ json_read_string(&c->inp, args.ctx_id, sizeof(args.ctx_id));
json_test_char(&c->inp, MARKER_EOA);
json_test_char(&c->inp, MARKER_EOM);
+ strlcpy(args.token, token, sizeof(args.token));
+ cache_enter(get_context_cache_client, c, &args, sizeof(MemoryCommandArgs));
+}
+
+static void get_children_cache_client(void * parm) {
+ MemoryCommandArgs * args = (MemoryCommandArgs *)parm;
+ Channel * c = cache_channel();
+ Context * parent = NULL;
+
+ if (args->ctx_id[0] != 0) parent = id2ctx(args->ctx_id);
+
+ cache_exit();
+
write_stringz(&c->out, "R");
- write_stringz(&c->out, token);
+ write_stringz(&c->out, args->token);
write_errno(&c->out, 0);
write_stream(&c->out, '[');
- if (id[0] == 0) {
+ if (args->ctx_id[0] == 0) {
LINK * qp;
int cnt = 0;
for (qp = context_root.next; qp != &context_root; qp = qp->next) {
@@ -306,20 +317,17 @@ static void command_get_children(char * token, Channel * c) {
cnt++;
}
}
- else {
- Context * parent = id2ctx(id);
- if (parent != NULL) {
- LINK * l;
- int cnt = 0;
- for (l = parent->children.next; l != &parent->children; l = l->next) {
- Context * ctx = cldl2ctxp(l);
- assert(ctx->parent == parent);
- if (ctx->exited) continue;
- if (ctx->mem_access == 0 && list_is_empty(&ctx->children)) continue;
- if (cnt > 0) write_stream(&c->out, ',');
- json_write_string(&c->out, ctx->id);
- cnt++;
- }
+ else if (parent != NULL) {
+ LINK * l;
+ int cnt = 0;
+ for (l = parent->children.next; l != &parent->children; l = l->next) {
+ Context * ctx = cldl2ctxp(l);
+ assert(ctx->parent == parent);
+ if (ctx->exited) continue;
+ if (ctx->mem_access == 0 && list_is_empty(&ctx->children)) continue;
+ if (cnt > 0) write_stream(&c->out, ',');
+ json_write_string(&c->out, ctx->id);
+ cnt++;
}
}
write_stream(&c->out, ']');
@@ -328,6 +336,18 @@ static void command_get_children(char * token, Channel * c) {
write_stream(&c->out, MARKER_EOM);
}
+static void command_get_children(char * token, Channel * c) {
+ MemoryCommandArgs args;
+
+ memset(&args, 0, sizeof(args));
+ json_read_string(&c->inp, args.ctx_id, sizeof(args.ctx_id));
+ json_test_char(&c->inp, MARKER_EOA);
+ json_test_char(&c->inp, MARKER_EOM);
+
+ strlcpy(args.token, token, sizeof(args.token));
+ cache_enter(get_children_cache_client, c, &args, sizeof(MemoryCommandArgs));
+}
+
static void read_memory_fill_array_cb(InputStream * inp, void * args) {
MemoryCommandArgs * buf = (MemoryCommandArgs *)args;
if (buf->pos >= buf->max) {
@@ -382,6 +402,7 @@ static MemoryCommandArgs * read_command_args(char * token, Channel * c, int cmd)
void send_event_memory_changed(Context * ctx, ContextAddress addr, unsigned long size) {
OutputStream * out = &broadcast_group->out;
+ assert(cache_miss_count() == 0);
write_stringz(out, "E");
write_stringz(out, MEMORY);
write_stringz(out, "memoryChanged");
@@ -700,6 +721,7 @@ static void command_fill(char * token, Channel * c) {
static void send_event_context_added(Context * ctx) {
OutputStream * out = &broadcast_group->out;
+ assert(cache_miss_count() == 0);
write_stringz(out, "E");
write_stringz(out, MEMORY);
write_stringz(out, "contextAdded");
@@ -716,6 +738,7 @@ static void send_event_context_added(Context * ctx) {
static void send_event_context_changed(Context * ctx) {
OutputStream * out = &broadcast_group->out;
+ assert(cache_miss_count() == 0);
write_stringz(out, "E");
write_stringz(out, MEMORY);
write_stringz(out, "contextChanged");
@@ -732,6 +755,7 @@ static void send_event_context_changed(Context * ctx) {
static void send_event_context_removed(Context * ctx) {
OutputStream * out = &broadcast_group->out;
+ assert(cache_miss_count() == 0);
write_stringz(out, "E");
write_stringz(out, MEMORY);
write_stringz(out, "contextRemoved");
diff --git a/agent/tcf/services/registers.c b/agent/tcf/services/registers.c
index c8f27779..53f6ba81 100644
--- a/agent/tcf/services/registers.c
+++ b/agent/tcf/services/registers.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007-2019 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007-2020 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
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -46,6 +46,18 @@ static Listener * listeners = NULL;
static unsigned listener_cnt = 0;
static unsigned listener_max = 0;
+typedef struct Notification {
+ LINK link_all;
+ Context * ctx;
+ int frame;
+ RegisterDefinition * def;
+ char * id;
+} Notification;
+
+static int notify_definitions_changed = 0;
+static LINK notifications = TCF_LIST_INIT(notifications);
+#define all2notification(link) ((Notification *)((char *)(link) - offsetof(Notification, link_all)))
+
static uint8_t * bbf = NULL;
static unsigned bbf_pos = 0;
static unsigned bbf_len = 0;
@@ -353,50 +365,86 @@ static void command_get_children(char * token, Channel * c) {
cache_enter(command_get_children_cache_client, c, &args, sizeof(args));
}
+static void flush_notifications(void) {
+ OutputStream * out = &broadcast_group->out;
+
+ assert(cache_miss_count() == 0);
+
+ if (notify_definitions_changed) {
+ unsigned i;
+ for (i = 0; i < listener_cnt; i++) {
+ Listener * l = listeners + i;
+ if (l->func->register_definitions_changed == NULL) continue;
+ l->func->register_definitions_changed(l->args);
+ }
+
+ write_stringz(out, "E");
+ write_stringz(out, REGISTERS);
+ write_stringz(out, "contextChanged");
+ write_stream(out, 0);
+ write_stream(out, MARKER_EOM);
+ }
+
+ while (!list_is_empty(&notifications)) {
+ Notification * n = all2notification(notifications.next);
+ list_remove(&n->link_all);
+
+ if (!notify_definitions_changed && !n->ctx->exited) {
+ unsigned i;
+ for (i = 0; i < listener_cnt; i++) {
+ Listener * l = listeners + i;
+ if (l->func->register_changed == NULL) continue;
+ l->func->register_changed(n->ctx, n->frame, n->def, l->args);
+ }
+
+ write_stringz(out, "E");
+ write_stringz(out, REGISTERS);
+ write_stringz(out, "registerChanged");
+ json_write_string(out, n->id);
+ write_stream(out, 0);
+ write_stream(out, MARKER_EOM);
+ }
+ context_unlock(n->ctx);
+ loc_free(n->id);
+ loc_free(n);
+ }
+
+ notify_definitions_changed = 0;
+}
+
void send_event_register_changed(const char * id) {
- unsigned i;
Context * ctx = NULL;
int frame = STACK_NO_FRAME;
RegisterDefinition * def = NULL;
- OutputStream * out = &broadcast_group->out;
+ Notification * n = NULL;
+ LINK * l = NULL;
id2register(id, &ctx, &frame, &def);
if (ctx == NULL) return;
-
- for (i = 0; i < listener_cnt; i++) {
- Listener * l = listeners + i;
- if (l->func->register_changed == NULL) continue;
- l->func->register_changed(ctx, frame, def, l->args);
+ assert(!ctx->exited);
+ for (l = notifications.next; l != &notifications; l = l->next) {
+ n = all2notification(l);
+ if (n->ctx == ctx && n->frame == frame && n->def == def) return;
}
-
if (frame >= 0 && frame == get_top_frame(ctx)) {
id = register2id(ctx, STACK_TOP_FRAME, def);
}
+ n = (Notification *)loc_alloc_zero(sizeof(Notification));
+ n->ctx = ctx;
+ n->frame = frame;
+ n->def = def;
+ n->id = loc_strdup(id);
+ context_lock(n->ctx);
+ list_add_last(&n->link_all, &notifications);
- write_stringz(out, "E");
- write_stringz(out, REGISTERS);
- write_stringz(out, "registerChanged");
-
- json_write_string(out, id);
- write_stream(out, 0);
-
- write_stream(out, MARKER_EOM);
+ /* Delay notifications until cache transaction is committed */
+ if (cache_transaction_id() == 0) flush_notifications();
}
void send_event_register_definitions_changed(void) {
- unsigned i;
- OutputStream * out = &broadcast_group->out;
-
- for (i = 0; i < listener_cnt; i++) {
- Listener * l = listeners + i;
- if (l->func->register_definitions_changed == NULL) continue;
- l->func->register_definitions_changed(l->args);
- }
-
- write_stringz(out, "E");
- write_stringz(out, REGISTERS);
- write_stringz(out, "contextChanged");
- write_stream(out, MARKER_EOM);
+ notify_definitions_changed = 1;
+ /* Delay notifications until cache transaction is committed */
+ if (cache_transaction_id() == 0) flush_notifications();
}
typedef struct GetArgs {
@@ -479,7 +527,6 @@ typedef struct SetArgs {
static void command_set_cache_client(void * x) {
SetArgs * args = (SetArgs *)x;
Channel * c = cache_channel();
- int notify = 0;
Trap trap;
if (set_trap(&trap)) {
@@ -500,15 +547,13 @@ static void command_set_cache_client(void * x) {
if ((size_t)args->data_len > reg_def->size) exception(ERR_INV_DATA_SIZE);
if (args->data_len > 0) {
if (context_write_reg(ctx, reg_def, 0, args->data_len, args->data) < 0) exception(errno);
- notify = 1;
+ send_event_register_changed(args->id);
}
clear_trap(&trap);
}
cache_exit();
- if (notify) send_event_register_changed(args->id);
-
if (!is_channel_closed(c)) {
write_stringz(&c->out, "R");
write_stringz(&c->out, args->token);
@@ -542,7 +587,6 @@ typedef struct Location {
RegisterDefinition * reg_def;
unsigned offs;
unsigned size;
- int notify;
} Location;
static Location * buf = NULL;
@@ -687,7 +731,6 @@ typedef struct SetmArgs {
static void command_setm_cache_client(void * x) {
SetmArgs * args = (SetmArgs *)x;
Channel * c = cache_channel();
- int notify = 0;
Trap trap;
if (set_trap(&trap)) {
@@ -699,9 +742,8 @@ static void command_setm_cache_client(void * x) {
assert(l->frame_info == NULL);
if (l->size > 0) {
if (context_write_reg(l->ctx, l->reg_def, l->offs, l->size, args->data + data_pos) < 0) exception(errno);
+ send_event_register_changed(l->id);
data_pos += l->size;
- l->notify = 1;
- notify = 1;
}
}
clear_trap(&trap);
@@ -709,14 +751,6 @@ static void command_setm_cache_client(void * x) {
cache_exit();
- if (notify) {
- unsigned locs_pos = 0;
- while (locs_pos < args->locs_cnt) {
- Location * l = args->locs + locs_pos++;
- if (l->notify) send_event_register_changed(l->id);
- }
- }
-
if (!is_channel_closed(c)) {
write_stringz(&c->out, "R");
write_stringz(&c->out, args->token);
@@ -773,6 +807,10 @@ void add_registers_event_listener(RegistersEventListener * listener, void * args
listener_cnt++;
}
+static void cache_transaction_listener(int evt) {
+ if (evt == CTLE_COMMIT) flush_notifications();
+}
+
void ini_registers_service(Protocol * proto, TCFBroadcastGroup * bcg) {
broadcast_group = bcg;
add_command_handler(proto, REGISTERS, "getContext", command_get_context);
@@ -782,6 +820,7 @@ void ini_registers_service(Protocol * proto, TCFBroadcastGroup * bcg) {
add_command_handler(proto, REGISTERS, "getm", command_getm);
add_command_handler(proto, REGISTERS, "setm", command_setm);
add_command_handler(proto, REGISTERS, "search", command_search);
+ add_cache_transaction_listener(cache_transaction_listener);
}
#endif /* SERVICE_Registers */
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index 07049f79..febfb23d 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -3326,19 +3326,24 @@ int get_symbol_name(const Symbol * sym, char ** name) {
else if (sym->tbl != NULL) {
ELF_SymbolInfo sym_info;
if (sym->dimension == 0) {
- size_t i;
unpack_elf_symbol_info(sym->tbl, sym->index, &sym_info);
- for (i = 0;; i++) {
- if (sym_info.name[i] == 0) {
- *name = sym_info.name;
- break;
- }
- if (sym_info.name[i] == '@' && sym_info.name[i + 1] == '@') {
- *name = (char *)tmp_alloc_zero(i + 1);
- memcpy(*name, sym_info.name, i);
- break;
+ if (sym_info.name != NULL) {
+ size_t i;
+ for (i = 0;; i++) {
+ if (sym_info.name[i] == 0) {
+ *name = sym_info.name;
+ break;
+ }
+ if (sym_info.name[i] == '@' && sym_info.name[i + 1] == '@') {
+ *name = (char *)tmp_alloc_zero(i + 1);
+ memcpy(*name, sym_info.name, i);
+ break;
+ }
}
}
+ else {
+ *name = NULL;
+ }
}
else {
ContextAddress sym_offs = 0;
@@ -3451,7 +3456,7 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) {
if (sym->dimension == 0) {
ELF_SymbolInfo info;
unpack_elf_symbol_info(sym->tbl, sym->index, &info);
- if (IS_PPC64_FUNC_OPD(sym->tbl->file, &info)) {
+ if (IS_PPC64_FUNC_OPD(sym->tbl->file, &info) && info.name != NULL) {
/*
* For PPC64, the size of an ELF symbol is either the size
* described by the .<name> symbol or, if this symbol does not
diff --git a/server/tcf/services/context-proxy.c b/server/tcf/services/context-proxy.c
index 944f848f..483fd221 100644
--- a/server/tcf/services/context-proxy.c
+++ b/server/tcf/services/context-proxy.c
@@ -1706,7 +1706,7 @@ static ContextCache * get_memory_map_cache(Context * ctx) {
assert(cache->ctx == ctx);
if (!set_trap(&trap)) return NULL;
if (is_channel_closed(c)) exception(ERR_CHANNEL_CLOSED);
- if (cache->peer != NULL && !cache->peer->rc_done) cache_wait(&cache->peer->rc_cache);
+ if (!cache->peer->rc_done) cache_wait(&cache->peer->rc_cache);
if (cache->pending_get_mmap != NULL) cache_wait(&cache->mmap_cache);
if (cache->mmap_is_valid == 0 && cache->peer != NULL) {
@@ -2264,12 +2264,12 @@ int context_get_isa(Context * ctx, ContextAddress addr, ContextISA * isa) {
}
#endif
-static void channel_close_listener(Channel * c) {
+static void channel_close_listener(Channel * ch) {
LINK * l = NULL;
for (l = peers.next; l != &peers; l = l->next) {
PeerCache * p = peers2peer(l);
- if (p->target == c) {
+ if (p->target == ch) {
int i;
assert(p->rc_pending_cnt == 0);
for (i = 0; i < CTX_ID_HASH_SIZE; i++) {

Back to the top