This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: objdump -I patch


Adds a -I option to objdump so that objdump -S can find source that
has moved.

2003-08-04  Bradley Harrington  <bharring@us.ibm.com>
	    Alan Modra  <amodra@bigpond.net.au>

	* objdump.c (include_paths, include_path_count): New vars.
	(add_include_path): New function.
	(usage): Describe --include.
	(long_options): Add "include".
	(struct print_file_list): Make filename const.  Add modname.
	(try_print_file_open, update_source_path): New functions.
	(show_line): Use them.
	(main): Handle 'I' option.  Don't check for NULL xrealloc arg.

Committed to mainline.

Index: binutils/objdump.c
===================================================================
RCS file: /cvs/src/src/binutils/objdump.c,v
retrieving revision 1.73
diff -u -p -r1.73 objdump.c
--- binutils/objdump.c	30 Jul 2003 03:54:15 -0000	1.73
+++ binutils/objdump.c	4 Aug 2003 14:13:52 -0000
@@ -77,6 +77,10 @@ static int dump_debugging_tags;		/* --de
 static bfd_vma adjust_section_vma = 0;	/* --adjust-vma */
 static int file_start_context = 0;      /* --file-start-context */
 
+/* Variables for handling include file path table.  */
+static const char **include_paths;
+static int include_path_count;
+
 /* Extra info to pass to the disassembler address printing function.  */
 struct objdump_disasm_info
 {
@@ -165,6 +169,7 @@ usage (FILE *stream, int status)
   -EB --endian=big               Assume big endian format when disassembling\n\
   -EL --endian=little            Assume little endian format when disassembling\n\
       --file-start-context       Include context from start of file (with -S)\n\
+  -I, --include=DIR              Add DIR to search list for source files\n\
   -l, --line-numbers             Include line numbers and filenames in output\n\
   -C, --demangle[=STYLE]         Decode mangled/processed symbol names\n\
                                   The STYLE, if specified, can be `auto', `gnu',\n\
@@ -228,6 +233,7 @@ static struct option long_options[]=
   {"section-headers", no_argument, NULL, 'h'},
   {"show-raw-insn", no_argument, &show_raw_insn, 1},
   {"source", no_argument, NULL, 'S'},
+  {"include", required_argument, NULL, 'I'},
   {"stabs", no_argument, NULL, 'G'},
   {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
   {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
@@ -841,7 +847,8 @@ static unsigned int prev_line;
 struct print_file_list
 {
   struct print_file_list *next;
-  char *filename;
+  const char *filename;
+  const char *modname;
   unsigned int line;
   FILE *f;
 };
@@ -853,6 +860,89 @@ static struct print_file_list *print_fil
 
 #define SHOW_PRECEDING_CONTEXT_LINES (5)
 
+/* Tries to open MODNAME, and if successful adds a node to print_files
+   linked list and returns that node.  Returns NULL on failure.  */
+
+static struct print_file_list *
+try_print_file_open (const char *origname, const char *modname)
+{
+  struct print_file_list *p;
+  FILE *f;
+
+  f = fopen (modname, "r");
+  if (f == NULL)
+    return NULL;
+
+  if (print_files != NULL && print_files->f != NULL)
+    {
+      fclose (print_files->f);
+      print_files->f = NULL;
+    }
+
+  p = xmalloc (sizeof (struct print_file_list));
+  p->filename = origname;
+  p->modname = modname;
+  p->line = 0;
+  p->f = f;
+  p->next = print_files;
+  print_files = p;
+  return p;
+}
+
+/* If the the source file, as described in the symtab, is not found
+   try to locate it in one of the paths specified with -I
+   If found, add location to print_files linked list.  */
+
+static struct print_file_list *
+update_source_path (const char *filename)
+{
+  struct print_file_list *p;
+  const char *fname;
+  int i;
+
+  if (filename == NULL)
+    return NULL;
+
+  p = try_print_file_open (filename, filename);
+  if (p != NULL)
+    return p;
+
+  if (include_path_count == 0)
+    return NULL;
+
+  /* Get the name of the file.  */
+  fname = strrchr (filename, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    /* We could have a mixed forward/back slash case.  */
+    char *backslash = strrchr (filename, '\\');
+    if (fname == NULL || (backslash != NULL && backslash > fname))
+      fname = backslash;
+    if (fname == NULL && filename[0] != '\0' && filename[1] == ':')
+      fname = filename + 1;
+  }
+#endif
+  if (fname == NULL)
+    fname = filename;
+  else
+    ++fname;
+
+  /* If file exists under a new path, we need to add it to the list
+     so that show_line knows about it.  */
+  for (i = 0; i < include_path_count; i++)
+    {
+      char *modname = concat (include_paths[i], "/", fname, (const char *) 0);
+
+      p = try_print_file_open (filename, modname);
+      if (p)
+	return p;
+
+      free (modname);
+    }
+
+  return NULL;
+}
+
 /* Skip ahead to a given line in a file, optionally printing each
    line.  */
 
@@ -950,7 +1040,7 @@ show_line (bfd *abfd, asection *section,
 
 	      if (p->f == NULL)
 		{
-		  p->f = fopen (p->filename, "r");
+		  p->f = fopen (p->modname, "r");
 		  p->line = 0;
 		}
 	      if (p->f != NULL)
@@ -973,28 +1063,12 @@ show_line (bfd *abfd, asection *section,
 	}
       else
 	{
-	  FILE *f;
+	  p = update_source_path (filename);
 
-	  f = fopen (filename, "r");
-	  if (f != NULL)
+	  if (p != NULL)
 	    {
 	      int l;
 
-	      p = ((struct print_file_list *)
-		   xmalloc (sizeof (struct print_file_list)));
-	      p->filename = xmalloc (strlen (filename) + 1);
-	      strcpy (p->filename, filename);
-	      p->line = 0;
-	      p->f = f;
-
-	      if (print_files != NULL && print_files->f != NULL)
-		{
-		  fclose (print_files->f);
-		  print_files->f = NULL;
-		}
-	      p->next = print_files;
-	      print_files = p;
-
 	      if (file_start_context)
 		l = 0;
 	      else
@@ -2537,6 +2611,23 @@ dump_reloc_set (bfd *abfd, asection *sec
       printf ("\n");
     }
 }
+
+/* Creates a table of paths, to search for source files.  */
+
+static void
+add_include_path (const char *path)
+{
+  if (path[0] == 0)
+    return;
+  include_path_count++;
+  include_paths = xrealloc (include_paths,
+			    include_path_count * sizeof (*include_paths));
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  if (path[1] == ':' && path[2] == 0)
+    path = concat (path, ".", (const char *) 0);
+#endif
+  include_paths[include_path_count - 1] = path;
+}
 
 int
 main (int argc, char **argv)
@@ -2562,7 +2653,7 @@ main (int argc, char **argv)
   bfd_init ();
   set_default_bfd_target ();
 
-  while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zgeG",
+  while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSI:j:wE:zgeG",
 			   long_options, (int *) 0))
 	 != EOF)
     {
@@ -2582,16 +2673,10 @@ main (int argc, char **argv)
 	    disassembler_options = optarg;
 	  break;
 	case 'j':
-	  if (only == NULL)
-	    {
-	      only_size = 8;
-	      only = (char **) xmalloc (only_size * sizeof (char *));
-	    }
-	  else if (only_used == only_size)
+	  if (only_used == only_size)
 	    {
 	      only_size += 8;
-	      only = (char **) xrealloc (only,
-					 only_size * sizeof (char *));
+	      only = xrealloc (only, only_size * sizeof (char *));
 	    }
 	  only [only_used++] = optarg;
 	  break;
@@ -2657,6 +2742,9 @@ main (int argc, char **argv)
 	case 'i':
 	  formats_info = TRUE;
 	  seenflag = TRUE;
+	  break;
+	case 'I':
+	  add_include_path (optarg);
 	  break;
 	case 'p':
 	  dump_private_headers = TRUE;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]