Merge r14289 from the BUF_REMOVAL branch to trunk.
Change CLG_(get_debug_info) to not build up an absolute pathname in its
'file' parameter. Instead give it an additional parameter to hold the
directory name. Callers can then build up the absolute pathname if needed.
This change will come in handy soonish when VG_(get_filename_lineno) will be
changed and those buffers will disappear.
The change has a bit of ripple to get_fn_node_inseg and CLG_(get_file_node).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14666 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/callgrind/fn.c b/callgrind/fn.c
index 3102b52..fe3342f 100644
--- a/callgrind/fn.c
+++ b/callgrind/fn.c
@@ -286,7 +286,7 @@
 
 
 static __inline__ 
-file_node* new_file_node(HChar filename[FILENAME_LEN],
+file_node* new_file_node(const HChar *filename,
 			 obj_node* obj, file_node* next)
 {
   Int i;
@@ -305,11 +305,19 @@
 
  
 file_node* CLG_(get_file_node)(obj_node* curr_obj_node,
-                               HChar filename[FILENAME_LEN])
+                               const HChar *dir, const HChar *file)
 {
     file_node* curr_file_node;
     UInt       filename_hash;
 
+    /* Build up an absolute pathname, if there is a directory available */
+    HChar filename[VG_(strlen)(dir) + 1 + VG_(strlen)(file) + 1];
+    VG_(strcpy)(filename, dir);
+    if (filename[0] != '\0') {
+       VG_(strcat)(filename, "/");
+    }
+    VG_(strcat)(filename, file);
+
     /* lookup in file hash */
     filename_hash = str_hash(filename, N_FILE_ENTRIES);
     curr_file_node = curr_obj_node->files[filename_hash];
@@ -403,11 +411,12 @@
  */
 static __inline__
 fn_node* get_fn_node_inseg(DebugInfo* di,
-			   HChar filename[FILENAME_LEN],
+			   const HChar *dirname,
+			   const HChar *filename,
 			   const HChar *fnname)
 {
   obj_node  *obj  = CLG_(get_obj_node)(di);
-  file_node *file = CLG_(get_file_node)(obj, filename);
+  file_node *file = CLG_(get_file_node)(obj, dirname, filename);
   fn_node   *fn   = get_fn_node_infile(file, fnname);
 
   return fn;
@@ -415,12 +424,12 @@
 
 
 Bool CLG_(get_debug_info)(Addr instr_addr,
-			 HChar file[FILENAME_LEN],
-			 const HChar **fn_name, UInt* line_num,
-			 DebugInfo** pDebugInfo)
+                          HChar dir[FILENAME_LEN],
+                          HChar file[FILENAME_LEN],
+                          const HChar **fn_name, UInt* line_num,
+                          DebugInfo** pDebugInfo)
 {
   Bool found_file_line, found_fn, found_dirname, result = True;
-  HChar dir[FILENAME_LEN];
   UInt line;
   
   CLG_DEBUG(6, "  + get_debug_info(%#lx)\n", instr_addr);
@@ -438,14 +447,6 @@
 					       &line);
    found_fn = VG_(get_fnname)(instr_addr, fn_name);
 
-   if (found_dirname) {
-       // +1 for the '/'.
-       CLG_ASSERT(VG_(strlen)(dir) + VG_(strlen)(file) + 1 < FILENAME_LEN);
-       VG_(strcat)(dir, "/");         // Append '/'
-       VG_(strcat)(dir, file);    // Append file to dir
-       VG_(strcpy)(file, dir);    // Move dir+file to file
-   }
-
    if (!found_file_line && !found_fn) {
      CLG_(stat).no_debug_BBs++;
      VG_(strcpy)(file, "???");
@@ -488,6 +489,7 @@
 fn_node* CLG_(get_fn_node)(BB* bb)
 {
     HChar      filename[FILENAME_LEN];
+    HChar      dirname[FILENAME_LEN];
     const HChar *fnname;
     DebugInfo* di;
     UInt       line_num;
@@ -502,7 +504,7 @@
      * the BB according to debug information
      */
     CLG_(get_debug_info)(bb_addr(bb),
-			filename, &fnname, &line_num, &di);
+                         dirname, filename, &fnname, &line_num, &di);
 
     if (0 == VG_(strcmp)(fnname, "???")) {
 	int p;
@@ -533,7 +535,7 @@
     if (0 == VG_(strcmp)(fnname, "vgPlain___libc_freeres_wrapper")
 	&& exit_bb) {
       CLG_(get_debug_info)(bb_addr(exit_bb),
-			  filename, &fnname, &line_num, &di);
+                           dirname, filename, &fnname, &line_num, &di);
 	
 	CLG_DEBUG(1, "__libc_freeres_wrapper renamed to _exit\n");
     }
@@ -548,7 +550,7 @@
     }
 
     /* get fn_node struct for this function */
-    fn = get_fn_node_inseg( di, filename, fnname);
+    fn = get_fn_node_inseg( di, dirname, filename, fnname);
 
     /* if this is the 1st time the function is seen,
      * some attributes are set */
@@ -589,8 +591,12 @@
     bb->fn   = fn;
     bb->line = line_num;
 
-    CLG_DEBUG(3,"- get_fn_node(BB %#lx): %s (in %s:%u)\n",
-	     bb_addr(bb), fnname, filename, line_num);
+    if (dirname[0]) {
+       CLG_DEBUG(3,"- get_fn_node(BB %#lx): %s (in %s:%u)\n",
+                 bb_addr(bb), fnname, filename, line_num);
+    } else
+       CLG_DEBUG(3,"- get_fn_node(BB %#lx): %s (in %s/%s:%u)\n",
+                 bb_addr(bb), fnname, dirname, filename, line_num);
 
     return fn;
 }