$OpenBSD: patch-binutils_debug_c,v 1.3 2010/06/27 20:58:10 ckuethe Exp $
--- binutils/debug.c.orig	Sat Jun 26 11:22:43 2010
+++ binutils/debug.c	Sat Jun 26 11:31:17 2010
@@ -31,6 +31,7 @@
 #include <assert.h>
 #include "bfd.h"
 #include "libiberty.h"
+#include "bucomm.h"
 #include "debug.h"
 
 /* Global information we keep for debugging.  A pointer to this
@@ -552,6 +553,19 @@ struct debug_type_real_list
   struct debug_type_s *t;
 };
 
+/* Simple list, used for pathname translations. */
+struct xlat_list
+{
+  /* Next string on list. */
+  struct xlat_list *next;
+  /* Old part to match against. */
+  const char *old;
+  size_t olen;
+  /* New part to replace. */
+  const char *newstr;
+  size_t nlen;
+};
+
 /* Local functions.  */
 
 static void debug_error (const char *);
@@ -588,6 +602,11 @@ static bfd_boolean debug_type_samep
   (struct debug_handle *, struct debug_type_s *, struct debug_type_s *);
 static bfd_boolean debug_class_type_samep
   (struct debug_handle *, struct debug_type_s *, struct debug_type_s *);
+static const char *debug_xlat_pathname (const char *);
+
+/* List of pathname translations. */
+static struct xlat_list *xlat, *xltail;
+static bfd_boolean xlat_basename;
 
 /* Issue an error message.  */
 
@@ -680,6 +699,8 @@ debug_set_filename (void *handle, const char *name)
 
   if (name == NULL)
     name = "";
+  else
+    name = debug_xlat_pathname (name);
 
   nfile = (struct debug_file *) xmalloc (sizeof *nfile);
   memset (nfile, 0, sizeof *nfile);
@@ -720,6 +741,8 @@ debug_start_source (void *handle, const char *name)
 
   if (name == NULL)
     name = "";
+  else
+    name = debug_xlat_pathname (name);
 
   if (info->current_unit == NULL)
     {
@@ -3369,4 +3392,70 @@ debug_class_type_samep (struct debug_handle *info, str
     }
 
   return TRUE;
+}
+
+/* Register a pathname translation. */
+void
+debug_register_pathname_xlat (oname, nname)
+     const char *oname;
+     const char *nname;
+{
+  struct xlat_list *xlp;
+
+  /* Special case: if oname is given as NULL, this means the
+     --basename option has been given to objcopy. */
+  if (oname == NULL)
+    {
+      xlat_basename = TRUE;
+      return;
+    }
+
+  xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list));
+  xlp->next = NULL;
+  if (xlat == NULL)
+    xlat = xltail = xlp;
+  else
+    {
+      xltail->next = xlp;
+      xltail = xlp;
+    }
+  xlp->old = oname;
+  xlp->newstr = nname;
+  xlp->olen = strlen (oname);
+  xlp->nlen = strlen (nname);
+}
+
+/* Try to translate a pathname. */
+static const char *
+debug_xlat_pathname (oname)
+     const char *oname;
+{
+  struct xlat_list *xlp;
+  char *cp;
+  size_t olen;
+
+  if (xlat_basename)
+    return bu_basename (oname);  
+
+  olen = strlen (oname);
+  for (xlp = xlat; xlp; xlp = xlp->next)
+    {
+      if (xlp->olen > olen)
+	/* This cannot be our turn. */
+	continue;
+      /* Since we have pre-computed all our length values to avoid
+	 repetitively computing them, just use memcmp() since it's
+	 faster than strcmp(). */
+      if (memcmp (xlp->old, oname, xlp->olen) == 0)
+	{
+	  cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1);
+	  memcpy (cp, xlp->newstr, xlp->nlen);
+	  memcpy (cp + xlp->nlen, oname + xlp->olen,
+		  olen - xlp->olen + 1);
+	  return cp;
+	}
+    }
+
+  /* Not found, pass the original name on. */
+  return oname;
 }
