Re: PR25993, read of freed memory
[deliverable/binutils-gdb.git] / bfd / pdp11.c
index 50d006f0859068b33536bfcb8fb66318a86bac11..adcf34da1deca84e19a3c454812f5231b733a844 100644 (file)
@@ -63,6 +63,7 @@
 #define N_SET_FLAGS(execp, flags) do { } while (0)
 #define N_BADMAG(x) (N_MAGIC(x) != OMAGIC      \
                     && N_MAGIC(x) != NMAGIC    \
+                    && N_MAGIC(x) != IMAGIC    \
                     && N_MAGIC(x) != ZMAGIC)
 
 #include "sysdep.h"
@@ -90,7 +91,8 @@ struct pdp11_external_exec
 #define        A_MAGIC2        NMAGIC
 #define NMAGIC         0410    /* Pure executable.  */
 #define ZMAGIC         0413    /* Demand-paged executable.  */
-#define        A_MAGIC3        0411    /* Separated I&D.  */
+#define        IMAGIC          0411    /* Separated I&D.  */
+#define        A_MAGIC3        IMAGIC
 #define        A_MAGIC4        0405    /* Overlay.  */
 #define        A_MAGIC5        0430    /* Auto-overlay (nonseparate).  */
 #define        A_MAGIC6        0431    /* Auto-overlay (separate).  */
@@ -158,6 +160,7 @@ static bfd_boolean MY(write_object_contents) (bfd *);
 #undef N_REG
 #undef N_FN
 #undef N_EXT
+#undef N_STAB
 #define N_TYPE         0x1f    /* Type mask.  */
 #define N_UNDF         0x00    /* Undefined.  */
 #define N_ABS          0x01    /* Absolute.  */
@@ -167,6 +170,7 @@ static bfd_boolean MY(write_object_contents) (bfd *);
 #define N_REG          0x14    /* Register symbol.  */
 #define N_FN           0x1f    /* File name.  */
 #define N_EXT          0x20    /* External flag.  */
+#define N_STAB         0xc0    /* Not relevant; modified aout64.h's 0xe0 to avoid N_EXT.  */
 
 #define RELOC_SIZE 2
 
@@ -242,6 +246,10 @@ struct aout_final_link_info
   struct external_nlist *output_syms;
 };
 
+/* Copy of the link_info.separate_code boolean to select the output format with
+   separate instruction and data spaces selected by --imagic */
+static bfd_boolean separate_i_d = FALSE;
+
 reloc_howto_type howto_table_pdp11[] =
 {
   /* type             rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
@@ -452,13 +460,13 @@ NAME (aout, make_sections) (bfd *abfd)
    environment's "finish up" function just before returning, to
    handle any last-minute setup.  */
 
-const bfd_target *
+bfd_cleanup
 NAME (aout, some_aout_object_p) (bfd *abfd,
                                 struct internal_exec *execp,
-                                const bfd_target *(*callback_to_real_object_p) (bfd *))
+                                bfd_cleanup (*callback_to_real_object_p) (bfd *))
 {
   struct aout_data_struct *rawptr, *oldrawptr;
-  const bfd_target *result;
+  bfd_cleanup cleanup;
   size_t amt = sizeof (struct aout_data_struct);
 
   rawptr = bfd_zalloc (abfd, amt);
@@ -498,6 +506,8 @@ NAME (aout, some_aout_object_p) (bfd *abfd,
     }
   else if (N_MAGIC (execp) == OMAGIC)
     adata (abfd).magic = o_magic;
+  else if (N_MAGIC (execp) == IMAGIC)
+    adata (abfd).magic = i_magic;
   else
     {
       /* Should have been checked with N_BADMAG before this routine
@@ -580,7 +590,7 @@ NAME (aout, some_aout_object_p) (bfd *abfd,
   adata(abfd)->segment_size = SEGMENT_SIZE;
   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
 
-  return abfd->xvec;
+  return _bfd_no_cleanup;
 
   /* The architecture is encoded in various ways in various a.out variants,
      or is not encoded at all in some of them.  The relocation size depends
@@ -592,7 +602,7 @@ NAME (aout, some_aout_object_p) (bfd *abfd,
      header, should cope with them in this callback as well.  */
 #endif /* DOCUMENTATION */
 
-  result = (*callback_to_real_object_p)(abfd);
+  cleanup = (*callback_to_real_object_p)(abfd);
 
   /* Now that the segment addresses have been worked out, take a better
      guess at whether the file is executable.  If the entry point
@@ -633,12 +643,12 @@ NAME (aout, some_aout_object_p) (bfd *abfd,
     }
 #endif /* STAT_FOR_EXEC */
 
-  if (!result)
+  if (!cleanup)
     {
       free (rawptr);
       abfd->tdata.aout_data = oldrawptr;
     }
-  return result;
+  return cleanup;
 }
 
 /* Initialize ABFD for use with a.out files.  */
@@ -825,7 +835,7 @@ adjust_o_magic (bfd *abfd, struct internal_exec *execp)
       vma += pad;
       bss->vma = vma;
     }
-  else
+  else if (data->size > 0 || bss->size > 0) /* PR25677: for objcopy --extract-symbol */
     {
       /* The VMA of the .bss section is set by the VMA of the
         .data section plus the size of the .data section.  We may
@@ -988,6 +998,47 @@ adjust_n_magic (bfd *abfd, struct internal_exec *execp)
   N_SET_MAGIC (execp, NMAGIC);
 }
 
+static void
+adjust_i_magic (bfd *abfd, struct internal_exec *execp)
+{
+  file_ptr pos = adata (abfd).exec_bytes_size;
+  bfd_vma vma = 0;
+  int pad;
+  asection *text = obj_textsec (abfd);
+  asection *data = obj_datasec (abfd);
+  asection *bss = obj_bsssec (abfd);
+
+  /* Text.  */
+  text->filepos = pos;
+  if (!text->user_set_vma)
+    text->vma = vma;
+  else
+    vma = text->vma;
+  pos += execp->a_text;
+
+  /* Data.  */
+  data->filepos = pos;
+  if (!data->user_set_vma)
+    data->vma = 0;
+  vma = data->vma;
+
+  /* Since BSS follows data immediately, see if it needs alignment.  */
+  vma += data->size;
+  pad = align_power (vma, bss->alignment_power) - vma;
+  execp->a_data = data->size + pad;
+  pos += execp->a_data;
+
+  /* BSS.  */
+  if (!bss->user_set_vma)
+    bss->vma = vma;
+  else
+    vma = bss->vma;
+
+  /* Fix up exec header.  */
+  execp->a_bss = bss->size;
+  N_SET_MAGIC (execp, IMAGIC);
+}
+
 bfd_boolean
 NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
 {
@@ -1018,7 +1069,9 @@ NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
      I understand it better now, but I haven't time to do the cleanup this
      minute.  */
 
-  if (abfd->flags & WP_TEXT)
+  if (separate_i_d)
+    adata (abfd).magic = i_magic;
+  else if (abfd->flags & WP_TEXT)
     adata (abfd).magic = n_magic;
   else
     adata (abfd).magic = o_magic;
@@ -1031,6 +1084,7 @@ NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
                {
                case n_magic: str = "NMAGIC"; break;
                case o_magic: str = "OMAGIC"; break;
+               case i_magic: str = "IMAGIC"; break;
                case z_magic: str = "ZMAGIC"; break;
                default: abort ();
                }
@@ -1056,6 +1110,9 @@ NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
     case n_magic:
       adjust_n_magic (abfd, execp);
       break;
+    case i_magic:
+      adjust_i_magic (abfd, execp);
+      break;
     default:
       abort ();
     }
@@ -1446,7 +1503,7 @@ NAME (aout, translate_symbol_table) (bfd *abfd,
       else
        return FALSE;
 
-      in->symbol.value = GET_SWORD (abfd,  ext->e_value);
+      in->symbol.value = GET_WORD (abfd,  ext->e_value);
       /* TODO: is 0 a safe value here?  */
       in->desc = 0;
       in->other = 0;
@@ -1632,7 +1689,7 @@ NAME (aout, write_syms) (bfd *abfd)
 
   return TRUE;
 
-error_return:
+ error_return:
   _bfd_stringtab_free (strtab);
   return FALSE;
 }
@@ -2168,7 +2225,7 @@ NAME (aout, find_nearest_line) (bfd *abfd,
   size_t filelen, funclen;
   char *buf;
 
-  *filename_ptr = abfd->filename;
+  *filename_ptr = bfd_get_filename (abfd);
   *functionname_ptr = 0;
   *line_ptr = 0;
   if (discriminator_ptr)
@@ -2290,8 +2347,7 @@ NAME (aout, find_nearest_line) (bfd *abfd,
   else
     funclen = strlen (bfd_asymbol_name (func));
 
-  if (adata (abfd).line_buf != NULL)
-    free (adata (abfd).line_buf);
+  free (adata (abfd).line_buf);
   if (filelen + funclen == 0)
     adata (abfd).line_buf = buf = NULL;
   else
@@ -2358,7 +2414,7 @@ NAME (aout, bfd_free_cached_info) (bfd *abfd)
   if (bfd_get_format (abfd) != bfd_object)
     return TRUE;
 
-#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
+#define BFCI_FREE(x) do { free (x); x = NULL; } while (0)
   BFCI_FREE (obj_aout_symbols (abfd));
 
 #ifdef USE_MMAP
@@ -3624,6 +3680,7 @@ NAME (aout, final_link) (bfd *abfd,
   if (bfd_link_pic (info))
     abfd->flags |= DYNAMIC;
 
+  separate_i_d = info->separate_code;
   aout_info.info = info;
   aout_info.output_bfd = abfd;
   aout_info.contents = NULL;
@@ -3856,26 +3913,14 @@ NAME (aout, final_link) (bfd *abfd,
        }
     }
 
-  if (aout_info.contents != NULL)
-    {
-      free (aout_info.contents);
-      aout_info.contents = NULL;
-    }
-  if (aout_info.relocs != NULL)
-    {
-      free (aout_info.relocs);
-      aout_info.relocs = NULL;
-    }
-  if (aout_info.symbol_map != NULL)
-    {
-      free (aout_info.symbol_map);
-      aout_info.symbol_map = NULL;
-    }
-  if (aout_info.output_syms != NULL)
-    {
-      free (aout_info.output_syms);
-      aout_info.output_syms = NULL;
-    }
+  free (aout_info.contents);
+  aout_info.contents = NULL;
+  free (aout_info.relocs);
+  aout_info.relocs = NULL;
+  free (aout_info.symbol_map);
+  aout_info.symbol_map = NULL;
+  free (aout_info.output_syms);
+  aout_info.output_syms = NULL;
   if (includes_hash_initialized)
     {
       bfd_hash_table_free (&aout_info.includes.root);
@@ -3935,14 +3980,10 @@ NAME (aout, final_link) (bfd *abfd,
   return TRUE;
 
  error_return:
-  if (aout_info.contents != NULL)
-    free (aout_info.contents);
-  if (aout_info.relocs != NULL)
-    free (aout_info.relocs);
-  if (aout_info.symbol_map != NULL)
-    free (aout_info.symbol_map);
-  if (aout_info.output_syms != NULL)
-    free (aout_info.output_syms);
+  free (aout_info.contents);
+  free (aout_info.relocs);
+  free (aout_info.symbol_map);
+  free (aout_info.output_syms);
   if (includes_hash_initialized)
     bfd_hash_table_free (&aout_info.includes.root);
   return FALSE;
@@ -3979,13 +4020,14 @@ aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
      discarding such symbols.  */
   if (strip != strip_all
       && (strip != strip_some
-         || bfd_hash_lookup (flaginfo->info->keep_hash, input_bfd->filename,
+         || bfd_hash_lookup (flaginfo->info->keep_hash,
+                             bfd_get_filename (input_bfd),
                              FALSE, FALSE) != NULL)
       && discard != discard_all)
     {
       H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
       strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
-                                      input_bfd->filename, FALSE);
+                                      bfd_get_filename (input_bfd), FALSE);
       if (strtab_index == (bfd_size_type) -1)
        return FALSE;
       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
This page took 0.028687 seconds and 4 git commands to generate.