* aclocal.m4: Regenerate.
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 9e54192003eccc8d31a573f382efcb206eba0791..1e9d97058ba6c8401ed124d5d10781e59717e8fd 100644 (file)
       processed in order by display_bfd().  If the file is an archive each
       of its elements is processed in turn.
       
-   3. The file's target architecture and binary file format are determnined
+   3. The file's target architecture and binary file format are determined
       by bfd_check_format().  If they are recognised, then dump_bfd() is
       called.
 
-   4. dump_bfd() in turn calls seperate functions to display the requested
-      item(s) of infomation(s).  For example dissasemble_data() is called if
-      a disassmebly has been requested.
+   4. dump_bfd() in turn calls separate functions to display the requested
+      item(s) of information(s).  For example disassemble_data() is called if
+      a disassembly has been requested.
 
    When disassembling the code loops through blocks of instructions bounded
-   by symbols, calling dissassemble_bytes() on each block.  The actual
+   by symbols, calling disassemble_bytes() on each block.  The actual
    disassembling is done by the libopcodes library, via a function pointer
    supplied by the disassembler() function.  */
 
@@ -75,7 +75,8 @@ static int exit_status = 0;
 
 static char *default_target = NULL;    /* Default at runtime.  */
 
-/* The following variables are set based on arguments passed on command line.  */
+/* The following variables are set based on arguments passed on the
+   command line.  */
 static int show_version = 0;           /* Show the version number.  */
 static int dump_section_contents;      /* -s */
 static int dump_section_headers;       /* -h */
@@ -116,7 +117,8 @@ static size_t only_used = 0;
 static const char **include_paths;
 static int include_path_count;
 
-/* Extra info to pass to the section disassembler and address printing function.  */
+/* Extra info to pass to the section disassembler and address printing
+   function.  */
 struct objdump_disasm_info
 {
   bfd *              abfd;
@@ -600,9 +602,9 @@ objdump_print_value (bfd_vma vma, struct disassemble_info *info,
 {
   char buf[30];
   char *p;
-  struct objdump_disasm_info *aux
-    = (struct objdump_disasm_info *) info->application_data;
+  struct objdump_disasm_info *aux;
 
+  aux = (struct objdump_disasm_info *) info->application_data;
   bfd_sprintf_vma (aux->abfd, buf, vma);
   if (! skip_zeroes)
     p = buf;
@@ -643,14 +645,16 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *info,
     free (alloc);
 }
 
-/* Locate a symbol given a bfd, a section, and a VMA.  If REQUIRE_SEC
-   is TRUE, then always require the symbol to be in the section.  This
-   returns NULL if there is no suitable symbol.  If PLACE is not NULL,
-   then *PLACE is set to the index of the symbol in sorted_syms.  */
+/* Locate a symbol given a bfd and a section (from INFO->application_data),
+   and a VMA.  If INFO->application_data->require_sec is TRUE, then always
+   require the symbol to be in the section.  Returns NULL if there is no
+   suitable symbol.  If PLACE is not NULL, then *PLACE is set to the index
+   of the symbol in sorted_syms.  */
 
 static asymbol *
-find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
-                        bfd_boolean require_sec, long *place)
+find_symbol_for_address (bfd_vma vma,
+                        struct disassemble_info *info,
+                        long *place)
 {
   /* @@ Would it speed things up to cache the last two symbols returned,
      and maybe their address ranges?  For many processors, only one memory
@@ -661,11 +665,19 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
   long min = 0;
   long max = sorted_symcount;
   long thisplace;
-  unsigned int opb = bfd_octets_per_byte (abfd);
+  struct objdump_disasm_info *aux;
+  bfd *abfd;
+  asection *sec;
+  unsigned int opb;
 
   if (sorted_symcount < 1)
     return NULL;
 
+  aux = (struct objdump_disasm_info *) info->application_data;
+  abfd = aux->abfd;
+  sec = aux->sec;
+  opb = bfd_octets_per_byte (abfd);
+
   /* Perform a binary search looking for the closest symbol to the
      required value.  We are searching the range (min, max].  */
   while (min + 1 < max)
@@ -704,7 +716,7 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
      no way to tell what's desired without looking at the relocation
      table.  */
   if (sorted_syms[thisplace]->section != sec
-      && (require_sec
+      && (aux->require_sec
          || ((abfd->flags & HAS_RELOC) != 0
              && vma >= bfd_get_section_vma (abfd, sec)
              && vma < (bfd_get_section_vma (abfd, sec)
@@ -749,15 +761,22 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
        }
 
       if (sorted_syms[thisplace]->section != sec
-         && (require_sec
+         && (aux->require_sec
              || ((abfd->flags & HAS_RELOC) != 0
                  && vma >= bfd_get_section_vma (abfd, sec)
                  && vma < (bfd_get_section_vma (abfd, sec)
                            + bfd_section_size (abfd, sec)))))
-       {
-         /* There is no suitable symbol.  */
-         return NULL;
-       }
+       /* There is no suitable symbol.  */
+       return NULL;
+    }
+
+  /* Give the target a chance to reject the symbol.  */
+  while (! info->symbol_is_valid (sorted_syms [thisplace], info))
+    {
+      ++ thisplace;
+      if (thisplace >= sorted_symcount
+         || bfd_asymbol_value (sorted_syms [thisplace]) > vma)
+       return NULL;
     }
 
   if (place != NULL)
@@ -816,7 +835,8 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
    If SKIP_ZEROES is TRUE, don't output leading zeroes.  */
 
 static void
-objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
+objdump_print_addr (bfd_vma vma,
+                   struct disassemble_info *info,
                    bfd_boolean skip_zeroes)
 {
   struct objdump_disasm_info *aux;
@@ -830,8 +850,7 @@ objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
     }
 
   aux = (struct objdump_disasm_info *) info->application_data;
-  sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
-                                NULL);
+  sym = find_symbol_for_address (vma, info, NULL);
   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
                               skip_zeroes);
 }
@@ -850,16 +869,9 @@ objdump_print_address (bfd_vma vma, struct disassemble_info *info)
 static int
 objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info)
 {
-  struct objdump_disasm_info * aux;
   asymbol * sym;
 
-  /* No symbols - do not bother checking.  */
-  if (sorted_symcount < 1)
-    return 0;
-
-  aux = (struct objdump_disasm_info *) info->application_data;
-  sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
-                                NULL);
+  sym = find_symbol_for_address (vma, info, NULL);
 
   return (sym != NULL && (bfd_asymbol_value (sym) == vma));
 }
@@ -871,7 +883,7 @@ static char *prev_functionname;
 static unsigned int prev_line;
 
 /* We keep a list of all files that we have seen when doing a
-   dissassembly with source, so that we know how much of the file to
+   disassembly with source, so that we know how much of the file to
    display.  This can be important for inlined functions.  */
 
 struct print_file_list
@@ -999,7 +1011,7 @@ skip_to_line (struct print_file_list *p, unsigned int line,
     }
 }
 
-/* Show the line number, or the source line, in a dissassembly
+/* Show the line number, or the source line, in a disassembly
    listing.  */
 
 static void
@@ -1130,8 +1142,8 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
 typedef struct
 {
   char *buffer;
-  size_t size;
-  char *current;
+  size_t pos;
+  size_t alloc;
 } SFILE;
 
 /* sprintf to a "stream".  */
@@ -1139,39 +1151,25 @@ typedef struct
 static int
 objdump_sprintf (SFILE *f, const char *format, ...)
 {
-  char *buf;
   size_t n;
   va_list args;
 
-  va_start (args, format);
-
-  vasprintf (&buf, format, args);
-
-  if (buf == NULL)
+  while (1)
     {
+      size_t space = f->alloc - f->pos;
+  
+      va_start (args, format);
+      n = vsnprintf (f->buffer + f->pos, space, format, args);
       va_end (args);
-      fatal (_("Out of virtual memory"));
-    }
-
-  n = strlen (buf);
-
-  while ((size_t) ((f->buffer + f->size) - f->current) < n + 1)
-    {
-      size_t curroff;
 
-      curroff = f->current - f->buffer;
-      f->size *= 2;
-      f->buffer = xrealloc (f->buffer, f->size);
-      f->current = f->buffer + curroff;
+      if (space > n)
+       break;
+      
+      f->alloc = (f->alloc + n) * 2;
+      f->buffer = xrealloc (f->buffer, f->alloc);
     }
-
-  memcpy (f->current, buf, n);
-  f->current += n;
-  f->current[0] = '\0';
-
-  free (buf);
-
-  va_end (args);
+  f->pos += n;
+  
   return n;
 }
 
@@ -1231,10 +1229,15 @@ disassemble_bytes (struct disassemble_info * info,
   int skip_addr_chars;
   bfd_vma addr_offset;
   int opb = info->octets_per_byte;
+  SFILE sfile;
 
   aux = (struct objdump_disasm_info *) info->application_data;
   section = aux->sec;
 
+  sfile.alloc = 120;
+  sfile.buffer = xmalloc (sfile.alloc);
+  sfile.pos = 0;
+  
   if (insns)
     octets_per_line = 4;
   else
@@ -1299,7 +1302,6 @@ disassemble_bytes (struct disassemble_info * info,
       else
        {
          char buf[50];
-         SFILE sfile;
          int bpc = 0;
          int pb = 0;
 
@@ -1332,9 +1334,7 @@ disassemble_bytes (struct disassemble_info * info,
 
          if (insns)
            {
-             sfile.size = 120;
-             sfile.buffer = xmalloc (sfile.size);
-             sfile.current = sfile.buffer;
+             sfile.pos = 0;
              info->fprintf_func = (fprintf_ftype) objdump_sprintf;
              info->stream = (FILE *) &sfile;
              info->bytes_per_line = 0;
@@ -1359,9 +1359,8 @@ disassemble_bytes (struct disassemble_info * info,
                octets_per_line = info->bytes_per_line;
              if (octets < 0)
                {
-                 if (sfile.current != sfile.buffer)
+                 if (sfile.pos)
                    printf ("%s\n", sfile.buffer);
-                 free (sfile.buffer);
                  break;
                }
            }
@@ -1435,11 +1434,8 @@ disassemble_bytes (struct disassemble_info * info,
 
          if (! insns)
            printf ("%s", buf);
-         else
-           {
-             printf ("%s", sfile.buffer);
-             free (sfile.buffer);
-           }
+         else if (sfile.pos)
+           printf ("%s", sfile.buffer);
 
          if (prefix_addresses
              ? show_raw_insn > 0
@@ -1503,7 +1499,8 @@ disassemble_bytes (struct disassemble_info * info,
              else
                printf ("\t\t\t");
 
-             objdump_print_value (section->vma + q->address, info, TRUE);
+             objdump_print_value (section->vma - rel_offset + q->address,
+                                  info, TRUE);
 
              printf (": %s\t", q->howto->name);
 
@@ -1545,13 +1542,15 @@ disassemble_bytes (struct disassemble_info * info,
 
       addr_offset += octets / opb;
     }
+
+  free (sfile.buffer);
 }
 
 static void
 disassemble_section (bfd *abfd, asection *section, void *info)
 {
   struct disassemble_info *    pinfo = (struct disassemble_info *) info;
-  struct objdump_disasm_info * paux = (struct objdump_disasm_info *) pinfo->application_data;
+  struct objdump_disasm_info * paux;
   unsigned int                 opb = pinfo->octets_per_byte;
   bfd_byte *                   data = NULL;
   bfd_size_type                datasize = 0;
@@ -1580,14 +1579,15 @@ disassemble_section (bfd *abfd, asection *section, void *info)
     return;
 
   /* Decide which set of relocs to use.  Load them if necessary.  */
+  paux = (struct objdump_disasm_info *) pinfo->application_data;
   if (paux->dynrelbuf)
     {
       rel_pp = paux->dynrelbuf;
       rel_count = paux->dynrelcount;
       /* Dynamic reloc addresses are absolute, non-dynamic are section
-        relative.  REL_OFFSET specifies the reloc address corresponnding
+        relative.  REL_OFFSET specifies the reloc address corresponding
         to the start of this section.  */
-      rel_offset = pinfo->buffer_vma;
+      rel_offset = section->vma;
     }
   else
     {
@@ -1659,8 +1659,9 @@ disassemble_section (bfd *abfd, asection *section, void *info)
   printf (_("Disassembly of section %s:\n"), section->name);
 
   /* Find the nearest symbol forwards from our current position.  */
-  sym = find_symbol_for_address (abfd, section, section->vma + addr_offset,
-                                TRUE, &place);
+  paux->require_sec = TRUE;
+  sym = find_symbol_for_address (section->vma + addr_offset, info, &place);
+  paux->require_sec = FALSE;
 
   /* Disassemble a block of instructions up to the address associated with
      the symbol we have just found.  Then print the symbol and find the
@@ -1668,81 +1669,81 @@ disassemble_section (bfd *abfd, asection *section, void *info)
      or we have reached the end of the address range we are interested in.  */
   while (addr_offset < stop_offset)
     {
+      bfd_vma addr;
       asymbol *nextsym;
       unsigned long nextstop_offset;
       bfd_boolean insns;
 
-      if (sym != NULL
-         && bfd_asymbol_value (sym) <= section->vma + addr_offset)
+      addr = section->vma + addr_offset;
+
+      if (sym != NULL && bfd_asymbol_value (sym) <= addr)
        {
          int x;
 
          for (x = place;
               (x < sorted_symcount
-               && (bfd_asymbol_value (sorted_syms[x])
-                   <= section->vma + addr_offset));
+               && (bfd_asymbol_value (sorted_syms[x]) <= addr));
               ++x)
            continue;
 
-         pinfo->symbols = & sorted_syms[place];
+         pinfo->symbols = sorted_syms + place;
          pinfo->num_symbols = x - place;
        }
       else
-       pinfo->symbols = NULL;
+       {
+         pinfo->symbols = NULL;
+         pinfo->num_symbols = 0;
+       }
 
       if (! prefix_addresses)
        {
          pinfo->fprintf_func (pinfo->stream, "\n");
-         objdump_print_addr_with_sym (abfd, section, sym,
-                                      section->vma + addr_offset,
+         objdump_print_addr_with_sym (abfd, section, sym, addr,
                                       pinfo, FALSE);
          pinfo->fprintf_func (pinfo->stream, ":\n");
        }
 
-      if (sym != NULL
-         && bfd_asymbol_value (sym) > section->vma + addr_offset)
+      if (sym != NULL && bfd_asymbol_value (sym) > addr)
        nextsym = sym;
       else if (sym == NULL)
        nextsym = NULL;
       else
        {
+#define is_valid_next_sym(SYM) \
+  ((SYM)->section == section \
+   && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
+   && pinfo->symbol_is_valid (SYM, pinfo))
+           
          /* Search forward for the next appropriate symbol in
             SECTION.  Note that all the symbols are sorted
             together into one big array, and that some sections
             may have overlapping addresses.  */
          while (place < sorted_symcount
-                && (sorted_syms[place]->section != section
-                    || (bfd_asymbol_value (sorted_syms[place])
-                        <= bfd_asymbol_value (sym))))
+                && ! is_valid_next_sym (sorted_syms [place]))
            ++place;
+
          if (place >= sorted_symcount)
            nextsym = NULL;
          else
            nextsym = sorted_syms[place];
        }
 
-      if (sym != NULL
-         && bfd_asymbol_value (sym) > section->vma + addr_offset)
-       {
-         nextstop_offset = bfd_asymbol_value (sym) - section->vma;
-         if (nextstop_offset > stop_offset)
-           nextstop_offset = stop_offset;
-       }
+      if (sym != NULL && bfd_asymbol_value (sym) > addr)
+       nextstop_offset = bfd_asymbol_value (sym) - section->vma;
       else if (nextsym == NULL)
        nextstop_offset = stop_offset;
       else
-       {
-         nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
-         if (nextstop_offset > stop_offset)
-           nextstop_offset = stop_offset;
-       }
+       nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
+
+      if (nextstop_offset > stop_offset)
+       nextstop_offset = stop_offset;
 
       /* If a symbol is explicitly marked as being an object
         rather than a function, just dump the bytes without
         disassembling them.  */
       if (disassemble_all
          || sym == NULL
-         || bfd_asymbol_value (sym) > section->vma + addr_offset
+         || bfd_asymbol_value (sym) > addr
          || ((sym->flags & BSF_OBJECT) == 0
              && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
                  == NULL)
@@ -1789,7 +1790,7 @@ disassemble_data (bfd *abfd)
   /* Sort the symbols into section and symbol order.  */
   qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
 
-  init_disassemble_info (&disasm_info, stdout, fprintf);
+  init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
 
   disasm_info.application_data = (void *) &aux;
   aux.abfd = abfd;
@@ -1845,6 +1846,9 @@ disassemble_data (bfd *abfd)
        instead.  */
     disasm_info.endian = BFD_ENDIAN_UNKNOWN;
 
+  /* Allow the target to customize the info structure.  */
+  disassemble_init_for_target (& disasm_info);
+
   /* Pre-load the dynamic relocs if we are going
      to be dumping them along with the disassembly.  */
   if (dump_dynamic_reloc_info)
@@ -1857,12 +1861,15 @@ disassemble_data (bfd *abfd)
       if (relsize > 0)
        {
          aux.dynrelbuf = xmalloc (relsize);
-         aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, aux.dynrelbuf, dynsyms);
+         aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
+                                                           aux.dynrelbuf,
+                                                           dynsyms);
          if (aux.dynrelcount < 0)
            bfd_fatal (bfd_get_filename (abfd));
 
          /* Sort the relocs by address.  */
-         qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *), compare_relocs);
+         qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *),
+                compare_relocs);
        }
     }
 
@@ -1927,7 +1934,9 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
    using string table section STRSECT_NAME (in `strtab').  */
 
 static void
-print_section_stabs (bfd *abfd, const char *stabsect_name, unsigned *string_offset_ptr)
+print_section_stabs (bfd *abfd,
+                    const char *stabsect_name,
+                    unsigned *string_offset_ptr)
 {
   int i;
   unsigned file_string_table_offset = 0;
@@ -2400,7 +2409,9 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
 }
 
 static void
-dump_relocs_in_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
+dump_relocs_in_section (bfd *abfd,
+                       asection *section,
+                       void *dummy ATTRIBUTE_UNUSED)
 {
   arelent **relpp;
   long relcount;
@@ -2499,7 +2510,9 @@ add_include_path (const char *path)
 }
 
 static void
-adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *dummy ATTRIBUTE_UNUSED)
+adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
+                 asection *section,
+                 void *dummy ATTRIBUTE_UNUSED)
 {
   section->vma += adjust_section_vma;
   section->lma += adjust_section_vma;
@@ -2623,7 +2636,11 @@ display_bfd (bfd *abfd)
 static void
 display_file (char *filename, char *target)
 {
-  bfd *file, *arfile = NULL;
+  bfd *file;
+  bfd *arfile = NULL;
+
+  if (get_file_size (filename) < 1)
+    return;
 
   file = bfd_openr (filename, target);
   if (file == NULL)
This page took 0.060386 seconds and 4 git commands to generate.