Add support for -brtl, run time linking, to AIX ld.
authorTom Rix <trix@redhat.com>
Tue, 19 Feb 2002 05:01:40 +0000 (05:01 +0000)
committerTom Rix <trix@redhat.com>
Tue, 19 Feb 2002 05:01:40 +0000 (05:01 +0000)
bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/coff-rs6000.c
bfd/coff64-rs6000.c
bfd/libxcoff.h
bfd/xcofflink.c
ld/ChangeLog
ld/emultempl/aix.em

index ff86ca3..bc5c02e 100644 (file)
@@ -1,3 +1,15 @@
+2002-02-18  Tom Rix  <trix@redhat.com>
+
+       * xcofflink.c (bfd_xcoff_link_gernate_rtinit): Add -brtl support.
+       (bfd_xcoff_size_dynamic_sections): Same.
+       * bfd-in.h (bfd_xcoff_link_generate_rtinit): Same.
+       (bfd_xcoff_size_dynamic_sections): Same.
+       * coff-rs6000.c (xcoff_generate_rtinit): Same.
+       * coff-rs646000.c (xcoff64_generate_rtinit): Same.
+       * libxcoff.h (struct xcoff_backend_data_rec): Same.
+       * xcofflink.c (xcoff_build_ldsyms, xcoff_link_add_symbols): Clean.
+       * bfd-in2.h: Regenerate.
+
 2002-02-18  Alan Modra  <amodra@bigpond.net.au>
 
        * elf64-ppc.c (STFD_FR0_0R1, LFD_FR0_0R1, BLR): Define.
index bd8a915..5c21e1d 100644 (file)
@@ -745,9 +745,9 @@ extern boolean bfd_xcoff_record_link_assignment
 extern boolean bfd_xcoff_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *,
           unsigned long, unsigned long, unsigned long, boolean,
-          int, boolean, boolean, struct sec **));
+          int, boolean, boolean, struct sec **, boolean));
 extern boolean bfd_xcoff_link_generate_rtinit
-  PARAMS ((bfd *, const char *, const char *));
+  PARAMS ((bfd *, const char *, const char *, boolean));
 
 /* Externally visible COFF routines.  */
 
index ff4ba0d..83677e9 100644 (file)
@@ -751,9 +751,9 @@ extern boolean bfd_xcoff_record_link_assignment
 extern boolean bfd_xcoff_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *,
           unsigned long, unsigned long, unsigned long, boolean,
-          int, boolean, boolean, struct sec **));
+          int, boolean, boolean, struct sec **, boolean));
 extern boolean bfd_xcoff_link_generate_rtinit
-  PARAMS ((bfd *, const char *, const char *));
+  PARAMS ((bfd *, const char *, const char *, boolean));
 
 /* Externally visible COFF routines.  */
 
index 2772929..75ed122 100644 (file)
@@ -81,8 +81,9 @@ void _bfd_xcoff_rtype2howto PARAMS ((arelent *, struct internal_reloc *));
 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
 #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
 #ifdef AIX_CORE
-extern const bfd_target * rs6000coff_core_p ();
-extern boolean rs6000coff_core_file_matches_executable_p ();
+extern const bfd_target * rs6000coff_core_p PARAMS ((bfd *abfd));
+extern boolean rs6000coff_core_file_matches_executable_p 
+  PARAMS ((bfd *cbfd, bfd *ebfd));
 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
 #define CORE_FILE_P rs6000coff_core_p
@@ -144,8 +145,7 @@ static bfd_vma xcoff_loader_symbol_offset
 static bfd_vma xcoff_loader_reloc_offset
   PARAMS ((bfd *, struct internal_ldhdr *));
 static boolean xcoff_generate_rtinit 
-  PARAMS((bfd *, const char *, const char *));
-
+  PARAMS((bfd *, const char *, const char *, boolean));
 
 /* We use our own tdata type.  Its first field is the COFF tdata type,
    so the COFF routines are compatible.  */
@@ -3051,15 +3051,16 @@ xcoff_loader_reloc_offset (abfd, ldhdr)
 }
 
 static boolean 
-xcoff_generate_rtinit  (abfd, init, fini)
+xcoff_generate_rtinit  (abfd, init, fini, rtld)
      bfd *abfd;
      const char *init;
      const char *fini;
+     boolean rtld;
 {
   bfd_byte filehdr_ext[FILHSZ];
   bfd_byte scnhdr_ext[SCNHSZ];
-  bfd_byte syment_ext[SYMESZ * 8];
-  bfd_byte reloc_ext[RELSZ * 2];
+  bfd_byte syment_ext[SYMESZ * 10];
+  bfd_byte reloc_ext[RELSZ * 3];
   bfd_byte *data_buffer;
   bfd_size_type data_buffer_size;
   bfd_byte *string_table = NULL, *st_tmp = NULL;
@@ -3074,9 +3075,9 @@ xcoff_generate_rtinit  (abfd, init, fini)
   
   char *data_name = ".data";
   char *rtinit_name = "__rtinit";
+  char *rtld_name = "__rtld";
   
-  if (! bfd_xcoff_rtinit_size (abfd) 
-      || (init == NULL && fini == NULL))
+  if (! bfd_xcoff_rtinit_size (abfd))
     return false;
 
   initsz = (init == NULL ? 0 : 1 + strlen (init));
@@ -3088,7 +3089,7 @@ xcoff_generate_rtinit  (abfd, init, fini)
   filehdr.f_magic = bfd_xcoff_magic_number (abfd);
   filehdr.f_nscns = 1; 
   filehdr.f_timdat = 0;
-  filehdr.f_nsyms = 0;  /* at least 6, no more than 8 */
+  filehdr.f_nsyms = 0;  /* at least 6, no more than 10 */
   filehdr.f_symptr = 0; /* set below */
   filehdr.f_opthdr = 0;
   filehdr.f_flags = 0;
@@ -3179,9 +3180,10 @@ xcoff_generate_rtinit  (abfd, init, fini)
      0. .data csect
      2. __rtinit
      4. init function 
-     6. fini function */
-  memset (syment_ext, 0, 8 * SYMESZ);
-  memset (reloc_ext, 0, 2 * RELSZ);
+     6. fini function 
+     8. __rtld  */
+  memset (syment_ext, 0, 10 * SYMESZ);
+  memset (reloc_ext, 0, 3 * RELSZ);
 
   /* .data csect */
   memset (&syment, 0, sizeof (struct internal_syment));
@@ -3287,6 +3289,32 @@ xcoff_generate_rtinit  (abfd, init, fini)
       scnhdr.s_nreloc += 1;
     }
 
+  if (rtld)
+    {
+      memset (&syment, 0, sizeof (struct internal_syment));
+      memset (&auxent, 0, sizeof (union internal_auxent));
+      memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
+      syment.n_sclass = C_EXT;
+      syment.n_numaux = 1;
+      bfd_coff_swap_sym_out (abfd, &syment, 
+                            &syment_ext[filehdr.f_nsyms * SYMESZ]);
+      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
+                            syment.n_numaux, 
+                            &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+      /* reloc */
+      memset (&reloc, 0, sizeof (struct internal_reloc));
+      reloc.r_vaddr = 0x0000;
+      reloc.r_symndx = filehdr.f_nsyms;
+      reloc.r_type = R_POS;
+      reloc.r_size = 31;
+      bfd_coff_swap_reloc_out (abfd, &reloc, 
+                              &reloc_ext[scnhdr.s_nreloc * RELSZ]);
+
+      filehdr.f_nsyms += 2;
+      scnhdr.s_nreloc += 1;
+    }
+
   scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
   filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
 
@@ -3696,7 +3724,6 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
   /* rtinit */
   0,           /* _xcoff_rtinit_size */
   xcoff_generate_rtinit,  /* _xcoff_generate_rtinit */
-
 };
 
 /* The transfer vector that leads the outside world to all of the above. */
index d66a70e..288f620 100644 (file)
@@ -144,8 +144,7 @@ static bfd_vma xcoff64_loader_symbol_offset
 static bfd_vma xcoff64_loader_reloc_offset
   PARAMS ((bfd *, struct internal_ldhdr *));
 static boolean xcoff64_generate_rtinit 
-  PARAMS((bfd *, const char *, const char *));
-
+  PARAMS((bfd *, const char *, const char *, boolean));
 
 /* coffcode.h needs these to be defined */
 /* Internalcoff.h and coffcode.h modify themselves based on these flags.  */
@@ -171,8 +170,9 @@ static boolean xcoff64_generate_rtinit
 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
 #ifdef AIX_CORE
-extern const bfd_target * rs6000coff_core_p ();
-extern boolean rs6000coff_core_file_matches_executable_p ();
+extern const bfd_target * rs6000coff_core_p PARAMS ((bfd *abfd));
+extern boolean rs6000coff_core_file_matches_executable_p 
+  PARAMS((bfd *cbfd, bfd *ebfd));
 extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
 extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
 #define CORE_FILE_P rs6000coff_core_p
@@ -2098,15 +2098,16 @@ xcoff64_loader_reloc_offset (abfd, ldhdr)
 }
 
 static boolean 
-xcoff64_generate_rtinit  (abfd, init, fini)
+xcoff64_generate_rtinit (abfd, init, fini, rtld)
      bfd *abfd;
      const char *init;
      const char *fini;
+     boolean rtld;
 {
   bfd_byte filehdr_ext[FILHSZ];
-  bfd_byte scnhdr_ext[SCNHSZ];
-  bfd_byte syment_ext[SYMESZ * 8];
-  bfd_byte reloc_ext[RELSZ * 2];
+  bfd_byte scnhdr_ext[SCNHSZ * 3];
+  bfd_byte syment_ext[SYMESZ * 10];
+  bfd_byte reloc_ext[RELSZ * 3];
   bfd_byte *data_buffer;
   bfd_size_type data_buffer_size;
   bfd_byte *string_table, *st_tmp;
@@ -2114,16 +2115,20 @@ xcoff64_generate_rtinit  (abfd, init, fini)
   bfd_vma val;
   size_t initsz, finisz;
   struct internal_filehdr filehdr;
-  struct internal_scnhdr scnhdr;
+  struct internal_scnhdr text_scnhdr;
+  struct internal_scnhdr data_scnhdr;
+  struct internal_scnhdr bss_scnhdr;
   struct internal_syment syment;
   union internal_auxent auxent;
   struct internal_reloc reloc;
   
+  char *text_name = ".text";
   char *data_name = ".data";
+  char *bss_name = ".bss";
   char *rtinit_name = "__rtinit";
+  char *rtld_name = "__rtld";
   
-  if (! bfd_xcoff_rtinit_size (abfd) 
-      || (init == NULL && fini == NULL))
+  if (! bfd_xcoff_rtinit_size (abfd))
     return false;
 
   initsz = (init == NULL ? 0 : 1 + strlen (init));
@@ -2133,26 +2138,54 @@ xcoff64_generate_rtinit  (abfd, init, fini)
   memset (filehdr_ext, 0, FILHSZ);
   memset (&filehdr, 0, sizeof (struct internal_filehdr));
   filehdr.f_magic = bfd_xcoff_magic_number (abfd);
-  filehdr.f_nscns = 1
+  filehdr.f_nscns = 3
   filehdr.f_timdat = 0;
   filehdr.f_nsyms = 0;  /* at least 6, no more than 8 */
   filehdr.f_symptr = 0; /* set below */
   filehdr.f_opthdr = 0;
   filehdr.f_flags = 0;
 
-  /* section header */
-  memset (scnhdr_ext, 0, SCNHSZ);
-  memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
-  memcpy (scnhdr.s_name, data_name, strlen (data_name));
-  scnhdr.s_paddr = 0;
-  scnhdr.s_vaddr = 0;
-  scnhdr.s_size = 0;    /* set below */
-  scnhdr.s_scnptr = FILHSZ + SCNHSZ;
-  scnhdr.s_relptr = 0;  /* set below */
-  scnhdr.s_lnnoptr = 0;
-  scnhdr.s_nreloc = 0;  /* either 1 or 2 */
-  scnhdr.s_nlnno = 0;
-  scnhdr.s_flags = STYP_DATA;
+  /* section headers */
+  memset (scnhdr_ext, 0, 3 * SCNHSZ);
+
+  /* text */
+  memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
+  memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
+  text_scnhdr.s_paddr = 0;
+  text_scnhdr.s_vaddr = 0;
+  text_scnhdr.s_size = 0;
+  text_scnhdr.s_scnptr = 0;
+  text_scnhdr.s_relptr = 0;
+  text_scnhdr.s_lnnoptr = 0;
+  text_scnhdr.s_nreloc = 0;
+  text_scnhdr.s_nlnno = 0;
+  text_scnhdr.s_flags = STYP_TEXT;
+
+  /* data */
+  memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
+  memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
+  data_scnhdr.s_paddr = 0;
+  data_scnhdr.s_vaddr = 0;
+  data_scnhdr.s_size = 0;    /* set below */
+  data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
+  data_scnhdr.s_relptr = 0;  /* set below */
+  data_scnhdr.s_lnnoptr = 0;
+  data_scnhdr.s_nreloc = 0;  /* either 1 or 2 */
+  data_scnhdr.s_nlnno = 0;
+  data_scnhdr.s_flags = STYP_DATA;
+
+  /* bss */
+  memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
+  memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
+  bss_scnhdr.s_paddr = 0; /* set below */
+  bss_scnhdr.s_vaddr = 0; /* set below */
+  bss_scnhdr.s_size = 0;  /* set below */
+  bss_scnhdr.s_scnptr = 0;
+  bss_scnhdr.s_relptr = 0;  
+  bss_scnhdr.s_lnnoptr = 0;
+  bss_scnhdr.s_nreloc = 0;
+  bss_scnhdr.s_nlnno = 0;
+  bss_scnhdr.s_flags = STYP_BSS;
 
   /* .data 
      0x0000           0x00000000 : rtl
@@ -2209,7 +2242,8 @@ xcoff64_generate_rtinit  (abfd, init, fini)
 
   val = 0x10;
   bfd_put_32 (abfd, val, &data_buffer[0x10]);
-  scnhdr.s_size = data_buffer_size;
+  data_scnhdr.s_size = data_buffer_size;
+  bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
 
   /* string table */
   string_table_size = 4;
@@ -2217,6 +2251,8 @@ xcoff64_generate_rtinit  (abfd, init, fini)
   string_table_size += strlen (rtinit_name) + 1;
   string_table_size += initsz;
   string_table_size += finisz;
+  if (true == rtld)
+    string_table_size += strlen (rtld_name) + 1;
 
   string_table = (bfd_byte *)bfd_malloc (string_table_size);
   memset (string_table, 0, string_table_size);
@@ -2228,9 +2264,10 @@ xcoff64_generate_rtinit  (abfd, init, fini)
      0. .data csect
      2. __rtinit
      4. init function 
-     6. fini function */
-  memset (syment_ext, 0, 8 * SYMESZ);
-  memset (reloc_ext, 0, 2 * RELSZ);
+     6. fini function 
+     8. __rtld  */
+  memset (syment_ext, 0, 10 * SYMESZ);
+  memset (reloc_ext, 0, 3 * RELSZ);
 
   /* .data csect */
   memset (&syment, 0, sizeof (struct internal_syment));
@@ -2240,7 +2277,7 @@ xcoff64_generate_rtinit  (abfd, init, fini)
   memcpy (st_tmp, data_name, strlen (data_name));
   st_tmp += strlen (data_name) + 1;
 
-  syment.n_scnum = 1;
+  syment.n_scnum = 2;
   syment.n_sclass = C_HIDEXT;
   syment.n_numaux = 1;
   auxent.x_csect.x_scnlen.l = data_buffer_size;
@@ -2260,7 +2297,7 @@ xcoff64_generate_rtinit  (abfd, init, fini)
   memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
   st_tmp += strlen (rtinit_name) + 1;
   
-  syment.n_scnum = 1;
+  syment.n_scnum = 2;
   syment.n_sclass = C_EXT;
   syment.n_numaux = 1;
   auxent.x_csect.x_smtyp = XTY_LD;
@@ -2298,7 +2335,7 @@ xcoff64_generate_rtinit  (abfd, init, fini)
       bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
 
       filehdr.f_nsyms += 2;
-      scnhdr.s_nreloc += 1;
+      data_scnhdr.s_nreloc += 1;
     }
 
   /* finit */
@@ -2326,21 +2363,55 @@ xcoff64_generate_rtinit  (abfd, init, fini)
       reloc.r_type = R_POS;
       reloc.r_size = 63;
       bfd_coff_swap_reloc_out (abfd, &reloc, 
-                              &reloc_ext[scnhdr.s_nreloc * RELSZ]);
+                              &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
 
       filehdr.f_nsyms += 2;
-      scnhdr.s_nreloc += 1;
+      data_scnhdr.s_nreloc += 1;
     }
 
-  scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
-  filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
+  if (rtld)
+    {
+      memset (&syment, 0, sizeof (struct internal_syment));
+      memset (&auxent, 0, sizeof (union internal_auxent));
+
+      syment._n._n_n._n_offset = st_tmp - string_table;
+      memcpy (st_tmp, rtld_name, strlen (rtld_name));
+      st_tmp += strlen (rtld_name) + 1;
+
+      syment.n_sclass = C_EXT;
+      syment.n_numaux = 1;
+      bfd_coff_swap_sym_out (abfd, &syment, 
+                            &syment_ext[filehdr.f_nsyms * SYMESZ]);
+      bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, 
+                            syment.n_numaux, 
+                            &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+      /* reloc */
+      memset (&reloc, 0, sizeof (struct internal_reloc));
+      reloc.r_vaddr = 0x0000;
+      reloc.r_symndx = filehdr.f_nsyms;
+      reloc.r_type = R_POS;
+      reloc.r_size = 63;
+      bfd_coff_swap_reloc_out (abfd, &reloc, 
+                              &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
+
+      filehdr.f_nsyms += 2;
+      data_scnhdr.s_nreloc += 1;
+
+      bss_scnhdr.s_size = 0;
+    }
+
+  data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
+  filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
 
   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
   bfd_bwrite (filehdr_ext, FILHSZ, abfd);
-  bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
-  bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
+  bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
+  bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
+  bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
+  bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
   bfd_bwrite (data_buffer, data_buffer_size, abfd);
-  bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
+  bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
   bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
   bfd_bwrite (string_table, string_table_size, abfd);
 
@@ -2478,7 +2549,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
   /* rtinit */
   88,           /* _xcoff_rtinit_size */
   xcoff64_generate_rtinit,  /* _xcoff_generate_rtinit */
-
 };
 
 /* The transfer vector that leads the outside world to all of the above. */
index ee72370..20c3c4a 100644 (file)
@@ -95,7 +95,8 @@ struct xcoff_backend_data_rec
 
   /* rtinit */
   unsigned int _xcoff_rtinit_size;
-  boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *);
+  boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *, 
+                                   boolean);
 };
 
 /* Look up an entry in an XCOFF link hash table.  */
@@ -192,6 +193,6 @@ struct xcoff_backend_data_rec
 #define bfd_xcoff_is_xcoff32(a) (0x01DF == (bfd_xcoff_magic_number(a)))
 
 #define bfd_xcoff_rtinit_size(a) ((xcoff_backend(a)->_xcoff_rtinit_size))
-#define bfd_xcoff_generate_rtinit(a, b, c) ((xcoff_backend(a)->_xcoff_generate_rtinit ((a), (b), (c))))
+#define bfd_xcoff_generate_rtinit(a, b, c, d) ((xcoff_backend(a)->_xcoff_generate_rtinit ((a), (b), (c), (d))))
 
 #endif /* LIBXCOFF_H */
index 84b8e52..5b1ddcc 100644 (file)
@@ -1046,16 +1046,12 @@ xcoff_link_add_symbols (abfd, info)
       && ! info->static_link)
     {
       if (! xcoff_link_add_dynamic_symbols (abfd, info))
-       {
-         return false;
-       }
+       return false;
     }
 
   /* create the loader, toc, gl, ds and debug sections, if needed */
   if (false == xcoff_link_create_extra_sections(abfd, info))
-    {
-      goto error_return;
-    }
+    goto error_return;
 
   if ((abfd->flags & DYNAMIC) != 0
       && ! info->static_link)
@@ -1146,7 +1142,6 @@ xcoff_link_add_symbols (abfd, info)
        }
     }
 
-
   /* Don't let the linker relocation routines discard the symbols.  */
   obj_coff_keep_syms (abfd) = true;
 
@@ -2806,7 +2801,7 @@ boolean
 bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
                                 file_align, maxstack, maxdata, gc,
                                 modtype, textro, export_defineds,
-                                special_sections)
+                                special_sections, rtld)
      bfd *output_bfd;
      struct bfd_link_info *info;
      const char *libpath;
@@ -2819,6 +2814,7 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
      boolean textro;
      boolean export_defineds;
      asection **special_sections;
+     boolean rtld;
 {
   struct xcoff_link_hash_entry *hentry;
   asection *lsec;
@@ -2837,7 +2833,6 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
 
   if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     {
-
       for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
        special_sections[i] = NULL;
       return true;
@@ -2859,11 +2854,8 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
   xcoff_hash_table (info)->file_align = file_align;
   xcoff_hash_table (info)->textro = textro;
 
-  if (entry == NULL)
-    {
-      hentry = NULL;
-    }
-  else
+  hentry = NULL;
+  if (entry != NULL)
     {
       hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry,
                                       false, false, true);
@@ -2872,65 +2864,56 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
     }
 
   /* __rtinit */
-  if (info->init_function || info->fini_function) {
-    struct xcoff_link_hash_entry *hrtinit;
-    struct internal_ldsym *ldsym;
-
-    hrtinit = xcoff_link_hash_lookup (xcoff_hash_table (info),
-                                     "__rtinit",
-                                     false, false, true);
-    if (hrtinit != NULL)
-      {
-       xcoff_mark_symbol (info, hrtinit);
-       hrtinit->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT);
-      }
-    else
-      {
-       (*_bfd_error_handler)
-         (_("error: undefined symbol __rtinit"));
-
-       return false;
-      }
-
-    /* __rtinit initalized here
-       Some information, like the location of the .initfini seciton will
-       be filled in later.
-
-       name or offset taken care of below with bfd_xcoff_put_ldsymbol_name.  */
-    amt = sizeof (struct internal_ldsym);
-    ldsym = (struct internal_ldsym *) bfd_malloc (amt);
-
-    ldsym->l_value = 0;                  /* will be filled in later */
-    ldsym->l_scnum = 2;                  /* data section */
-    ldsym->l_smtype = XTY_SD;            /* csect section definition */
-    ldsym->l_smclas = 5;                 /* .rw */
-    ldsym->l_ifile = 0;                  /* special system loader symbol */
-    ldsym->l_parm = 0;                   /* NA */
-
-    /* Force __rtinit to be the first symbol in the loader symbol table
-       See xcoff_build_ldsyms
-
-       The first 3 symbol table indices are reserved to indicate the data,
-       text and bss sections.  */
-    BFD_ASSERT (0 == ldinfo.ldsym_count);
-
-    hrtinit->ldindx = 3;
-    ldinfo.ldsym_count = 1;
-    hrtinit->ldsym = ldsym;
-
-    if (false == bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo,
-                                             hrtinit->ldsym,
-                                             hrtinit->root.root.string))
-      {
+  if (info->init_function || info->fini_function || rtld == true) 
+    {
+      struct xcoff_link_hash_entry *hsym;
+      struct internal_ldsym *ldsym;
+      
+      hsym = xcoff_link_hash_lookup (xcoff_hash_table (info),
+                                    "__rtinit", false, false, true);
+      if (hsym == NULL)
+       {
+         (*_bfd_error_handler)
+           (_("error: undefined symbol __rtinit"));
+         return false;
+       }
+      
+      xcoff_mark_symbol (info, hsym);
+      hsym->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT);
+
+      /* __rtinit initalized */
+      amt = sizeof (struct internal_ldsym);
+      ldsym = (struct internal_ldsym *) bfd_malloc (amt);
+      
+      ldsym->l_value = 0;                  /* will be filled in later */
+      ldsym->l_scnum = 2;                  /* data section */
+      ldsym->l_smtype = XTY_SD;            /* csect section definition */
+      ldsym->l_smclas = 5;                 /* .rw */
+      ldsym->l_ifile = 0;                  /* special system loader symbol */
+      ldsym->l_parm = 0;                   /* NA */
+      
+      /* Force __rtinit to be the first symbol in the loader symbol table
+        See xcoff_build_ldsyms
+        
+        The first 3 symbol table indices are reserved to indicate the data,
+        text and bss sections.  */
+      BFD_ASSERT (0 == ldinfo.ldsym_count);
+      
+      hsym->ldindx = 3;
+      ldinfo.ldsym_count = 1;
+      hsym->ldsym = ldsym;
+      
+      if (false == bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo,
+                                               hsym->ldsym,
+                                               hsym->root.root.string))
        return false;
-      }
-
-    /* This symbol is written out by xcoff_write_global_symbol
-       Set stuff up so xcoff_write_global_symbol logic works.  */
-    hrtinit->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK;
-    hrtinit->root.type = bfd_link_hash_defined;
-    hrtinit->root.u.def.value = 0;
-  }
+      
+      /* This symbol is written out by xcoff_write_global_symbol
+        Set stuff up so xcoff_write_global_symbol logic works.  */
+      hsym->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK;
+      hsym->root.type = bfd_link_hash_defined;
+      hsym->root.u.def.value = 0;
+    }
 
   /* Garbage collect unused sections.  */
   if (info->relocateable
@@ -3220,10 +3203,11 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
 }
 
 boolean 
-bfd_xcoff_link_generate_rtinit (abfd, init, fini)
+bfd_xcoff_link_generate_rtinit (abfd, init, fini, rtld)
      bfd *abfd;
      const char *init;
      const char *fini;
+     boolean rtld;
 {
   struct bfd_in_memory *bim;
   
@@ -3242,7 +3226,7 @@ bfd_xcoff_link_generate_rtinit (abfd, init, fini)
   abfd->direction = write_direction;
   abfd->where = 0;
 
-  if (false == bfd_xcoff_generate_rtinit (abfd, init, fini)) 
+  if (false == bfd_xcoff_generate_rtinit (abfd, init, fini, rtld)) 
     return false;
 
   /* need to reset to unknown or it will not be read back in correctly */
@@ -3264,14 +3248,9 @@ xcoff_build_ldsyms (h, p)
   struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
   bfd_size_type amt;
 
-  /* __rtinit
-     Special handling of this symbol to make is the first symbol in
-     the loader symbol table.  Make sure this pass through does not
-     undo it.  */
+  /* __rtinit, this symbol has special handling. */
   if (h->flags & XCOFF_RTINIT)
-    {
       return true;
-    }
 
   /* If this is a final link, and the symbol was defined as a common
      symbol in a regular object file, and there was no definition in
@@ -3386,17 +3365,11 @@ xcoff_build_ldsyms (h, p)
             xcoff32 uses 4 bytes in the toc.
             xcoff64 uses 8 bytes in the toc.  */
          if (bfd_xcoff_is_xcoff64 (ldinfo->output_bfd))
-           {
-             byte_size = 8;
-           }
+           byte_size = 8;
          else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd))
-           {
-             byte_size = 4;
-           }
+           byte_size = 4;
          else
-           {
-             return false;
-           }
+           return false;
 
          hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
          hds->u.toc_offset = hds->toc_section->_raw_size;
index 2d388c4..3d705b4 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-18  Tom Rix  <trix@redhat.com>
+
+       * emultempl/aix.em (gld*_parse_args): Add -brtl support.
+       (gld*_before_allocation): Same.
+       (gld*_create_output_section_statements): Generate 
+       __rtinit if run time linking.  Add librtl.a to the link.
+       (gld*_read_file): Clean.
+
 2002-02-18  Alan Modra  <amodra@bigpond.net.au>
 
        * emulparams/elf64ppc.sh (OTHER_TEXT_SECTIONS): Define.
index e5db1b9..2d7b69f 100644 (file)
@@ -130,7 +130,10 @@ static unsigned int syscall_mask = 0x77;
 
 /* fake file for -binitfini support */
 static lang_input_statement_type *initfini_file;
+
+/* Whether to do run time linking */
+static boolean rtld;
+
 /* This routine is called before anything else is done.  */
 
 static void
@@ -155,7 +158,6 @@ gld${EMULATION_NAME}_before_parse ()
 
   link_info.init_function = NULL;
   link_info.fini_function = NULL;
-
 }
 
 /* Handle AIX specific options.  */
@@ -241,6 +243,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
     {"bpD", required_argument, NULL, OPTION_PD},
     {"bpT", required_argument, NULL, OPTION_PT},
     {"bro", no_argument, &textro, 1},
+    {"brtl", no_argument, &rtld, 1},
     {"bS", required_argument, NULL, OPTION_MAXSTACK},
     {"bso", no_argument, NULL, OPTION_AUTOIMP},
     {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
@@ -663,13 +666,10 @@ gld${EMULATION_NAME}_before_allocation ()
     }
 
   /* Let the XCOFF backend set up the .loader section.  */
-  if (!bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath,
-                                       entry_symbol, file_align,
-                                       maxstack, maxdata,
-                                       gc && !unix_ld ? true : false,
-                                       modtype,
-                                       textro ? true : false,
-                                       unix_ld, special_sections))
+  if (!bfd_xcoff_size_dynamic_sections 
+      (output_bfd, &link_info, libpath,        entry_symbol, file_align,
+       maxstack, maxdata, gc && !unix_ld ? true : false,
+       modtype,        textro ? true : false, unix_ld, special_sections, rtld))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
 
   /* Look through the special sections, and put them in the right
@@ -943,12 +943,11 @@ gld${EMULATION_NAME}_read_file (filename, import)
 
   lineno = 0;
 
-  /*
-   * default to 32 and 64 bit mode
-   * symbols at top of /lib/syscalls.exp do not have a mode modifier and they
-   * are not repeated, assume 64 bit routines also want to use them.
-   * See the routine change_symbol_mode for more information.
-   */
+  /* Default to 32 and 64 bit mode
+     symbols at top of /lib/syscalls.exp do not have a mode modifier and they
+     are not repeated, assume 64 bit routines also want to use them.
+     See the routine change_symbol_mode for more information.  */
+
   symbol_mode = 0x04;
 
   while ((c = getc (f)) != EOF)
@@ -1291,9 +1290,10 @@ gld${EMULATION_NAME}_create_output_section_statements()
 {
   /* __rtinit */
   if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour) 
-      && (link_info.init_function != NULL  || link_info.fini_function != NULL))
+      && (link_info.init_function != NULL  
+         || link_info.fini_function != NULL
+         || rtld == true))
     {
-      
       initfini_file = lang_add_input_file ("initfini",
                                           lang_input_file_is_file_enum,
                                           NULL);
@@ -1311,11 +1311,16 @@ gld${EMULATION_NAME}_create_output_section_statements()
       /* Call backend to fill in the rest */
       if (false == bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd, 
                                                   link_info.init_function, 
-                                                  link_info.fini_function))
+                                                  link_info.fini_function,
+                                                  rtld))
        {
          einfo ("%X%P: can not create BFD %E\n");
          return;
        }
+
+      /* __rtld defined in /lib/librtl.a */
+      if (true == rtld) 
+       lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL);
     }
 }