TCF Agent: added support for one-to-many file path mapping
diff --git a/agent/tcf/services/linenumbers_elf.c b/agent/tcf/services/linenumbers_elf.c
index 6566859..e10cca4 100644
--- a/agent/tcf/services/linenumbers_elf.c
+++ b/agent/tcf/services/linenumbers_elf.c
@@ -80,10 +80,13 @@
     j = strlen(full_name);
     if (i <= j && strcmp(file, full_name + j - i) == 0) return 1;
 #if SERVICE_PathMap
-    {
-        char * s = apply_path_map(chnl, ctx, full_name, PATH_MAP_TO_CLIENT);
-        if (s != full_name) {
-            full_name = canonic_path_map_file_name(s);
+    if (apply_path_map(chnl, ctx, full_name, PATH_MAP_TO_CLIENT) != full_name) {
+        unsigned n = 0;
+        unsigned cnt = 0;
+        char ** buf = NULL;
+        get_apply_path_map_results(&cnt, &buf);
+        for (n = 0; n < cnt; n++) {
+            full_name = canonic_path_map_file_name(buf[n]);
             j = strlen(full_name);
             if (i <= j && strcmp(file, full_name + j - i) == 0) return 1;
         }
diff --git a/agent/tcf/services/pathmap.c b/agent/tcf/services/pathmap.c
index 3ea725e..9fda711 100644
--- a/agent/tcf/services/pathmap.c
+++ b/agent/tcf/services/pathmap.c
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010-2021 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.
@@ -148,6 +148,10 @@
 
 static TCFBroadcastGroup * broadcast_group = NULL;
 
+static unsigned fnm_max = 0;
+static unsigned fnm_cnt = 0;
+static char ** fnm_buf = NULL;
+
 static void event_path_map_changed(void) {
     OutputStream * out = &broadcast_group->out;
 
@@ -346,7 +350,7 @@
     return diff;
 }
 
-static char * map_file_name(Context * ctx, PathMap * m, char * fnm, int mode) {
+static void map_file_name(Context * ctx, PathMap * m, char * fnm, int mode) {
     unsigned i, k;
 
     for (i = 0; i < m->rules_cnt; i++) {
@@ -414,20 +418,26 @@
             buf = tmp_strdup2(r->dst, fnm + k);
         }
 
-        if (mode != PATH_MAP_TO_LOCAL || stat(buf, &st) == 0) return buf;
+        if (mode != PATH_MAP_TO_LOCAL || stat(buf, &st) == 0) {
+            if (fnm_max <= fnm_cnt) {
+                fnm_max += 16;
+                fnm_buf = (char **)tmp_realloc(fnm_buf, fnm_max * sizeof(char *));
+            }
+            fnm_buf[fnm_cnt++] = buf;
+        }
     }
-
-    return fnm;
 }
 
 char * apply_path_map(Channel * c, Context * ctx, char * fnm, int mode) {
     char * cnm = canonic_path_map_file_name(fnm);
+    fnm_cnt = 0;
+    fnm_max = 0;
+    fnm_buf = NULL;
     if (c == NULL) {
         LINK * l = maps.next;
         while (l != &maps) {
             PathMap * m = maps2map(l);
-            char * lnm = map_file_name(ctx, m, cnm, mode);
-            if (lnm != cnm) return lnm;
+            map_file_name(ctx, m, cnm, mode);
             l = l->next;
         }
     }
@@ -437,21 +447,21 @@
         Channel * h = proxy_get_host_channel(c);
         if (h != NULL) {
             m = find_map(h);
-            if (m != NULL) {
-                char * lnm = map_file_name(ctx, m, cnm, mode);
-                if (lnm != cnm) return lnm;
-            }
+            if (m != NULL) map_file_name(ctx, m, cnm, mode);
         }
 #endif
         m = find_map(c);
-        if (m != NULL) {
-            char * lnm = map_file_name(ctx, m, cnm, mode);
-            if (lnm != cnm) return lnm;
-        }
+        if (m != NULL) map_file_name(ctx, m, cnm, mode);
     }
+    if (fnm_cnt > 0) return fnm_buf[0];
     return fnm;
 }
 
+void get_apply_path_map_results(unsigned * cnt, char *** buf) {
+    *cnt = fnm_cnt;
+    *buf = fnm_buf;
+}
+
 void iterate_path_map_rules(Channel * channel, IteratePathMapsCallBack * callback, void * args) {
     PathMap * m = find_map(channel);
     if (m != NULL) {
diff --git a/agent/tcf/services/pathmap.h b/agent/tcf/services/pathmap.h
index cac6731..4c155e3 100644
--- a/agent/tcf/services/pathmap.h
+++ b/agent/tcf/services/pathmap.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010-2021 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.
@@ -122,8 +122,13 @@
  * Translate debug file name to local or target file name using file path mapping table of given channel.
  * If channel = NULL, search all maps until translation is found.
  * Return pointer to tmp_alloc()-ed buffer that contains translated file name.
+ *
+ * In certain cases multiple path mapping match the file name.
+ * The function returns first match.
+ * The rest of translated file names can be retrieved with get_apply_path_map_results().
  */
 extern char * apply_path_map(Channel * channel, Context * ctx, char * file_name, int mode);
+extern void get_apply_path_map_results(unsigned * cnt, char *** buf);
 
 /*
  * Read new path map from the given input stream.