PR25002, ld/ldelf.c missing safe-ctype.h include
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 382ba35855cf9e06cba880c8d35cd8127d66b1b3..00541cbec5ffbca109751d7d851ca0780b86f8eb 100644 (file)
@@ -56,9 +56,7 @@
 #include "bucomm.h"
 #include "elfcomm.h"
 #include "dwarf.h"
-#ifdef HAVE_LIBCTF
 #include "ctf-api.h"
-#endif
 #include "getopt.h"
 #include "safe-ctype.h"
 #include "dis-asm.h"
@@ -101,11 +99,9 @@ static bfd_boolean with_source_code;        /* -S */
 static int show_raw_insn;              /* --show-raw-insn */
 static int dump_dwarf_section_info;    /* --dwarf */
 static int dump_stab_section_info;     /* --stabs */
-#ifdef HAVE_LIBCTF
 static int dump_ctf_section_info;       /* --ctf */
 static char *dump_ctf_section_name;
 static char *dump_ctf_parent_name;     /* --ctf-parent */
-#endif
 static int do_demangle;                        /* -C, --demangle */
 static bfd_boolean disassemble;                /* -d */
 static bfd_boolean disassemble_all;    /* -D */
@@ -127,6 +123,7 @@ static int prefix_strip;            /* --prefix-strip */
 static size_t prefix_length;
 static bfd_boolean unwind_inlines;     /* --inlines.  */
 static const char * disasm_sym;                /* Disassembly start symbol.  */
+static const char * source_comment;     /* --source_comment.  */
 
 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
 
@@ -196,8 +193,6 @@ static bfd_size_type stab_size;
 static bfd_byte *strtab;
 static bfd_size_type stabstr_size;
 
-static bfd_boolean is_relocatable = FALSE;
-
 /* Handlers for -P/--private.  */
 static const struct objdump_private_desc * const objdump_private_vectors[] =
   {
@@ -223,6 +218,7 @@ usage (FILE *stream, int status)
   -D, --disassemble-all    Display assembler contents of all sections\n\
       --disassemble=<sym>  Display assembler contents from <sym>\n\
   -S, --source             Intermix source code with disassembly\n\
+      --source-comment[=<txt>] Prefix lines of source code with <txt>\n\
   -s, --full-contents      Display the full contents of all sections requested\n\
   -g, --debugging          Display debug information in object file\n\
   -e, --debugging-tags     Display debug information using ctags style\n\
@@ -232,12 +228,8 @@ usage (FILE *stream, int status)
           =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
           =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
           =addr,=cu_index,=links,=follow-links]\n\
-                           Display DWARF info in the file\n"));
-#ifdef HAVE_LIBCTF
-  fprintf (stream, _("\
-  --ctf=SECTION            Display CTF info from SECTION\n"));
-#endif
-  fprintf (stream, _("\
+                           Display DWARF info in the file\n\
+  --ctf=SECTION            Display CTF info from SECTION\n\
   -t, --syms               Display the contents of the symbol table(s)\n\
   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
   -r, --reloc              Display the relocation entries in the file\n\
@@ -286,11 +278,8 @@ usage (FILE *stream, int status)
       --dwarf-start=N        Display DIEs starting with N, at the same depth\n\
                              or deeper\n\
       --dwarf-check          Make additional dwarf internal consistency checks.\
-      \n"));
-#ifdef HAVE_LIBCTF
-      fprintf (stream, _("\
+      \n\
       --ctf-parent=SECTION     Use SECTION as the CTF parent\n\n"));
-#endif
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
@@ -325,11 +314,10 @@ enum option_values
     OPTION_DWARF_START,
     OPTION_RECURSE_LIMIT,
     OPTION_NO_RECURSE_LIMIT,
-#ifdef HAVE_LIBCTF
+    OPTION_INLINES,
+    OPTION_SOURCE_COMMENT,
     OPTION_CTF,
-    OPTION_CTF_PARENT,
-#endif
-    OPTION_INLINES
+    OPTION_CTF_PARENT
   };
 
 static struct option long_options[]=
@@ -369,13 +357,12 @@ 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'},
+  {"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT},
   {"special-syms", no_argument, &dump_special_syms, 1},
   {"include", required_argument, NULL, 'I'},
   {"dwarf", optional_argument, NULL, OPTION_DWARF},
-#ifdef HAVE_LIBCTF
   {"ctf", required_argument, NULL, OPTION_CTF},
   {"ctf-parent", required_argument, NULL, OPTION_CTF_PARENT},
-#endif
   {"stabs", no_argument, NULL, 'G'},
   {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
   {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
@@ -719,7 +706,26 @@ slurp_symtab (bfd *abfd)
       bfd_fatal (_("error message was"));
     }
   if (storage)
-    sy = (asymbol **) xmalloc (storage);
+    {
+      off_t filesize = bfd_get_file_size (abfd);
+
+      /* qv PR 24707.  */
+      if (filesize > 0
+         && filesize < storage
+         /* The MMO file format supports its own special compression
+            technique, so its sections can be larger than the file size.  */
+         && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)    
+       {
+         bfd_nonfatal_message (bfd_get_filename (abfd), abfd, NULL,
+                               _("error: symbol table size (%#lx) is larger than filesize (%#lx)"),
+                       storage, (long) filesize);
+         exit_status = 1;
+         symcount = 0;
+         return NULL;
+       }
+
+      sy = (asymbol **) xmalloc (storage);
+    }
 
   symcount = bfd_canonicalize_symtab (abfd, sy);
   if (symcount < 0)
@@ -1592,8 +1598,10 @@ print_line (struct print_file_list *p, unsigned int linenum)
   if (linenum >= p->maxline)
     return;
   l = p->linemap [linenum];
-  /* Test fwrite return value to quiet glibc warning.  */
+  if (source_comment != NULL && strlen (l) > 0)
+    printf ("%s", source_comment);
   len = strcspn (l, "\n\r");
+  /* Test fwrite return value to quiet glibc warning.  */
   if (len == 0 || fwrite (l, len, 1, stdout) == 1)
     putchar ('\n');
 }
@@ -1828,6 +1836,12 @@ objdump_sprintf (SFILE *f, const char *format, ...)
 
 #define DEFAULT_SKIP_ZEROES_AT_END 3
 
+static int
+null_print (const void * stream ATTRIBUTE_UNUSED, const char * format ATTRIBUTE_UNUSED, ...)
+{
+  return 1;
+}
+
 /* Disassemble some data in memory between given values.  */
 
 static void
@@ -1895,10 +1909,7 @@ disassemble_bytes (struct disassemble_info * inf,
     {
       bfd_vma z;
       bfd_boolean need_nl = FALSE;
-      int previous_octets;
 
-      /* Remember the length of the previous instruction.  */
-      previous_octets = octets;
       octets = 0;
 
       /* Make sure we don't use relocs from previous instructions.  */
@@ -1982,26 +1993,46 @@ disassemble_bytes (struct disassemble_info * inf,
                  && *relppp < relppend)
                {
                  bfd_signed_vma distance_to_rel;
+                 int insn_size = 0;
+                 int max_reloc_offset
+                   = aux->abfd->arch_info->max_reloc_offset_into_insn;
 
-                 distance_to_rel = (**relppp)->address
-                   - (rel_offset + addr_offset);
+                 distance_to_rel = ((**relppp)->address - rel_offset
+                                    - addr_offset);
+
+                 if (distance_to_rel > 0
+                     && (max_reloc_offset < 0
+                         || distance_to_rel <= max_reloc_offset))
+                   {
+                     /* This reloc *might* apply to the current insn,
+                        starting somewhere inside it.  Discover the length
+                        of the current insn so that the check below will
+                        work.  */
+                     if (insn_width)
+                       insn_size = insn_width;
+                     else
+                       {
+                         /* We find the length by calling the dissassembler
+                            function with a dummy print handler.  This should
+                            work unless the disassembler is not expecting to
+                            be called multiple times for the same address.
+
+                            This does mean disassembling the instruction
+                            twice, but we only do this when there is a high
+                            probability that there is a reloc that will
+                            affect the instruction.  */
+                         inf->fprintf_func = (fprintf_ftype) null_print;
+                         insn_size = disassemble_fn (section->vma
+                                                     + addr_offset, inf);
+                         inf->fprintf_func = (fprintf_ftype) objdump_sprintf;
+                       }
+                   }
 
                  /* Check to see if the current reloc is associated with
                     the instruction that we are about to disassemble.  */
                  if (distance_to_rel == 0
-                     /* FIXME: This is wrong.  We are trying to catch
-                        relocs that are addressed part way through the
-                        current instruction, as might happen with a packed
-                        VLIW instruction.  Unfortunately we do not know the
-                        length of the current instruction since we have not
-                        disassembled it yet.  Instead we take a guess based
-                        upon the length of the previous instruction.  The
-                        proper solution is to have a new target-specific
-                        disassembler function which just returns the length
-                        of an instruction at a given address without trying
-                        to display its disassembly. */
                      || (distance_to_rel > 0
-                         && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb)))
+                         && distance_to_rel < insn_size / (int) opb))
                    {
                      inf->flags |= INSN_HAS_RELOC;
                      aux->reloc = **relppp;
@@ -2745,7 +2776,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   /* Ensure any string section has a terminating NUL.  */
   section->start[section->size] = 0;
 
-  if (is_relocatable && debug_displays [debug].relocate)
+  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
+      && debug_displays [debug].relocate)
     {
       long         reloc_size;
       bfd_boolean  ret;
@@ -2939,8 +2971,6 @@ dump_dwarf (bfd *abfd)
       return;
     }
 
-  is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
-
   eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
 
   switch (bfd_get_arch (abfd))
@@ -3214,7 +3244,6 @@ dump_bfd_header (bfd *abfd)
 }
 \f
 
-#ifdef HAVE_LIBCTF
 /* Formatting callback function passed to ctf_dump.  Returns either the pointer
    it is passed, or a pointer to newly-allocated storage, in which case
    dump_ctf() will free it when it no longer needs it.  */
@@ -3223,16 +3252,15 @@ static char *
 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
                       char *s, void *arg)
 {
-  char *spaces = arg;
+  const char *blanks = arg;
   char *new_s;
 
-  if (asprintf (&new_s, "%s%s", spaces, s) < 0)
+  if (asprintf (&new_s, "%s%s", blanks, s) < 0)
     return s;
   return new_s;
 }
 
 /* Make a ctfsect suitable for ctf_bfdopen_ctfsect().  */
-
 static ctf_sect_t
 make_ctfsect (const char *name, bfd_byte *data,
              bfd_size_type size)
@@ -3240,10 +3268,7 @@ make_ctfsect (const char *name, bfd_byte *data,
   ctf_sect_t ctfsect;
 
   ctfsect.cts_name = name;
-  ctfsect.cts_type = SHT_PROGBITS;
-  ctfsect.cts_flags = 0;
   ctfsect.cts_entsize = 1;
-  ctfsect.cts_offset = 0;
   ctfsect.cts_size = size;
   ctfsect.cts_data = data;
 
@@ -3348,8 +3373,8 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
   free (parentdata);
   free (ctfdata);
 }
-#endif /* HAVE_LIBCTF */
 
+\f
 static void
 dump_bfd_private_header (bfd *abfd)
 {
@@ -4060,10 +4085,8 @@ dump_bfd (bfd *abfd, bfd_boolean is_mainfile)
     dump_symbols (abfd, TRUE);
   if (dump_dwarf_section_info)
     dump_dwarf (abfd);
-#ifdef HAVE_LIBCTF
   if (dump_ctf_section_info)
     dump_ctf (abfd, dump_ctf_section_name, dump_ctf_parent_name);
-#endif
   if (dump_stab_section_info)
     dump_stabs (abfd);
   if (dump_reloc_info && ! disassemble)
@@ -4461,6 +4484,15 @@ main (int argc, char **argv)
          with_source_code = TRUE;
          seenflag = TRUE;
          break;
+       case OPTION_SOURCE_COMMENT:
+         disassemble = TRUE;
+         with_source_code = TRUE;
+         seenflag = TRUE;
+         if (optarg)
+           source_comment = xstrdup (sanitize_string (optarg));
+         else
+           source_comment = xstrdup ("# ");
+         break;
        case 'g':
          dump_debugging = 1;
          seenflag = TRUE;
@@ -4503,7 +4535,6 @@ main (int argc, char **argv)
        case OPTION_DWARF_CHECK:
          dwarf_check = TRUE;
          break;
-#ifdef HAVE_LIBCTF
         case OPTION_CTF:
           dump_ctf_section_info = TRUE;
           dump_ctf_section_name = xstrdup (optarg);
@@ -4512,7 +4543,6 @@ main (int argc, char **argv)
        case OPTION_CTF_PARENT:
          dump_ctf_parent_name = xstrdup (optarg);
          break;
-#endif
        case 'G':
          dump_stab_section_info = TRUE;
          seenflag = TRUE;
@@ -4572,10 +4602,10 @@ main (int argc, char **argv)
     }
 
   free_only_list ();
-#ifdef HAVE_LIBCTF
   free (dump_ctf_section_name);
   free (dump_ctf_parent_name);
-#endif
+  free ((void *) source_comment);
+
   END_PROGRESS (program_name);
 
   return exit_status;
This page took 0.027433 seconds and 4 git commands to generate.