This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
patch, ld AIX -brtl support
- From: Tom Rix <trix at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Mon, 18 Feb 2002 15:08:31 -0600
- Subject: patch, ld AIX -brtl support
This ld/bfd patch supports -brtl, run time linking, on AIX.
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
2002-02-17 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.
* 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.
diff -rcp src-old/bfd/bfd-in.h src/bfd/bfd-in.h
*** src-old/bfd/bfd-in.h Fri Feb 15 05:54:48 2002
--- src/bfd/bfd-in.h Sat Feb 16 14:19:01 2002
*************** extern boolean bfd_xcoff_record_link_ass
*** 745,753 ****
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 **));
extern boolean bfd_xcoff_link_generate_rtinit
! PARAMS ((bfd *, const char *, const char *));
/* Externally visible COFF routines. */
--- 745,753 ----
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 **, boolean));
extern boolean bfd_xcoff_link_generate_rtinit
! PARAMS ((bfd *, const char *, const char *, boolean));
/* Externally visible COFF routines. */
diff -rcp src-old/bfd/coff-rs6000.c src/bfd/coff-rs6000.c
*** src-old/bfd/coff-rs6000.c Fri Feb 15 05:54:48 2002
--- src/bfd/coff-rs6000.c Mon Feb 18 06:46:31 2002
*************** void _bfd_xcoff_rtype2howto PARAMS ((are
*** 81,88 ****
#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 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
--- 81,89 ----
#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 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
*************** static bfd_vma xcoff_loader_symbol_offse
*** 144,151 ****
static bfd_vma xcoff_loader_reloc_offset
PARAMS ((bfd *, struct internal_ldhdr *));
static boolean xcoff_generate_rtinit
! PARAMS((bfd *, const char *, const char *));
!
/* We use our own tdata type. Its first field is the COFF tdata type,
so the COFF routines are compatible. */
--- 145,151 ----
static bfd_vma xcoff_loader_reloc_offset
PARAMS ((bfd *, struct internal_ldhdr *));
static boolean xcoff_generate_rtinit
! 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. */
*************** xcoff_loader_reloc_offset (abfd, ldhdr)
*** 3051,3065 ****
}
static boolean
! xcoff_generate_rtinit (abfd, init, fini)
bfd *abfd;
const char *init;
const char *fini;
{
bfd_byte filehdr_ext[FILHSZ];
bfd_byte scnhdr_ext[SCNHSZ];
! bfd_byte syment_ext[SYMESZ * 8];
! bfd_byte reloc_ext[RELSZ * 2];
bfd_byte *data_buffer;
bfd_size_type data_buffer_size;
bfd_byte *string_table = NULL, *st_tmp = NULL;
--- 3051,3066 ----
}
static boolean
! 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 * 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;
*************** xcoff_generate_rtinit (abfd, init, fini
*** 3074,3082 ****
char *data_name = ".data";
char *rtinit_name = "__rtinit";
! if (! bfd_xcoff_rtinit_size (abfd)
! || (init == NULL && fini == NULL))
return false;
initsz = (init == NULL ? 0 : 1 + strlen (init));
--- 3075,3083 ----
char *data_name = ".data";
char *rtinit_name = "__rtinit";
+ char *rtld_name = "__rtld";
! if (! bfd_xcoff_rtinit_size (abfd))
return false;
initsz = (init == NULL ? 0 : 1 + strlen (init));
*************** xcoff_generate_rtinit (abfd, init, fini
*** 3088,3094 ****
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_symptr = 0; /* set below */
filehdr.f_opthdr = 0;
filehdr.f_flags = 0;
--- 3089,3095 ----
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 10 */
filehdr.f_symptr = 0; /* set below */
filehdr.f_opthdr = 0;
filehdr.f_flags = 0;
*************** xcoff_generate_rtinit (abfd, init, fini
*** 3179,3187 ****
0. .data csect
2. __rtinit
4. init function
! 6. fini function */
! memset (syment_ext, 0, 8 * SYMESZ);
! memset (reloc_ext, 0, 2 * RELSZ);
/* .data csect */
memset (&syment, 0, sizeof (struct internal_syment));
--- 3180,3189 ----
0. .data csect
2. __rtinit
4. init function
! 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));
*************** xcoff_generate_rtinit (abfd, init, fini
*** 3287,3292 ****
--- 3289,3320 ----
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;
*************** static const struct xcoff_backend_data_r
*** 3696,3702 ****
/* rtinit */
0, /* _xcoff_rtinit_size */
xcoff_generate_rtinit, /* _xcoff_generate_rtinit */
-
};
/* The transfer vector that leads the outside world to all of the above. */
--- 3724,3729 ----
diff -rcp src-old/bfd/coff64-rs6000.c src/bfd/coff64-rs6000.c
*** src-old/bfd/coff64-rs6000.c Fri Feb 15 05:54:48 2002
--- src/bfd/coff64-rs6000.c Sun Feb 17 15:04:01 2002
*************** static bfd_vma xcoff64_loader_symbol_off
*** 144,151 ****
static bfd_vma xcoff64_loader_reloc_offset
PARAMS ((bfd *, struct internal_ldhdr *));
static boolean xcoff64_generate_rtinit
! PARAMS((bfd *, const char *, const char *));
!
/* coffcode.h needs these to be defined */
/* Internalcoff.h and coffcode.h modify themselves based on these flags. */
--- 144,150 ----
static bfd_vma xcoff64_loader_reloc_offset
PARAMS ((bfd *, struct internal_ldhdr *));
static boolean xcoff64_generate_rtinit
! 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. */
*************** static boolean xcoff64_generate_rtinit
*** 171,178 ****
#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 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
--- 170,178 ----
#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 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
*************** xcoff64_loader_reloc_offset (abfd, ldhdr
*** 2098,2112 ****
}
static boolean
! xcoff64_generate_rtinit (abfd, init, fini)
bfd *abfd;
const char *init;
const char *fini;
{
bfd_byte filehdr_ext[FILHSZ];
! bfd_byte scnhdr_ext[SCNHSZ];
! bfd_byte syment_ext[SYMESZ * 8];
! bfd_byte reloc_ext[RELSZ * 2];
bfd_byte *data_buffer;
bfd_size_type data_buffer_size;
bfd_byte *string_table, *st_tmp;
--- 2098,2113 ----
}
static boolean
! 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 * 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;
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2114,2129 ****
bfd_vma val;
size_t initsz, finisz;
struct internal_filehdr filehdr;
! struct internal_scnhdr scnhdr;
struct internal_syment syment;
union internal_auxent auxent;
struct internal_reloc reloc;
char *data_name = ".data";
char *rtinit_name = "__rtinit";
! if (! bfd_xcoff_rtinit_size (abfd)
! || (init == NULL && fini == NULL))
return false;
initsz = (init == NULL ? 0 : 1 + strlen (init));
--- 2115,2134 ----
bfd_vma val;
size_t initsz, finisz;
struct internal_filehdr filehdr;
! 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))
return false;
initsz = (init == NULL ? 0 : 1 + strlen (init));
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2133,2158 ****
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_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;
/* .data
0x0000 0x00000000 : rtl
--- 2138,2191 ----
memset (filehdr_ext, 0, FILHSZ);
memset (&filehdr, 0, sizeof (struct internal_filehdr));
filehdr.f_magic = bfd_xcoff_magic_number (abfd);
! 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 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
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2209,2215 ****
val = 0x10;
bfd_put_32 (abfd, val, &data_buffer[0x10]);
! scnhdr.s_size = data_buffer_size;
/* string table */
string_table_size = 4;
--- 2242,2249 ----
val = 0x10;
bfd_put_32 (abfd, val, &data_buffer[0x10]);
! 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;
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2217,2222 ****
--- 2251,2258 ----
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);
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2228,2236 ****
0. .data csect
2. __rtinit
4. init function
! 6. fini function */
! memset (syment_ext, 0, 8 * SYMESZ);
! memset (reloc_ext, 0, 2 * RELSZ);
/* .data csect */
memset (&syment, 0, sizeof (struct internal_syment));
--- 2264,2273 ----
0. .data csect
2. __rtinit
4. init function
! 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));
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2240,2246 ****
memcpy (st_tmp, data_name, strlen (data_name));
st_tmp += strlen (data_name) + 1;
! syment.n_scnum = 1;
syment.n_sclass = C_HIDEXT;
syment.n_numaux = 1;
auxent.x_csect.x_scnlen.l = data_buffer_size;
--- 2277,2283 ----
memcpy (st_tmp, data_name, strlen (data_name));
st_tmp += strlen (data_name) + 1;
! syment.n_scnum = 2;
syment.n_sclass = C_HIDEXT;
syment.n_numaux = 1;
auxent.x_csect.x_scnlen.l = data_buffer_size;
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2260,2266 ****
memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
st_tmp += strlen (rtinit_name) + 1;
! syment.n_scnum = 1;
syment.n_sclass = C_EXT;
syment.n_numaux = 1;
auxent.x_csect.x_smtyp = XTY_LD;
--- 2297,2303 ----
memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
st_tmp += strlen (rtinit_name) + 1;
! syment.n_scnum = 2;
syment.n_sclass = C_EXT;
syment.n_numaux = 1;
auxent.x_csect.x_smtyp = XTY_LD;
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2298,2304 ****
bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
filehdr.f_nsyms += 2;
! scnhdr.s_nreloc += 1;
}
/* finit */
--- 2335,2341 ----
bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
filehdr.f_nsyms += 2;
! data_scnhdr.s_nreloc += 1;
}
/* finit */
*************** xcoff64_generate_rtinit (abfd, init, fi
*** 2326,2346 ****
reloc.r_type = R_POS;
reloc.r_size = 63;
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;
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_bwrite (data_buffer, data_buffer_size, abfd);
! bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
bfd_bwrite (string_table, string_table_size, abfd);
--- 2363,2417 ----
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;
! }
!
! 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, &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, data_scnhdr.s_nreloc * RELSZ, abfd);
bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
bfd_bwrite (string_table, string_table_size, abfd);
*************** static const struct xcoff_backend_data_r
*** 2478,2484 ****
/* rtinit */
88, /* _xcoff_rtinit_size */
xcoff64_generate_rtinit, /* _xcoff_generate_rtinit */
-
};
/* The transfer vector that leads the outside world to all of the above. */
--- 2549,2554 ----
diff -rcp src-old/bfd/libxcoff.h src/bfd/libxcoff.h
*** src-old/bfd/libxcoff.h Fri Feb 15 05:54:51 2002
--- src/bfd/libxcoff.h Sat Feb 16 12:54:03 2002
*************** struct xcoff_backend_data_rec
*** 95,101 ****
/* rtinit */
unsigned int _xcoff_rtinit_size;
! boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *);
};
/* Look up an entry in an XCOFF link hash table. */
--- 95,102 ----
/* rtinit */
unsigned int _xcoff_rtinit_size;
! boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *,
! boolean);
};
/* Look up an entry in an XCOFF link hash table. */
*************** struct xcoff_backend_data_rec
*** 192,197 ****
#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))))
#endif /* LIBXCOFF_H */
--- 193,198 ----
#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, d) ((xcoff_backend(a)->_xcoff_generate_rtinit ((a), (b), (c), (d))))
#endif /* LIBXCOFF_H */
diff -rcp src-old/bfd/xcofflink.c src/bfd/xcofflink.c
*** src-old/bfd/xcofflink.c Fri Feb 15 05:54:53 2002
--- src/bfd/xcofflink.c Mon Feb 18 06:25:18 2002
*************** xcoff_link_add_symbols (abfd, info)
*** 1046,1061 ****
&& ! info->static_link)
{
if (! xcoff_link_add_dynamic_symbols (abfd, info))
! {
! 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;
! }
if ((abfd->flags & DYNAMIC) != 0
&& ! info->static_link)
--- 1046,1057 ----
&& ! info->static_link)
{
if (! xcoff_link_add_dynamic_symbols (abfd, info))
! 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;
if ((abfd->flags & DYNAMIC) != 0
&& ! info->static_link)
*************** xcoff_link_add_symbols (abfd, info)
*** 1146,1152 ****
}
}
-
/* Don't let the linker relocation routines discard the symbols. */
obj_coff_keep_syms (abfd) = true;
--- 1142,1147 ----
*************** boolean
*** 2806,2812 ****
bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
file_align, maxstack, maxdata, gc,
modtype, textro, export_defineds,
! special_sections)
bfd *output_bfd;
struct bfd_link_info *info;
const char *libpath;
--- 2801,2807 ----
bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
file_align, maxstack, maxdata, gc,
modtype, textro, export_defineds,
! special_sections, rtld)
bfd *output_bfd;
struct bfd_link_info *info;
const char *libpath;
*************** bfd_xcoff_size_dynamic_sections (output_
*** 2819,2824 ****
--- 2814,2820 ----
boolean textro;
boolean export_defineds;
asection **special_sections;
+ boolean rtld;
{
struct xcoff_link_hash_entry *hentry;
asection *lsec;
*************** bfd_xcoff_size_dynamic_sections (output_
*** 2837,2843 ****
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;
--- 2833,2838 ----
*************** bfd_xcoff_size_dynamic_sections (output_
*** 2859,2869 ****
xcoff_hash_table (info)->file_align = file_align;
xcoff_hash_table (info)->textro = textro;
! if (entry == NULL)
! {
! hentry = NULL;
! }
! else
{
hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry,
false, false, true);
--- 2854,2861 ----
xcoff_hash_table (info)->file_align = file_align;
xcoff_hash_table (info)->textro = textro;
! hentry = NULL;
! if (entry != NULL)
{
hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry,
false, false, true);
*************** bfd_xcoff_size_dynamic_sections (output_
*** 2872,2936 ****
}
/* __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))
! {
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;
! }
/* Garbage collect unused sections. */
if (info->relocateable
--- 2864,2919 ----
}
/* __rtinit */
! 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. */
! 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
*************** bfd_xcoff_size_dynamic_sections (output_
*** 3220,3229 ****
}
boolean
! bfd_xcoff_link_generate_rtinit (abfd, init, fini)
bfd *abfd;
const char *init;
const char *fini;
{
struct bfd_in_memory *bim;
--- 3203,3213 ----
}
boolean
! bfd_xcoff_link_generate_rtinit (abfd, init, fini, rtld)
bfd *abfd;
const char *init;
const char *fini;
+ boolean rtld;
{
struct bfd_in_memory *bim;
*************** bfd_xcoff_link_generate_rtinit (abfd, in
*** 3242,3248 ****
abfd->direction = write_direction;
abfd->where = 0;
! if (false == bfd_xcoff_generate_rtinit (abfd, init, fini))
return false;
/* need to reset to unknown or it will not be read back in correctly */
--- 3226,3232 ----
abfd->direction = write_direction;
abfd->where = 0;
! 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 */
*************** xcoff_build_ldsyms (h, p)
*** 3264,3277 ****
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. */
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
--- 3248,3256 ----
struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
bfd_size_type amt;
! /* __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
*************** xcoff_build_ldsyms (h, p)
*** 3386,3402 ****
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;
! }
else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd))
! {
! byte_size = 4;
! }
else
! {
! return false;
! }
hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
hds->u.toc_offset = hds->toc_section->_raw_size;
--- 3365,3375 ----
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;
else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd))
! byte_size = 4;
else
! return false;
hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
hds->u.toc_offset = hds->toc_section->_raw_size;
diff -rcp src-old/ld/emultempl/aix.em src/ld/emultempl/aix.em
*** src-old/ld/emultempl/aix.em Fri Feb 15 05:55:26 2002
--- src/ld/emultempl/aix.em Mon Feb 18 06:34:14 2002
*************** static unsigned int syscall_mask = 0x77;
*** 130,136 ****
/* fake file for -binitfini support */
static lang_input_statement_type *initfini_file;
!
/* This routine is called before anything else is done. */
static void
--- 130,139 ----
/* 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
*************** gld${EMULATION_NAME}_before_parse ()
*** 155,161 ****
link_info.init_function = NULL;
link_info.fini_function = NULL;
-
}
/* Handle AIX specific options. */
--- 158,163 ----
*************** gld${EMULATION_NAME}_parse_args (argc, a
*** 241,246 ****
--- 243,249 ----
{"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},
*************** gld${EMULATION_NAME}_before_allocation (
*** 663,675 ****
}
/* 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))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
/* Look through the special sections, and put them in the right
--- 666,675 ----
}
/* 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, rtld))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
/* Look through the special sections, and put them in the right
*************** gld${EMULATION_NAME}_read_file (filename
*** 943,954 ****
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.
! */
symbol_mode = 0x04;
while ((c = getc (f)) != EOF)
--- 943,953 ----
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. */
!
symbol_mode = 0x04;
while ((c = getc (f)) != EOF)
*************** gld${EMULATION_NAME}_create_output_secti
*** 1291,1299 ****
{
/* __rtinit */
if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
! && (link_info.init_function != NULL || link_info.fini_function != NULL))
{
-
initfini_file = lang_add_input_file ("initfini",
lang_input_file_is_file_enum,
NULL);
--- 1290,1299 ----
{
/* __rtinit */
if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
! && (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);
*************** gld${EMULATION_NAME}_create_output_secti
*** 1311,1321 ****
/* 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))
{
einfo ("%X%P: can not create BFD %E\n");
return;
}
}
}
--- 1311,1326 ----
/* 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,
! 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);
}
}