aboutsummaryrefslogtreecommitdiff
path: root/bfd/coff-rs6000.c
diff options
context:
space:
mode:
authorTom Rix <trix@redhat.com>2002-02-19 05:01:40 +0000
committerTom Rix <trix@redhat.com>2002-02-19 05:01:40 +0000
commit69f284c74ed40f90e9358f9df122d46194ed91b3 (patch)
treef3a912d0dbea4323bc5fd390508946abe6a06d59 /bfd/coff-rs6000.c
parent55c0a857d61b0e4ed4c1ee7e4afd5c1771a45859 (diff)
downloadfsf-binutils-gdb-69f284c74ed40f90e9358f9df122d46194ed91b3.zip
fsf-binutils-gdb-69f284c74ed40f90e9358f9df122d46194ed91b3.tar.gz
fsf-binutils-gdb-69f284c74ed40f90e9358f9df122d46194ed91b3.tar.bz2
Add support for -brtl, run time linking, to AIX ld.
Diffstat (limited to 'bfd/coff-rs6000.c')
-rw-r--r--bfd/coff-rs6000.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 2772929..75ed122 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -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. */