libctf: fix a number of build problems found on Solaris and NetBSD
[deliverable/binutils-gdb.git] / binutils / objdump.c
index ab091c10d4bfcffef991026ab2b9469d2362965c..b9d08f70f95c4f9e0f0c19c35b7cb3710601080f 100644 (file)
@@ -56,6 +56,9 @@
 #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"
@@ -98,6 +101,11 @@ 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 */
@@ -224,7 +232,12 @@ 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\
+                           Display DWARF info in the file\n"));
+#ifdef HAVE_LIBCTF
+  fprintf (stream, _("\
+  --ctf=SECTION            Display CTF info from SECTION\n"));
+#endif
+  fprintf (stream, _("\
   -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\
@@ -273,7 +286,11 @@ 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\n"));
+      \n"));
+#ifdef HAVE_LIBCTF
+      fprintf (stream, _("\
+      --ctf-parent=SECTION     Use SECTION as the CTF parent\n\n"));
+#endif
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
@@ -308,6 +325,10 @@ enum option_values
     OPTION_DWARF_START,
     OPTION_RECURSE_LIMIT,
     OPTION_NO_RECURSE_LIMIT,
+#ifdef HAVE_LIBCTF
+    OPTION_CTF,
+    OPTION_CTF_PARENT,
+#endif
     OPTION_INLINES
   };
 
@@ -351,6 +372,10 @@ static struct option long_options[]=
   {"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},
@@ -382,10 +407,10 @@ nonfatal (const char *msg)
 static const char *
 sanitize_string (const char * in)
 {
-  static char *        buffer = NULL;
-  static unsigned int  buffer_len = 0;
-  const char *         original = in;
-  char *               out;
+  static char *  buffer = NULL;
+  static size_t  buffer_len = 0;
+  const char *   original = in;
+  char *         out;
 
   /* Paranoia.  */
   if (in == NULL)
@@ -1946,7 +1971,8 @@ disassemble_bytes (struct disassemble_info * inf,
              inf->stream = &sfile;
              inf->bytes_per_line = 0;
              inf->bytes_per_chunk = 0;
-             inf->flags = disassemble_all ? DISASSEMBLE_DATA : 0;
+             inf->flags = ((disassemble_all ? DISASSEMBLE_DATA : 0)
+                           | (wide_output ? WIDE_OUTPUT : 0));
              if (machine)
                inf->flags |= USER_SPECIFIED_MACHINE_TYPE;
 
@@ -1991,6 +2017,7 @@ disassemble_bytes (struct disassemble_info * inf,
                   disassembling code of course, and when -D is in effect.  */
                inf->stop_vma = section->vma + stop_offset;
 
+             inf->stop_offset = stop_offset;
              octets = (*disassemble_fn) (section->vma + addr_offset, inf);
 
              inf->stop_vma = 0;
@@ -2679,6 +2706,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   bfd *abfd = (bfd *) file;
   bfd_byte *contents;
   bfd_size_type amt;
+  size_t alloced;
 
   if (section->start != NULL)
     {
@@ -2694,8 +2722,9 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   section->address = bfd_get_section_vma (abfd, sec);
   section->user_data = sec;
   section->size = bfd_get_section_size (sec);
-  amt = section->size + 1;
-  if (amt == 0 || amt > bfd_get_file_size (abfd))
+  /* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */
+  alloced = amt = section->size + 1;
+  if (alloced != amt || alloced == 0)
     {
       section->start = NULL;
       free_debug_section (debug);
@@ -2704,7 +2733,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
              (unsigned long long) section->size);
       return FALSE;
     }
-  section->start = contents = malloc (amt);
+  section->start = contents = malloc (alloced);
   if (section->start == NULL
       || !bfd_get_full_section_contents (abfd, sec, &contents))
     {
@@ -2967,7 +2996,8 @@ dump_dwarf (bfd *abfd)
    it.  Return NULL on failure.   */
 
 static bfd_byte *
-read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
+read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr,
+                   bfd_size_type *entsize_ptr)
 {
   asection *stabsect;
   bfd_byte *contents;
@@ -2991,6 +3021,8 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
     }
 
   *size_ptr = bfd_section_size (abfd, stabsect);
+  if (entsize_ptr)
+    *entsize_ptr = stabsect->entsize;
 
   return contents;
 }
@@ -3114,11 +3146,11 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
     {
       if (strtab == NULL)
        strtab = read_section_stabs (abfd, sought->string_section_name,
-                                    &stabstr_size);
+                                    &stabstr_size, NULL);
 
       if (strtab)
        {
-         stabs = read_section_stabs (abfd, section->name, &stab_size);
+         stabs = read_section_stabs (abfd, section->name, &stab_size, NULL);
          if (stabs)
            print_section_stabs (abfd, section->name, &sought->string_offset);
        }
@@ -3180,8 +3212,141 @@ dump_bfd_header (bfd *abfd)
   bfd_printf_vma (abfd, abfd->start_address);
   printf ("\n");
 }
-
 \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.  */
+
+static char *
+dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
+                      char *s, void *arg)
+{
+  char *spaces = arg;
+  char *new_s;
+
+  if (asprintf (&new_s, "%s%s", spaces, 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)
+{
+  ctf_sect_t ctfsect;
+
+  ctfsect.cts_name = name;
+  ctfsect.cts_entsize = 1;
+  ctfsect.cts_size = size;
+  ctfsect.cts_data = data;
+
+  return ctfsect;
+}
+
+/* Dump one CTF archive member.  */
+
+static int
+dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
+{
+  ctf_file_t *parent = (ctf_file_t *) arg;
+  const char *things[] = {"Labels", "Data objects", "Function objects",
+                         "Variables", "Types", "Strings", ""};
+  const char **thing;
+  size_t i;
+
+  /* Only print out the name of non-default-named archive members.
+     The name .ctf appears everywhere, even for things that aren't
+     really archives, so printing it out is liable to be confusing.  */
+  if (strcmp (name, ".ctf") != 0)
+    printf (_("\nCTF archive member: %s:\n"), sanitize_string (name));
+
+  ctf_import (ctf, parent);
+  for (i = 1, thing = things; *thing[0]; thing++, i++)
+    {
+      ctf_dump_state_t *s = NULL;
+      char *item;
+
+      printf ("\n  %s:\n", *thing);
+      while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
+                              (void *) "    ")) != NULL)
+       {
+         printf ("%s\n", item);
+         free (item);
+       }
+
+      if (ctf_errno (ctf))
+       {
+         non_fatal (_("Iteration failed: %s, %s\n"), *thing,
+                  ctf_errmsg (ctf_errno (ctf)));
+         break;
+       }
+    }
+  return 0;
+}
+
+/* Dump the CTF debugging information.  */
+
+static void
+dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
+{
+  ctf_archive_t *ctfa, *parenta = NULL;
+  bfd_byte *ctfdata, *parentdata = NULL;
+  bfd_size_type ctfsize, parentsize;
+  ctf_sect_t ctfsect;
+  ctf_file_t *parent = NULL;
+  int err;
+
+  if ((ctfdata = read_section_stabs (abfd, sect_name, &ctfsize, NULL)) == NULL)
+      bfd_fatal (bfd_get_filename (abfd));
+
+  if (parent_name
+      && (parentdata = read_section_stabs (abfd, parent_name, &parentsize,
+                                          NULL)) == NULL)
+      bfd_fatal (bfd_get_filename (abfd));
+
+  /* Load the CTF file and dump it.  */
+
+  ctfsect = make_ctfsect (sect_name, ctfdata, ctfsize);
+  if ((ctfa = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL)
+    {
+      non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err));
+      bfd_fatal (bfd_get_filename (abfd));
+    }
+
+  if (parentdata)
+    {
+      ctfsect = make_ctfsect (parent_name, parentdata, parentsize);
+      if ((parenta = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL)
+       {
+         non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err));
+         bfd_fatal (bfd_get_filename (abfd));
+       }
+
+      /* Assume that the applicable parent archive member is the default one.
+        (This is what all known implementations are expected to do, if they
+        put CTFs and their parents in archives together.)  */
+      if ((parent = ctf_arc_open_by_name (parenta, NULL, &err)) == NULL)
+       {
+         non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err));
+         bfd_fatal (bfd_get_filename (abfd));
+       }
+    }
+
+  printf (_("Contents of CTF section %s:\n"), sanitize_string (sect_name));
+
+  ctf_archive_iter (ctfa, dump_ctf_archive_member, parent);
+  ctf_file_close (parent);
+  ctf_close (ctfa);
+  ctf_close (parenta);
+  free (parentdata);
+  free (ctfdata);
+}
+#endif /* HAVE_LIBCTF */
+
 static void
 dump_bfd_private_header (bfd *abfd)
 {
@@ -3629,7 +3794,7 @@ dump_relocs_in_section (bfd *abfd,
                        asection *section,
                        void *dummy ATTRIBUTE_UNUSED)
 {
-  arelent **relpp;
+  arelent **relpp = NULL;
   long relcount;
   long relsize;
 
@@ -3640,47 +3805,28 @@ dump_relocs_in_section (bfd *abfd,
       || ((section->flags & SEC_RELOC) == 0))
     return;
 
-  relsize = bfd_get_reloc_upper_bound (abfd, section);
-  if (relsize < 0)
-    bfd_fatal (bfd_get_filename (abfd));
-
   printf ("RELOCATION RECORDS FOR [%s]:", sanitize_string (section->name));
 
+  relsize = bfd_get_reloc_upper_bound (abfd, section);
   if (relsize == 0)
     {
       printf (" (none)\n\n");
       return;
     }
 
-  if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0
-      && (/* Check that the size of the relocs is reasonable.  Note that some
-            file formats, eg aout, can have relocs whose internal size is
-            larger than their external size, thus we check the size divided
-            by four against the file size.  See PR 23931 for an example of
-            this.  */
-         ((ufile_ptr) (relsize / 4) > bfd_get_file_size (abfd))
-         /* Also check the section's reloc count since if this is negative
-            (or very large) the computation in bfd_get_reloc_upper_bound
-            may have resulted in returning a small, positive integer.
-            See PR 22508 for a reproducer.
-
-            Note - we check against file size rather than section size as
-            it is possible for there to be more relocs that apply to a
-            section than there are bytes in that section.  */
-         || (section->reloc_count > bfd_get_file_size (abfd))))
+  if (relsize < 0)
+    relcount = relsize;
+  else
     {
-      printf (" (too many: %#x relocs)\n", section->reloc_count);
-      bfd_set_error (bfd_error_file_truncated);
-      bfd_fatal (bfd_get_filename (abfd));
+      relpp = (arelent **) xmalloc (relsize);
+      relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
     }
 
-  relpp = (arelent **) xmalloc (relsize);
-  relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
-
   if (relcount < 0)
     {
       printf ("\n");
-      non_fatal (_("failed to read relocs in: %s"), sanitize_string (bfd_get_filename (abfd)));
+      non_fatal (_("failed to read relocs in: %s"),
+                sanitize_string (bfd_get_filename (abfd)));
       bfd_fatal (_("error message was"));
     }
   else if (relcount == 0)
@@ -3765,11 +3911,25 @@ adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
     }
 }
 
+/* Return the sign-extended form of an ARCH_SIZE sized VMA.  */
+
+static bfd_vma
+sign_extend_address (bfd *abfd ATTRIBUTE_UNUSED,
+                    bfd_vma vma,
+                    unsigned arch_size)
+{
+  bfd_vma mask;
+  mask = (bfd_vma) 1 << (arch_size - 1);
+  return (((vma & ((mask << 1) - 1)) ^ mask) - mask);
+}
+
 /* Dump selected contents of ABFD.  */
 
 static void
 dump_bfd (bfd *abfd, bfd_boolean is_mainfile)
 {
+  const struct elf_backend_data * bed;
+
   if (bfd_big_endian (abfd))
     byte_get = byte_get_big_endian;
   else if (bfd_little_endian (abfd))
@@ -3800,6 +3960,18 @@ dump_bfd (bfd *abfd, bfd_boolean is_mainfile)
        }
     }
 
+  /* Adjust user-specified start and stop limits for targets that use
+     signed addresses.  */
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+      && (bed = get_elf_backend_data (abfd)) != NULL
+      && bed->sign_extend_vma)
+    {
+      start_address = sign_extend_address (abfd, start_address,
+                                          bed->s->arch_size);
+      stop_address = sign_extend_address (abfd, stop_address,
+                                         bed->s->arch_size);
+    }
+
   /* If we are adjusting section VMA's, change them all now.  Changing
      the BFD information is a hack.  However, we must do it, or
      bfd_find_nearest_line will not do the right thing.  */
@@ -3885,6 +4057,10 @@ 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)
@@ -4324,6 +4500,16 @@ 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);
+          seenflag = TRUE;
+          break;
+       case OPTION_CTF_PARENT:
+         dump_ctf_parent_name = xstrdup (optarg);
+         break;
+#endif
        case 'G':
          dump_stab_section_info = TRUE;
          seenflag = TRUE;
@@ -4383,7 +4569,10 @@ main (int argc, char **argv)
     }
 
   free_only_list ();
-
+#ifdef HAVE_LIBCTF
+  free (dump_ctf_section_name);
+  free (dump_ctf_parent_name);
+#endif
   END_PROGRESS (program_name);
 
   return exit_status;
This page took 0.029812 seconds and 4 git commands to generate.