Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2011-09-12 21:38:37 +0000
committereutarass2011-09-12 21:38:37 +0000
commit42b76b7aabb36ce114f74186527157e035e3c91c (patch)
tree558bed3d50c47e062b55da9f30df58273a3c1f61
parentb81c6fd3fa909779abf1e3ba9923481c8a402f66 (diff)
downloadorg.eclipse.tcf.agent-42b76b7aabb36ce114f74186527157e035e3c91c.tar.gz
org.eclipse.tcf.agent-42b76b7aabb36ce114f74186527157e035e3c91c.tar.xz
org.eclipse.tcf.agent-42b76b7aabb36ce114f74186527157e035e3c91c.zip
TCF Agent: implemented translation of breakpoint file names.
-rw-r--r--server/services/context-proxy.c4
-rw-r--r--services/breakpoints.c23
-rw-r--r--services/linenumbers.c2
-rw-r--r--services/linenumbers.h2
-rw-r--r--services/linenumbers_elf.c18
-rw-r--r--services/linenumbers_win32.c3
-rw-r--r--services/pathmap.c52
-rw-r--r--services/pathmap.h27
-rw-r--r--services/tcf_elf.c16
9 files changed, 114 insertions, 33 deletions
diff --git a/server/services/context-proxy.c b/server/services/context-proxy.c
index ae4a2158..850eb5d5 100644
--- a/server/services/context-proxy.c
+++ b/server/services/context-proxy.c
@@ -994,8 +994,8 @@ static void read_memory_map_item(InputStream * inp, void * args) {
memset(m, 0, sizeof(MemoryRegion));
if (json_read_struct(inp, read_memory_region_property, m) && m->file_name != NULL) {
struct stat buf;
- char * fnm = path_map_to_local(c, m->file_name);
- if (fnm != NULL) {
+ char * fnm = apply_path_map(c, m->file_name, PATH_MAP_TO_LOCAL);
+ if (fnm != m->file_name) {
loc_free(m->file_name);
m->file_name = loc_strdup(fnm);
}
diff --git a/services/breakpoints.c b/services/breakpoints.c
index f96a8ee3..8d46a2dd 100644
--- a/services/breakpoints.c
+++ b/services/breakpoints.c
@@ -44,6 +44,7 @@
#include <services/linenumbers.h>
#include <services/stacktrace.h>
#include <services/memorymap.h>
+#include <services/pathmap.h>
typedef struct BreakpointRef BreakpointRef;
typedef struct BreakpointAttribute BreakpointAttribute;
@@ -1048,7 +1049,7 @@ static void evaluate_text_location(void * x) {
bp_ip = 0;
assert(cache_enter_cnt > 0);
- if (line_to_address(args->ctx, bp->file, bp->line, bp->column, plant_breakpoint_address_iterator, args) < 0) {
+ if (line_to_address(args->ctx, cache_channel(), bp->file, bp->line, bp->column, plant_breakpoint_address_iterator, args) < 0) {
address_expression_error(args->ctx, bp, errno);
}
if (bp_ip != 0) plant_at_address_expression(args->ctx, bp_ip, args->bp);
@@ -2404,6 +2405,18 @@ static void event_code_unmapped(Context * ctx, ContextAddress addr, ContextAddre
}
#endif
+#if SERVICE_PathMap
+static void event_path_map_changed(Channel * c, void * args) {
+ unsigned hash = (unsigned)(uintptr_t)c / 16 % INP2BR_HASH_SIZE;
+ LINK * l = inp2br[hash].next;
+ while (l != &inp2br[hash]) {
+ BreakpointRef * br = link_inp2br(l);
+ l = l->next;
+ if (br->channel == c && br->bp->file != NULL) replant_breakpoint(br->bp);
+ }
+}
+#endif
+
static void channel_close_listener(Channel * c) {
delete_breakpoint_refs(c);
}
@@ -2434,6 +2447,14 @@ void ini_breakpoints_service(Protocol * proto, TCFBroadcastGroup * bcg) {
add_memory_map_event_listener(&listener, NULL);
}
#endif
+#if SERVICE_PathMap
+ {
+ static PathMapEventListener listener = {
+ event_path_map_changed,
+ };
+ add_path_map_event_listener(&listener, NULL);
+ }
+#endif
list_init(&breakpoints);
list_init(&instructions);
list_init(&evaluations_posted);
diff --git a/services/linenumbers.c b/services/linenumbers.c
index 7ed0d8e1..5bdfdd11 100644
--- a/services/linenumbers.c
+++ b/services/linenumbers.c
@@ -215,7 +215,7 @@ static void map_to_memory_cache_client(void * x) {
code_area_cnt = 0;
- if (err == 0 && line_to_address(ctx, args->file,
+ if (err == 0 && line_to_address(ctx, cache_channel(), args->file,
args->line, args->column, add_code_area, NULL) < 0) err = errno;
cache_exit();
diff --git a/services/linenumbers.h b/services/linenumbers.h
index 3e43c970..c891f902 100644
--- a/services/linenumbers.h
+++ b/services/linenumbers.h
@@ -45,7 +45,7 @@ typedef struct CodeArea {
typedef void LineNumbersCallBack(CodeArea *, void *);
-extern int line_to_address(Context * ctx, char * file, int line, int column, LineNumbersCallBack * client, void * args);
+extern int line_to_address(Context * ctx, Channel * chnl, char * file, int line, int column, LineNumbersCallBack * client, void * args);
extern int address_to_line(Context * ctx, ContextAddress addr0, ContextAddress addr1, LineNumbersCallBack * client, void * args);
diff --git a/services/linenumbers_elf.c b/services/linenumbers_elf.c
index 039076f2..e67a861c 100644
--- a/services/linenumbers_elf.c
+++ b/services/linenumbers_elf.c
@@ -40,6 +40,7 @@
#include <services/dwarf.h>
#include <services/dwarfcache.h>
#include <services/stacktrace.h>
+#include <services/pathmap.h>
static int is_absolute_path(char * fnm) {
if (fnm[0] == '/') return 1;
@@ -73,12 +74,15 @@ static void canonic_path(char * fnm, char * buf, size_t buf_size) {
}
}
}
+ if (i == 0 && ch >= 'a' && ch <= 'z' && *fnm == ':') {
+ ch = ch - 'a' + 'A';
+ }
buf[i++] = ch;
}
buf[i++] = 0;
}
-static int compare_path(char * file, char * pwd, char * dir, char * name) {
+static int compare_path(Channel * chnl, char * file, char * pwd, char * dir, char * name) {
int i, j;
char buf[FILE_PATH_SIZE];
@@ -103,7 +107,12 @@ static int compare_path(char * file, char * pwd, char * dir, char * name) {
else {
canonic_path(name, buf, sizeof(buf));
}
-
+#if SERVICE_PathMap
+ {
+ char * cnm = apply_path_map(chnl, buf, PATH_MAP_TO_CLIENT);
+ if (cnm != buf) canonic_path(cnm, buf, sizeof(buf));
+ }
+#endif
i = strlen(file);
j = strlen(buf);
return i <= j && strcmp(file, buf + j - i) == 0;
@@ -204,7 +213,8 @@ static void unit_line_to_address(Context * ctx, CompUnit * unit, unsigned file,
}
}
-int line_to_address(Context * ctx, char * file_name, int line, int column, LineNumbersCallBack * client, void * args) {
+int line_to_address(Context * ctx, Channel * chnl, char * file_name, int line, int column,
+ LineNumbersCallBack * client, void * args) {
int err = 0;
if (ctx == NULL) err = ERR_INV_CONTEXT;
@@ -232,7 +242,7 @@ int line_to_address(Context * ctx, char * file_name, int line, int column, LineN
if (cache->mFileInfoHash) {
FileInfo * f = cache->mFileInfoHash[h % cache->mFileInfoHashSize];
while (f != NULL) {
- if (f->mNameHash == h && compare_path(fnm, f->mCompUnit->mDir, f->mDir, f->mName)) {
+ if (f->mNameHash == h && compare_path(chnl, fnm, f->mCompUnit->mDir, f->mDir, f->mName)) {
CompUnit * unit = f->mCompUnit;
unsigned j = f - unit->mFiles;
unit_line_to_address(ctx, unit, j, line, column, client, args);
diff --git a/services/linenumbers_win32.c b/services/linenumbers_win32.c
index 892ea824..fdaf74c1 100644
--- a/services/linenumbers_win32.c
+++ b/services/linenumbers_win32.c
@@ -34,7 +34,8 @@
#include <system/Windows/windbgcache.h>
#include <system/Windows/context-win32.h>
-int line_to_address(Context * ctx, char * file, int line, int column, LineNumbersCallBack * callback, void * user_args) {
+int line_to_address(Context * ctx, Channel * chnl, char * file, int line, int column,
+ LineNumbersCallBack * callback, void * user_args) {
int err = 0;
if (ctx == NULL) err = ERR_INV_CONTEXT;
diff --git a/services/pathmap.c b/services/pathmap.c
index e4af7d08..c973f4c3 100644
--- a/services/pathmap.c
+++ b/services/pathmap.c
@@ -30,6 +30,11 @@
#include <framework/myalloc.h>
#include <services/pathmap.h>
+typedef struct Listener {
+ PathMapEventListener * listener;
+ void * args;
+} Listener;
+
typedef struct PathMapRuleAttr {
char * name;
char * value;
@@ -58,6 +63,30 @@ static int ini_done = 0;
static LINK maps;
static char host_name[256];
+static Listener * listeners = NULL;
+static unsigned listener_cnt = 0;
+static unsigned listener_max = 0;
+
+static void path_map_event_mapping_changed(Channel * c) {
+ unsigned i;
+ for (i = 0; i < listener_cnt; i++) {
+ Listener * l = listeners + i;
+ if (l->listener->mapping_changed == NULL) continue;
+ l->listener->mapping_changed(c, l->args);
+ }
+}
+
+void add_path_map_event_listener(PathMapEventListener * listener, void * client_data) {
+ Listener * l = NULL;
+ if (listener_cnt >= listener_max) {
+ listener_max += 8;
+ listeners = (Listener *)loc_realloc(listeners, listener_max * sizeof(Listener));
+ }
+ l = listeners + listener_cnt++;
+ l->listener = listener;
+ l->args = client_data;
+}
+
static PathMap * find_map(Channel * c) {
LINK * l;
for (l = maps.next; l != &maps; l = l->next) {
@@ -80,7 +109,7 @@ static int is_my_host(char * host) {
return strcasecmp(host, host_name) == 0;
}
-static char * map_to_local(PathMap * m, char * fnm) {
+static char * map_file_name(PathMap * m, char * fnm, int mode) {
unsigned i, j, k;
static char buf[FILE_PATH_SIZE];
@@ -101,35 +130,39 @@ static char * map_to_local(PathMap * m, char * fnm) {
if (src == NULL || src[0] == 0) continue;
if (dst == NULL || dst[0] == 0) continue;
if (prot != NULL && prot[0] != 0 && strcasecmp(prot, "file")) continue;
- if (!is_my_host(host)) continue;
+ switch (mode) {
+ case PATH_MAP_TO_LOCAL:
+ if (host && !is_my_host(host)) continue;
+ break;
+ }
k = strlen(src);
if (strncmp(src, fnm, k)) continue;
if (fnm[k] != 0 && fnm[k] != '/' && fnm[k] != '\\') continue;
j = strlen(dst) - 1;
if (fnm[k] != 0 && (dst[j] == '/' || dst[j] == '\\')) k++;
snprintf(buf, sizeof(buf), "%s%s", dst, fnm + k);
- if (stat(buf, &st) == 0) return buf;
+ if (mode != PATH_MAP_TO_LOCAL || stat(buf, &st) == 0) return buf;
}
- return NULL;
+ return fnm;
}
-char * path_map_to_local(Channel * c, char * fnm) {
+char * apply_path_map(Channel * c, char * fnm, int mode) {
if (c == NULL) {
LINK * l = maps.next;
while (l != &maps) {
PathMap * m = maps2map(l);
- char * lnm = map_to_local(m, fnm);
- if (lnm != NULL) return lnm;
+ char * lnm = map_file_name(m, fnm, mode);
+ if (lnm != fnm) return lnm;
l = l->next;
}
}
else {
PathMap * m = find_map(c);
if (m == NULL) return NULL;
- return map_to_local(m, fnm);
+ return map_file_name(m, fnm, mode);
}
- return NULL;
+ return fnm;
}
static void write_rule(OutputStream * out, PathMapRule * r) {
@@ -202,6 +235,7 @@ void set_path_map(Channel * c, InputStream * inp) {
m->rules_cnt = 0;
}
json_read_array(inp, read_rule, m);
+ path_map_event_mapping_changed(c);
}
static void command_get(char * token, Channel * c) {
diff --git a/services/pathmap.h b/services/pathmap.h
index 94e40d37..d931a7c1 100644
--- a/services/pathmap.h
+++ b/services/pathmap.h
@@ -24,18 +24,37 @@
#include <config.h>
#include <framework/protocol.h>
+#if SERVICE_PathMap
+
+#define PATH_MAP_TO_CLIENT 1
+#define PATH_MAP_TO_LOCAL 2
+#define PATH_MAP_TO_TARGET 3
+
+/*
+ * Path map listener.
+ */
+typedef struct PathMapEventListener {
+ void (*mapping_changed)(Channel * c, void * client_data);
+} PathMapEventListener;
+
/*
- * Translate debug file name to local name using file path mapping table of given channel.
- * Return pointer to static buffer that contains translated file name,
- * or null if mapping not found.
+ * Translate debug file name to local or target file name using file path mapping table of given channel.
+ * Return pointer to static buffer that contains translated file name.
*/
-extern char * path_map_to_local(Channel * channel, char * file_name);
+extern char * apply_path_map(Channel * channel, char * file_name, int mode);
/*
* Read new path map from the given input stream.
*/
extern void set_path_map(Channel * c, InputStream * inp);
+/*
+ * Add path map listener.
+ */
+extern void add_path_map_event_listener(PathMapEventListener * listener, void * client_data);
+
extern void ini_path_map_service(Protocol * proto);
+#endif /* SERVICE_PathMap */
+
#endif /* D_pathmap */
diff --git a/services/tcf_elf.c b/services/tcf_elf.c
index 68cf9c53..2c5e7bce 100644
--- a/services/tcf_elf.c
+++ b/services/tcf_elf.c
@@ -251,6 +251,7 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) {
while (offs % 4 != 0) offs++;
if (type == 3 && strcmp(name, "GNU") == 0) {
char fnm[FILE_PATH_SIZE];
+ char * lnm = fnm;
struct stat buf;
char id[64];
size_t id_size = 0;
@@ -265,13 +266,10 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) {
id[id_size++] = 0;
trace(LOG_ELF, "Found GNU build ID %s", id);
snprintf(fnm, sizeof(fnm), "/usr/lib/debug/.build-id/%.2s/%s.debug", id, id + 2);
- if (stat(fnm, &buf) == 0) return loc_strdup(fnm);
#if SERVICE_PathMap
- {
- char * lnm = path_map_to_local(NULL, fnm);
- if (lnm != NULL) return loc_strdup(lnm);
- }
+ lnm = apply_path_map(NULL, lnm, PATH_MAP_TO_LOCAL);
#endif
+ if (stat(lnm, &buf) == 0) return loc_strdup(lnm);
return NULL;
}
offs += desc_sz;
@@ -286,6 +284,7 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) {
else {
/* TODO: check debug info CRC */
char fnm[FILE_PATH_SIZE];
+ char * lnm = fnm;
struct stat buf;
char * name = (char *)sec->data;
int l = strlen(file->name);
@@ -297,13 +296,10 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) {
snprintf(fnm, sizeof(fnm), "%.*s.debug/%s", l, file->name, name);
if (stat(fnm, &buf) == 0) return loc_strdup(fnm);
snprintf(fnm, sizeof(fnm), "/usr/lib/debug%.*s%s", l, file->name, name);
- if (stat(fnm, &buf) == 0) return loc_strdup(fnm);
#if SERVICE_PathMap
- {
- char * lnm = path_map_to_local(NULL, fnm);
- if (lnm != NULL) return loc_strdup(lnm);
- }
+ lnm = apply_path_map(NULL, lnm, PATH_MAP_TO_LOCAL);
#endif
+ if (stat(lnm, &buf) == 0) return loc_strdup(lnm);
return NULL;
}
}

Back to the top