Add support for -brtl, run time linking, to AIX ld.
This commit is contained in:
parent
55c0a857d6
commit
69f284c74e
9 changed files with 262 additions and 166 deletions
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
149
bfd/xcofflink.c
149
bfd/xcofflink.c
|
@ -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"));
|
||||
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;
|
||||
}
|
||||
|
||||
/* __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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue