2008-07-15 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 6f178177dc112c9265a5a48a218c56f7472d3a09..74a4198849db0fbcba189453372401736cf606fc 100644 (file)
@@ -740,6 +740,27 @@ find_symbol_for_address (bfd_vma vma,
             == bfd_asymbol_value (sorted_syms[thisplace - 1])))
     --thisplace;
 
+  /* Prefer a symbol in the current section if we have multple symbols
+     with the same value, as can occur with overlays or zero size
+     sections.  */
+  min = thisplace;
+  while (min < max
+        && (bfd_asymbol_value (sorted_syms[min])
+            == bfd_asymbol_value (sorted_syms[thisplace])))
+    {
+      if (sorted_syms[min]->section == sec
+         && info->symbol_is_valid (sorted_syms[min], info))
+       {
+         thisplace = min;
+
+         if (place != NULL)
+           *place = thisplace;
+
+         return sorted_syms[thisplace];
+       }
+      ++min;
+    }
+
   /* If the file is relocatable, and the symbol could be from this
      section, prefer a symbol from this section over symbols from
      others, even if the other symbol's value might be closer.
@@ -759,19 +780,9 @@ find_symbol_for_address (bfd_vma vma,
       || !info->symbol_is_valid (sorted_syms[thisplace], info))
     {
       long i;
-      long newplace;
+      long newplace = sorted_symcount;
 
-      for (i = thisplace + 1; i < sorted_symcount; i++)
-       {
-         if (bfd_asymbol_value (sorted_syms[i])
-             != bfd_asymbol_value (sorted_syms[thisplace]))
-           break;
-       }
-
-      --i;
-      newplace = sorted_symcount;
-
-      for (; i >= 0; i--)
+      for (i = min - 1; i >= 0; i--)
        {
          if ((sorted_syms[i]->section == sec || !want_section)
              && info->symbol_is_valid (sorted_syms[i], info))
@@ -864,7 +875,7 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
     }
 
   if (display_file_offsets)
-    info->fprintf_func (info->stream, " (File Offset: 0x%lx)",
+    info->fprintf_func (info->stream, _(" (File Offset: 0x%lx)"),
                        (long int)(sec->filepos + (vma - sec->vma)));
 }
 
@@ -877,18 +888,22 @@ objdump_print_addr (bfd_vma vma,
                    bfd_boolean skip_zeroes)
 {
   struct objdump_disasm_info *aux;
-  asymbol *sym = NULL; /* Initialize to avoid compiler warning.  */
+  asymbol *sym = NULL;
   bfd_boolean skip_find = FALSE;
 
+  aux = (struct objdump_disasm_info *) info->application_data;
+
   if (sorted_symcount < 1)
     {
       (*info->fprintf_func) (info->stream, "0x");
       objdump_print_value (vma, info, skip_zeroes);
+
+      if (display_file_offsets)
+       info->fprintf_func (info->stream, _(" (File Offset: 0x%lx)"),
+                           (long int)(aux->sec->filepos + (vma - aux->sec->vma)));
       return;
     }
 
-  aux = (struct objdump_disasm_info *) info->application_data;
-
   if (aux->reloc != NULL
       && aux->reloc->sym_ptr_ptr != NULL
       && * aux->reloc->sym_ptr_ptr != NULL)
@@ -960,7 +975,7 @@ static struct print_file_list *print_files;
 
 #define SHOW_PRECEDING_CONTEXT_LINES (5)
 
-/* Read a complete file into memory. */
+/* Read a complete file into memory.  */
 
 static const char *
 slurp_file (const char *fn, size_t *size)
@@ -971,7 +986,7 @@ slurp_file (const char *fn, size_t *size)
 #endif
   const char *map;
   struct stat st;
-  int fd = open (fn, O_RDONLY);
+  int fd = open (fn, O_RDONLY | O_BINARY);
 
   if (fd < 0)
     return NULL;
@@ -2047,15 +2062,25 @@ load_debug_section (enum dwarf_section_display_enum debug, void *file)
   bfd *abfd = file;
   asection *sec;
   bfd_boolean ret;
+  int section_is_compressed;
 
   /* If it is already loaded, do nothing.  */
   if (section->start != NULL)
     return 1;
 
   /* Locate the debug section.  */
-  sec = bfd_get_section_by_name (abfd, section->name);
+  sec = bfd_get_section_by_name (abfd, section->uncompressed_name);
+  if (sec != NULL)
+    section->name = section->uncompressed_name;
+  else
+    {
+      sec = bfd_get_section_by_name (abfd, section->compressed_name);
+      if (sec != NULL)
+       section->name = section->compressed_name;
+    }
   if (sec == NULL)
     return 0;
+  section_is_compressed = section->name == section->compressed_name;
 
   /* Compute a bias to be added to offsets found within the DWARF debug
      information.  These offsets are meant to be relative to the start of
@@ -2082,11 +2107,24 @@ load_debug_section (enum dwarf_section_display_enum debug, void *file)
     ret = bfd_get_section_contents (abfd, sec, section->start, 0,
                                    section->size);
 
-  if (!ret)
+  if (! ret)
     {
       free_debug_section (debug);
       printf (_("\nCan't get contents for section '%s'.\n"),
              section->name);
+      return 0;
+    }
+
+  if (section_is_compressed)
+    {
+      bfd_size_type size = section->size;
+      if (! bfd_uncompress_section_contents (&section->start, &size))
+        {
+          free_debug_section (debug);
+          printf (_("\nCan't uncompress section '%s'.\n"), section->name);
+          return 0;
+        }
+      section->size = size;
     }
 
   return ret;
@@ -2120,15 +2158,16 @@ dump_dwarf_section (bfd *abfd, asection *section,
     match = name;
 
   for (i = 0; i < max; i++)
-    if (strcmp (debug_displays[i].section.name, match) == 0)
+    if (strcmp (debug_displays [i].section.uncompressed_name, match) == 0
+        || strcmp (debug_displays [i].section.compressed_name, match) == 0)
       {
-       if (!debug_displays[i].eh_frame)
+       if (!debug_displays [i].eh_frame)
          {
            struct dwarf_section *sec = &debug_displays [i].section;
 
            if (load_debug_section (i, abfd))
              {
-               debug_displays[i].display (sec, abfd);
+               debug_displays [i].display (sec, abfd);
 
                if (i != info && i != abbrev)
                  free_debug_section (i);
@@ -2138,7 +2177,7 @@ dump_dwarf_section (bfd *abfd, asection *section,
       }
 }
 
-static const char *mach_o_dwarf_sections [] = {
+static const char *mach_o_uncompressed_dwarf_sections [] = {
   "LC_SEGMENT.__DWARFA.__debug_abbrev",                /* .debug_abbrev */
   "LC_SEGMENT.__DWARFA.__debug_aranges",       /* .debug_aranges */
   "LC_SEGMENT.__DWARFA.__debug_frame",         /* .debug_frame */
@@ -2157,7 +2196,27 @@ static const char *mach_o_dwarf_sections [] = {
   "LC_SEGMENT.__DWARFA.__debug_weaknames"      /* .debug_weaknames */
 };
 
-static const char *generic_dwarf_sections [max];
+static const char *mach_o_compressed_dwarf_sections [] = {
+  "LC_SEGMENT.__DWARFA.__zdebug_abbrev",       /* .zdebug_abbrev */
+  "LC_SEGMENT.__DWARFA.__zdebug_aranges",      /* .zdebug_aranges */
+  "LC_SEGMENT.__DWARFA.__zdebug_frame",                /* .zdebug_frame */
+  "LC_SEGMENT.__DWARFA.__zdebug_info",         /* .zdebug_info */
+  "LC_SEGMENT.__DWARFA.__zdebug_line",         /* .zdebug_line */
+  "LC_SEGMENT.__DWARFA.__zdebug_pubnames",     /* .zdebug_pubnames */
+  ".eh_frame",                                 /* .eh_frame */
+  "LC_SEGMENT.__DWARFA.__zdebug_macinfo",      /* .zdebug_macinfo */
+  "LC_SEGMENT.__DWARFA.__zdebug_str",          /* .zdebug_str */
+  "LC_SEGMENT.__DWARFA.__zdebug_loc",          /* .zdebug_loc */
+  "LC_SEGMENT.__DWARFA.__zdebug_pubtypes",     /* .zdebug_pubtypes */
+  "LC_SEGMENT.__DWARFA.__zdebug_ranges",       /* .zdebug_ranges */
+  "LC_SEGMENT.__DWARFA.__zdebug_static_func",  /* .zdebug_static_func */
+  "LC_SEGMENT.__DWARFA.__zdebug_static_vars",  /* .zdebug_static_vars */
+  "LC_SEGMENT.__DWARFA.__zdebug_types",                /* .zdebug_types */
+  "LC_SEGMENT.__DWARFA.__zdebug_weaknames"     /* .zdebug_weaknames */
+};
+
+static const char *generic_uncompressed_dwarf_sections [max];
+static const char *generic_compressed_dwarf_sections [max];
 
 static void
 check_mach_o_dwarf (bfd *abfd)
@@ -2166,18 +2225,33 @@ check_mach_o_dwarf (bfd *abfd)
   enum bfd_flavour current_flavour = bfd_get_flavour (abfd);
   enum dwarf_section_display_enum i;
 
-  if (generic_dwarf_sections [0] == NULL)
+  if (generic_uncompressed_dwarf_sections [0] == NULL)
     for (i = 0; i < max; i++)
-      generic_dwarf_sections [i] = debug_displays[i].section.name;
+      {
+        generic_uncompressed_dwarf_sections [i]
+            = debug_displays[i].section.uncompressed_name;
+        generic_compressed_dwarf_sections [i]
+            = debug_displays[i].section.compressed_name;
+      }
 
   if (old_flavour != current_flavour)
     {
       if (current_flavour == bfd_target_mach_o_flavour)
        for (i = 0; i < max; i++)
-         debug_displays[i].section.name = mach_o_dwarf_sections [i];
+          {
+            debug_displays[i].section.uncompressed_name
+                = mach_o_uncompressed_dwarf_sections [i];
+            debug_displays[i].section.compressed_name
+                = mach_o_compressed_dwarf_sections [i];
+          }
       else if (old_flavour == bfd_target_mach_o_flavour)
        for (i = 0; i < max; i++)
-         debug_displays[i].section.name = generic_dwarf_sections [i];
+          {
+            debug_displays[i].section.uncompressed_name
+                = generic_uncompressed_dwarf_sections [i];
+            debug_displays[i].section.compressed_name
+                = generic_compressed_dwarf_sections [i];
+          }
 
       old_flavour = current_flavour;
     }
@@ -2464,12 +2538,6 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
   if ((datasize = bfd_section_size (abfd, section)) == 0)
     return;
 
-  printf (_("Contents of section %s:\n"), section->name);
-
-  data = xmalloc (datasize);
-
-  bfd_get_section_contents (abfd, section, data, 0, datasize);
-
   /* Compute the address range to display.  */
   if (start_address == (bfd_vma) -1
       || start_address < section->vma)
@@ -2490,6 +2558,18 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
        stop_offset = datasize / opb;
     }
 
+  if (start_offset >= stop_offset)
+    return;
+  
+  printf (_("Contents of section %s:"), section->name);
+  if (display_file_offsets)
+    printf (_("  (Starting at file offset: 0x%lx)"), (long int)(section->filepos + start_offset));
+  printf ("\n");
+
+  data = xmalloc (datasize);
+
+  bfd_get_section_contents (abfd, section, data, 0, datasize);
+
   width = 4;
 
   bfd_sprintf_vma (abfd, buf, start_offset + section->vma);
@@ -2927,7 +3007,7 @@ dump_bfd (bfd *abfd)
     {
       void *dhandle;
 
-      dhandle = read_debugging_info (abfd, syms, symcount);
+      dhandle = read_debugging_info (abfd, syms, symcount, TRUE);
       if (dhandle != NULL)
        {
          if (!print_debugging_info (stdout, dhandle, abfd, syms,
@@ -2939,6 +3019,12 @@ dump_bfd (bfd *abfd)
              exit_status = 1;
            }
        }
+      /* PR 6483: If there was no STABS or IEEE debug
+        info in the file, try DWARF instead.  */
+      else if (! dump_dwarf_section_info)
+       {
+         dump_dwarf (abfd);
+       }
     }
 
   if (syms)
This page took 0.026467 seconds and 4 git commands to generate.