Add support for debuginfod to the binutils (disable by default, enabled via a configu...
[deliverable/binutils-gdb.git] / binutils / objdump.c
index fffbcf876db704fbb9f5ba151a336e0dfddd329e..27b0fb6039404f8a3fe4266d155bbb47b4bce7f6 100644 (file)
@@ -1,5 +1,5 @@
 /* objdump.c -- dump information about an object file.
-   Copyright (C) 1990-2019 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -123,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;
 
@@ -146,7 +147,6 @@ static int include_path_count;
 struct objdump_disasm_info
 {
   bfd *              abfd;
-  asection *         sec;
   bfd_boolean        require_sec;
   arelent **         dynrelbuf;
   long               dynrelcount;
@@ -217,6 +217,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\
@@ -262,7 +263,7 @@ usage (FILE *stream, int status)
   -w, --wide                     Format output for more than 80 columns\n\
   -z, --disassemble-zeroes       Do not skip blocks of zeroes when disassembling\n\
       --start-address=ADDR       Only process data whose address is >= ADDR\n\
-      --stop-address=ADDR        Only process data whose address is <= ADDR\n\
+      --stop-address=ADDR        Only process data whose address is < ADDR\n\
       --prefix-addresses         Print complete address alongside disassembly\n\
       --[no-]show-raw-insn       Display hex alongside symbolic disassembly\n\
       --insn-width=WIDTH         Display WIDTH bytes on a single line for -d\n\
@@ -313,6 +314,7 @@ enum option_values
     OPTION_RECURSE_LIMIT,
     OPTION_NO_RECURSE_LIMIT,
     OPTION_INLINES,
+    OPTION_SOURCE_COMMENT,
     OPTION_CTF,
     OPTION_CTF_PARENT
   };
@@ -354,6 +356,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'},
+  {"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},
@@ -528,7 +531,7 @@ static void
 dump_section_header (bfd *abfd, asection *section, void *data)
 {
   char *comma = "";
-  unsigned int opb = bfd_octets_per_byte (abfd);
+  unsigned int opb = bfd_octets_per_byte (abfd, section);
   int longest_section_name = *((int *) data);
 
   /* Ignore linker created section.  See elfNN_ia64_object_p in
@@ -541,13 +544,13 @@ dump_section_header (bfd *abfd, asection *section, void *data)
     return;
 
   printf ("%3d %-*s %08lx  ", section->index, longest_section_name,
-         sanitize_string (bfd_get_section_name (abfd, section)),
-         (unsigned long) bfd_section_size (abfd, section) / opb);
-  bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
+         sanitize_string (bfd_section_name (section)),
+         (unsigned long) bfd_section_size (section) / opb);
+  bfd_printf_vma (abfd, bfd_section_vma (section));
   printf ("  ");
   bfd_printf_vma (abfd, section->lma);
   printf ("  %08lx  2**%u", (unsigned long) section->filepos,
-         bfd_get_section_alignment (abfd, section));
+         bfd_section_alignment (section));
   if (! wide_output)
     printf ("\n                ");
   printf ("  ");
@@ -580,7 +583,10 @@ dump_section_header (bfd *abfd, asection *section, void *data)
       PF (SEC_COFF_NOREAD, "NOREAD");
     }
   else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    PF (SEC_ELF_PURECODE, "PURECODE");
+    {
+      PF (SEC_ELF_OCTETS, "OCTETS");
+      PF (SEC_ELF_PURECODE, "PURECODE");
+    }
   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
   PF (SEC_GROUP, "GROUP");
   if (bfd_get_arch (abfd) == bfd_arch_mep)
@@ -627,7 +633,8 @@ dump_section_header (bfd *abfd, asection *section, void *data)
    DATA which contains the string length of the longest section name.  */
 
 static void
-find_longest_section_name (bfd *abfd, asection *section, void *data)
+find_longest_section_name (bfd *abfd ATTRIBUTE_UNUSED,
+                          asection *section, void *data)
 {
   int *longest_so_far = (int *) data;
   const char *name;
@@ -641,7 +648,7 @@ find_longest_section_name (bfd *abfd, asection *section, void *data)
   if (! process_section_p (section))
     return;
 
-  name = bfd_get_section_name (abfd, section);
+  name = bfd_section_name (section);
   len = (int) strlen (name);
   if (len > *longest_so_far)
     *longest_so_far = len;
@@ -796,6 +803,8 @@ remove_useless_symbols (asymbol **symbols, long count)
   return out_ptr - symbols;
 }
 
+static const asection *compare_section;
+
 /* Sort symbols into value order.  */
 
 static int
@@ -807,8 +816,7 @@ compare_symbols (const void *ap, const void *bp)
   const char *bn;
   size_t anl;
   size_t bnl;
-  bfd_boolean af;
-  bfd_boolean bf;
+  bfd_boolean as, af, bs, bf;
   flagword aflags;
   flagword bflags;
 
@@ -817,10 +825,16 @@ compare_symbols (const void *ap, const void *bp)
   else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
     return -1;
 
-  if (a->section > b->section)
-    return 1;
-  else if (a->section < b->section)
+  /* Prefer symbols from the section currently being disassembled.
+     Don't sort symbols from other sections by section, since there
+     isn't much reason to prefer one section over another otherwise.
+     See sym_ok comment for why we compare by section name.  */
+  as = strcmp (compare_section->name, a->section->name) == 0;
+  bs = strcmp (compare_section->name, b->section->name) == 0;
+  if (as && !bs)
     return -1;
+  if (!as && bs)
+    return 1;
 
   an = bfd_asymbol_name (a);
   bn = bfd_asymbol_name (b);
@@ -846,7 +860,8 @@ compare_symbols (const void *ap, const void *bp)
 
 #define file_symbol(s, sn, snl)                        \
   (((s)->flags & BSF_FILE) != 0                        \
-   || ((sn)[(snl) - 2] == '.'                  \
+   || ((snl) > 2                               \
+       && (sn)[(snl) - 2] == '.'               \
        && ((sn)[(snl) - 1] == 'o'              \
           || (sn)[(snl) - 1] == 'a')))
 
@@ -858,8 +873,8 @@ compare_symbols (const void *ap, const void *bp)
   if (! af && bf)
     return -1;
 
-  /* Try to sort global symbols before local symbols before function
-     symbols before debugging symbols.  */
+  /* Sort function and object symbols before global symbols before
+     local symbols before section symbols before debugging symbols.  */
 
   aflags = a->flags;
   bflags = b->flags;
@@ -871,6 +886,13 @@ compare_symbols (const void *ap, const void *bp)
       else
        return -1;
     }
+  if ((aflags & BSF_SECTION_SYM) != (bflags & BSF_SECTION_SYM))
+    {
+      if ((aflags & BSF_SECTION_SYM) != 0)
+       return 1;
+      else
+       return -1;
+    }
   if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
     {
       if ((aflags & BSF_FUNCTION) != 0)
@@ -878,6 +900,13 @@ compare_symbols (const void *ap, const void *bp)
       else
        return 1;
     }
+  if ((aflags & BSF_OBJECT) != (bflags & BSF_OBJECT))
+    {
+      if ((aflags & BSF_OBJECT) != 0)
+       return -1;
+      else
+       return 1;
+    }
   if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
     {
       if ((aflags & BSF_LOCAL) != 0)
@@ -991,7 +1020,7 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
   if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
     version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
 
-  if (bfd_is_und_section (bfd_get_section (sym)))
+  if (bfd_is_und_section (bfd_asymbol_section (sym)))
     hidden = TRUE;
 
   name = sanitize_string (name);
@@ -1030,8 +1059,8 @@ sym_ok (bfd_boolean               want_section,
         debug info file, whilst the section we want is in a normal file.
         So the section pointers will be different, but the section names
         will be the same.  */
-      if (strcmp (bfd_section_name (abfd, sorted_syms[place]->section),
-                 bfd_section_name (abfd, sec)) != 0)
+      if (strcmp (bfd_section_name (sorted_syms[place]->section),
+                 bfd_section_name (sec)) != 0)
        return FALSE;
     }
 
@@ -1070,7 +1099,7 @@ find_symbol_for_address (bfd_vma vma,
 
   aux = (struct objdump_disasm_info *) inf->application_data;
   abfd = aux->abfd;
-  sec = aux->sec;
+  sec = inf->section;
   opb = inf->octets_per_byte;
 
   /* Perform a binary search looking for the closest symbol to the
@@ -1095,14 +1124,11 @@ find_symbol_for_address (bfd_vma vma,
 
   /* The symbol we want is now in min, the low end of the range we
      were searching.  If there are several symbols with the same
-     value, we want the first (non-section/non-debugging) one.  */
+     value, we want the first one.  */
   thisplace = min;
   while (thisplace > 0
         && (bfd_asymbol_value (sorted_syms[thisplace])
-            == bfd_asymbol_value (sorted_syms[thisplace - 1]))
-        && ((sorted_syms[thisplace - 1]->flags
-             & (BSF_SECTION_SYM | BSF_DEBUGGING)) == 0)
-        )
+            == bfd_asymbol_value (sorted_syms[thisplace - 1])))
     --thisplace;
 
   /* Prefer a symbol in the current section if we have multple symbols
@@ -1137,9 +1163,9 @@ find_symbol_for_address (bfd_vma vma,
      Also give the target a chance to reject symbols.  */
   want_section = (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) / opb)));
+                     && vma >= bfd_section_vma (sec)
+                     && vma < (bfd_section_vma (sec)
+                               + bfd_section_size (sec) / opb)));
   
   if (! sym_ok (want_section, abfd, thisplace, sec, inf))
     {
@@ -1263,8 +1289,8 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
       bfd_vma secaddr;
 
       (*inf->fprintf_func) (inf->stream, " <%s",
-                           sanitize_string (bfd_get_section_name (abfd, sec)));
-      secaddr = bfd_get_section_vma (abfd, sec);
+                           sanitize_string (bfd_section_name (sec)));
+      secaddr = bfd_section_vma (sec);
       if (vma < secaddr)
        {
          (*inf->fprintf_func) (inf->stream, "-0x");
@@ -1334,7 +1360,8 @@ objdump_print_addr (bfd_vma vma,
 
       if (display_file_offsets)
        inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
-                          (long int)(aux->sec->filepos + (vma - aux->sec->vma)));
+                          (long int) (inf->section->filepos
+                                      + (vma - inf->section->vma)));
       return;
     }
 
@@ -1347,14 +1374,14 @@ objdump_print_addr (bfd_vma vma,
       /* Adjust the vma to the reloc.  */
       vma += bfd_asymbol_value (sym);
 
-      if (bfd_is_und_section (bfd_get_section (sym)))
+      if (bfd_is_und_section (bfd_asymbol_section (sym)))
        skip_find = TRUE;
     }
 
   if (!skip_find)
     sym = find_symbol_for_address (vma, inf, NULL);
 
-  objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, inf,
+  objdump_print_addr_with_sym (aux->abfd, inf->section, sym, vma, inf,
                               skip_zeroes);
 }
 
@@ -1594,8 +1621,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');
 }
@@ -1830,6 +1859,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
@@ -1855,7 +1890,7 @@ disassemble_bytes (struct disassemble_info * inf,
   SFILE sfile;
 
   aux = (struct objdump_disasm_info *) inf->application_data;
-  section = aux->sec;
+  section = inf->section;
 
   sfile.alloc = 120;
   sfile.buffer = (char *) xmalloc (sfile.alloc);
@@ -1897,10 +1932,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.  */
@@ -1984,26 +2016,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;
@@ -2205,8 +2257,8 @@ disassemble_bytes (struct disassemble_info * inf,
                    {
                      asection *sym_sec;
 
-                     sym_sec = bfd_get_section (*q->sym_ptr_ptr);
-                     sym_name = bfd_get_section_name (aux->abfd, sym_sec);
+                     sym_sec = bfd_asymbol_section (*q->sym_ptr_ptr);
+                     sym_name = bfd_section_name (sym_sec);
                      if (sym_name == NULL || *sym_name == '\0')
                        sym_name = "*unknown*";
                      printf ("%s", sanitize_string (sym_name));
@@ -2279,7 +2331,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   if (! process_section_p (section))
     return;
 
-  datasize = bfd_get_section_size (section);
+  datasize = bfd_section_size (section);
   if (datasize == 0)
     return;
 
@@ -2351,12 +2403,15 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       return;
     }
 
-  paux->sec = section;
   pinfo->buffer = data;
   pinfo->buffer_vma = section->vma;
   pinfo->buffer_length = datasize;
   pinfo->section = section;
 
+  /* Sort the symbols into value and section order.  */
+  compare_section = section;
+  qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+
   /* Skip over the relocs belonging to addresses below the
      start address.  */
   while (rel_pp < rel_ppend
@@ -2509,7 +2564,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       else
        {
 #define is_valid_next_sym(SYM) \
-  (strcmp (bfd_section_name (abfd, (SYM)->section), bfd_section_name (abfd, section)) == 0 \
+  (strcmp (bfd_section_name ((SYM)->section), bfd_section_name (section)) == 0 \
    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
    && pinfo->symbol_is_valid (SYM, pinfo))
 
@@ -2600,9 +2655,6 @@ disassemble_data (bfd *abfd)
       ++sorted_symcount;
     }
 
-  /* Sort the symbols into section and symbol order.  */
-  qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
-
   init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
 
   disasm_info.application_data = (void *) &aux;
@@ -2652,7 +2704,7 @@ disassemble_data (bfd *abfd)
   disasm_info.arch = bfd_get_arch (abfd);
   disasm_info.mach = bfd_get_mach (abfd);
   disasm_info.disassembler_options = disassembler_options;
-  disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
+  disasm_info.octets_per_byte = bfd_octets_per_byte (abfd, NULL);
   disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
   disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
   disasm_info.disassembler_needs_relocs = FALSE;
@@ -2698,6 +2750,7 @@ disassemble_data (bfd *abfd)
   if (aux.dynrelbuf != NULL)
     free (aux.dynrelbuf);
   free (sorted_syms);
+  disassemble_free_target (&disasm_info);
 }
 \f
 static bfd_boolean
@@ -2721,9 +2774,9 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   section->filename = bfd_get_filename (abfd);
   section->reloc_info = NULL;
   section->num_relocs = 0;
-  section->address = bfd_get_section_vma (abfd, sec);
+  section->address = bfd_section_vma (sec);
   section->user_data = sec;
-  section->size = bfd_get_section_size (sec);
+  section->size = bfd_section_size (sec);
   /* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */
   alloced = amt = section->size + 1;
   if (alloced != amt || alloced == 0)
@@ -2892,11 +2945,38 @@ open_debug_file (const char * pathname)
   return data;
 }
 
+#if HAVE_LIBDEBUGINFOD
+/* Return a hex string represention of the build-id.  */
+
+unsigned char *
+get_build_id (void * data)
+{
+  unsigned i;
+  char * build_id_str;
+  bfd * abfd = (bfd *) data;
+  const struct bfd_build_id * build_id;
+
+  build_id = abfd->build_id;
+  if (build_id == NULL)
+    return NULL;
+
+  build_id_str = malloc (build_id->size * 2 + 1);
+  if (build_id_str == NULL)
+    return NULL;
+
+  for (i = 0; i < build_id->size; i++)
+    sprintf (build_id_str + (i * 2), "%02x", build_id->data[i]);
+  build_id_str[build_id->size * 2] = '\0';
+
+  return (unsigned char *)build_id_str;
+}
+#endif /* HAVE_LIBDEBUGINFOD */
+
 static void
 dump_dwarf_section (bfd *abfd, asection *section,
                    void *arg ATTRIBUTE_UNUSED)
 {
-  const char *name = bfd_get_section_name (abfd, section);
+  const char *name = bfd_section_name (section);
   const char *match;
   int i;
 
@@ -2942,44 +3022,8 @@ dump_dwarf (bfd *abfd)
       return;
     }
 
-  eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
-
   switch (bfd_get_arch (abfd))
     {
-    case bfd_arch_i386:
-      switch (bfd_get_mach (abfd))
-       {
-       case bfd_mach_x86_64:
-       case bfd_mach_x86_64_intel_syntax:
-       case bfd_mach_x86_64_nacl:
-       case bfd_mach_x64_32:
-       case bfd_mach_x64_32_intel_syntax:
-       case bfd_mach_x64_32_nacl:
-         init_dwarf_regnames_x86_64 ();
-         break;
-
-       default:
-         init_dwarf_regnames_i386 ();
-         break;
-       }
-      break;
-
-    case bfd_arch_iamcu:
-      init_dwarf_regnames_iamcu ();
-      break;
-
-    case bfd_arch_aarch64:
-      init_dwarf_regnames_aarch64();
-      break;
-
-    case bfd_arch_s390:
-      init_dwarf_regnames_s390 ();
-      break;
-
-    case bfd_arch_riscv:
-      init_dwarf_regnames_riscv ();
-      break;
-
     case bfd_arch_s12z:
       /* S12Z has a 24 bit address space.  But the only known
         producer of dwarf_info encodes addresses into 32 bits.  */
@@ -2987,9 +3031,13 @@ dump_dwarf (bfd *abfd)
       break;
 
     default:
+      eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
       break;
     }
 
+  init_dwarf_regnames_by_bfd_arch_and_mach (bfd_get_arch (abfd),
+                                           bfd_get_mach (abfd));
+
   bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
 }
 \f
@@ -3021,7 +3069,7 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr,
       return NULL;
     }
 
-  *size_ptr = bfd_section_size (abfd, stabsect);
+  *size_ptr = bfd_section_size (stabsect);
   if (entsize_ptr)
     *entsize_ptr = stabsect->entsize;
 
@@ -3252,19 +3300,27 @@ 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 *things[] = {"Header", "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.  */
+     really archives, so printing it out is liable to be confusing.
+
+     The parent, if there is one, is the default-owned archive member:
+     avoid importing it into itself.  (This does no harm, but looks
+     confusing.)  */
+
   if (strcmp (name, ".ctf") != 0)
-    printf (_("\nCTF archive member: %s:\n"), sanitize_string (name));
+    {
+      printf (_("\nCTF archive member: %s:\n"), sanitize_string (name));
+      ctf_import (ctf, parent);
+    }
 
-  ctf_import (ctf, parent);
-  for (i = 1, thing = things; *thing[0]; thing++, i++)
+  for (i = 0, thing = things; *thing[0]; thing++, i++)
     {
       ctf_dump_state_t *s = NULL;
       char *item;
@@ -3292,7 +3348,7 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
 static void
 dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
 {
-  ctf_archive_t *ctfa, *parenta = NULL;
+  ctf_archive_t *ctfa, *parenta = NULL, *lookparent;
   bfd_byte *ctfdata, *parentdata = NULL;
   bfd_size_type ctfsize, parentsize;
   ctf_sect_t ctfsect;
@@ -3325,14 +3381,18 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
          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));
-       }
+      lookparent = parenta;
+    }
+  else
+    lookparent = ctfa;
+
+  /* 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 (lookparent, 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));
@@ -3417,7 +3477,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
   bfd_vma addr_offset;
   bfd_vma start_offset;
   bfd_vma stop_offset;
-  unsigned int opb = bfd_octets_per_byte (abfd);
+  unsigned int opb = bfd_octets_per_byte (abfd, section);
   /* Bytes per line.  */
   const int onaline = 16;
   char buf[64];
@@ -3430,7 +3490,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
   if (! process_section_p (section))
     return;
 
-  if ((datasize = bfd_section_size (abfd, section)) == 0)
+  if ((datasize = bfd_section_size (section)) == 0)
     return;
 
   /* Compute the address range to display.  */
@@ -4455,6 +4515,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;
@@ -4497,11 +4566,11 @@ main (int argc, char **argv)
        case OPTION_DWARF_CHECK:
          dwarf_check = TRUE;
          break;
-        case OPTION_CTF:
-          dump_ctf_section_info = TRUE;
-          dump_ctf_section_name = xstrdup (optarg);
-          seenflag = TRUE;
-          break;
+       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;
@@ -4566,6 +4635,7 @@ main (int argc, char **argv)
   free_only_list ();
   free (dump_ctf_section_name);
   free (dump_ctf_parent_name);
+  free ((void *) source_comment);
 
   END_PROGRESS (program_name);
 
This page took 0.034573 seconds and 4 git commands to generate.