This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: objdump -I patch
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Bradley Harrington <bharring at us dot ibm dot com>, binutils at sources dot redhat dot com
- Date: Tue, 05 Aug 2003 00:01:52 +0930
- Subject: Re: objdump -I patch
- References: <20030613050928.GM23826@bubble.sa.bigpond.net.au><OF5CD1973C.22DAA596-ON86256D5C.006DBE26-86256D5C.006E5F0A@us.ibm.com>
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