1*3d8817e4Smiod /* BFD back-end for i386 a.out binaries under LynxOS. 2*3d8817e4Smiod Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2002, 3*3d8817e4Smiod 2003 Free Software Foundation, Inc. 4*3d8817e4Smiod 5*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library. 6*3d8817e4Smiod 7*3d8817e4Smiod This program is free software; you can redistribute it and/or modify 8*3d8817e4Smiod it under the terms of the GNU General Public License as published by 9*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or 10*3d8817e4Smiod (at your option) any later version. 11*3d8817e4Smiod 12*3d8817e4Smiod This program is distributed in the hope that it will be useful, 13*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of 14*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*3d8817e4Smiod GNU General Public License for more details. 16*3d8817e4Smiod 17*3d8817e4Smiod You should have received a copy of the GNU General Public License 18*3d8817e4Smiod along with this program; if not, write to the Free Software 19*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20*3d8817e4Smiod 21*3d8817e4Smiod #define N_SHARED_LIB(x) 0 22*3d8817e4Smiod 23*3d8817e4Smiod #define TEXT_START_ADDR 0 24*3d8817e4Smiod #define TARGET_PAGE_SIZE 4096 25*3d8817e4Smiod #define SEGMENT_SIZE TARGET_PAGE_SIZE 26*3d8817e4Smiod #define DEFAULT_ARCH bfd_arch_i386 27*3d8817e4Smiod 28*3d8817e4Smiod /* Do not "beautify" the CONCAT* macro args. Traditional C will not 29*3d8817e4Smiod remove whitespace added here, and thus will fail to concatenate 30*3d8817e4Smiod the tokens. */ 31*3d8817e4Smiod #define MY(OP) CONCAT2 (i386lynx_aout_,OP) 32*3d8817e4Smiod #define TARGETNAME "a.out-i386-lynx" 33*3d8817e4Smiod 34*3d8817e4Smiod #include "bfd.h" 35*3d8817e4Smiod #include "sysdep.h" 36*3d8817e4Smiod #include "libbfd.h" 37*3d8817e4Smiod 38*3d8817e4Smiod #ifndef WRITE_HEADERS 39*3d8817e4Smiod #define WRITE_HEADERS(abfd, execp) \ 40*3d8817e4Smiod { \ 41*3d8817e4Smiod bfd_size_type text_size; /* dummy vars */ \ 42*3d8817e4Smiod file_ptr text_end; \ 43*3d8817e4Smiod if (adata(abfd).magic == undecided_magic) \ 44*3d8817e4Smiod NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ 45*3d8817e4Smiod \ 46*3d8817e4Smiod execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ 47*3d8817e4Smiod execp->a_entry = bfd_get_start_address (abfd); \ 48*3d8817e4Smiod \ 49*3d8817e4Smiod execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ 50*3d8817e4Smiod obj_reloc_entry_size (abfd)); \ 51*3d8817e4Smiod execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ 52*3d8817e4Smiod obj_reloc_entry_size (abfd)); \ 53*3d8817e4Smiod NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ 54*3d8817e4Smiod \ 55*3d8817e4Smiod if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \ 56*3d8817e4Smiod || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \ 57*3d8817e4Smiod abfd) != EXEC_BYTES_SIZE) \ 58*3d8817e4Smiod return FALSE; \ 59*3d8817e4Smiod /* Now write out reloc info, followed by syms and strings */ \ 60*3d8817e4Smiod \ 61*3d8817e4Smiod if (bfd_get_symcount (abfd) != 0) \ 62*3d8817e4Smiod { \ 63*3d8817e4Smiod if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) \ 64*3d8817e4Smiod != 0) \ 65*3d8817e4Smiod return FALSE; \ 66*3d8817e4Smiod \ 67*3d8817e4Smiod if (! NAME(aout,write_syms) (abfd)) return FALSE; \ 68*3d8817e4Smiod \ 69*3d8817e4Smiod if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) \ 70*3d8817e4Smiod != 0) \ 71*3d8817e4Smiod return FALSE; \ 72*3d8817e4Smiod \ 73*3d8817e4Smiod if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \ 74*3d8817e4Smiod return FALSE; \ 75*3d8817e4Smiod if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) \ 76*3d8817e4Smiod != 0) \ 77*3d8817e4Smiod return 0; \ 78*3d8817e4Smiod \ 79*3d8817e4Smiod if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd))) \ 80*3d8817e4Smiod return FALSE; \ 81*3d8817e4Smiod } \ 82*3d8817e4Smiod } 83*3d8817e4Smiod #endif 84*3d8817e4Smiod 85*3d8817e4Smiod #include "libaout.h" 86*3d8817e4Smiod #include "aout/aout64.h" 87*3d8817e4Smiod 88*3d8817e4Smiod void NAME (lynx,swap_std_reloc_out) 89*3d8817e4Smiod PARAMS ((bfd *, arelent *, struct reloc_std_external *)); 90*3d8817e4Smiod void NAME (lynx,swap_ext_reloc_out) 91*3d8817e4Smiod PARAMS ((bfd *, arelent *, struct reloc_ext_external *)); 92*3d8817e4Smiod void NAME (lynx,swap_ext_reloc_in) 93*3d8817e4Smiod PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **, 94*3d8817e4Smiod bfd_size_type)); 95*3d8817e4Smiod void NAME (lynx,swap_std_reloc_in) 96*3d8817e4Smiod PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **, 97*3d8817e4Smiod bfd_size_type)); 98*3d8817e4Smiod bfd_boolean NAME (lynx,slurp_reloc_table) 99*3d8817e4Smiod PARAMS ((bfd *, sec_ptr, asymbol **)); 100*3d8817e4Smiod bfd_boolean NAME (lynx,squirt_out_relocs) 101*3d8817e4Smiod PARAMS ((bfd *, asection *)); 102*3d8817e4Smiod long NAME (lynx,canonicalize_reloc) 103*3d8817e4Smiod PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); 104*3d8817e4Smiod 105*3d8817e4Smiod #ifdef LYNX_CORE 106*3d8817e4Smiod 107*3d8817e4Smiod char *lynx_core_file_failing_command (); 108*3d8817e4Smiod int lynx_core_file_failing_signal (); 109*3d8817e4Smiod bfd_boolean lynx_core_file_matches_executable_p (); 110*3d8817e4Smiod const bfd_target *lynx_core_file_p (); 111*3d8817e4Smiod 112*3d8817e4Smiod #define MY_core_file_failing_command lynx_core_file_failing_command 113*3d8817e4Smiod #define MY_core_file_failing_signal lynx_core_file_failing_signal 114*3d8817e4Smiod #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p 115*3d8817e4Smiod #define MY_core_file_p lynx_core_file_p 116*3d8817e4Smiod 117*3d8817e4Smiod #endif /* LYNX_CORE */ 118*3d8817e4Smiod 119*3d8817e4Smiod 120*3d8817e4Smiod #define KEEPIT udata.i 121*3d8817e4Smiod 122*3d8817e4Smiod extern reloc_howto_type aout_32_ext_howto_table[]; 123*3d8817e4Smiod extern reloc_howto_type aout_32_std_howto_table[]; 124*3d8817e4Smiod 125*3d8817e4Smiod /* Standard reloc stuff */ 126*3d8817e4Smiod /* Output standard relocation information to a file in target byte order. */ 127*3d8817e4Smiod 128*3d8817e4Smiod void 129*3d8817e4Smiod NAME(lynx,swap_std_reloc_out) (abfd, g, natptr) 130*3d8817e4Smiod bfd *abfd; 131*3d8817e4Smiod arelent *g; 132*3d8817e4Smiod struct reloc_std_external *natptr; 133*3d8817e4Smiod { 134*3d8817e4Smiod int r_index; 135*3d8817e4Smiod asymbol *sym = *(g->sym_ptr_ptr); 136*3d8817e4Smiod int r_extern; 137*3d8817e4Smiod unsigned int r_length; 138*3d8817e4Smiod int r_pcrel; 139*3d8817e4Smiod int r_baserel, r_jmptable, r_relative; 140*3d8817e4Smiod unsigned int r_addend; 141*3d8817e4Smiod asection *output_section = sym->section->output_section; 142*3d8817e4Smiod 143*3d8817e4Smiod PUT_WORD (abfd, g->address, natptr->r_address); 144*3d8817e4Smiod 145*3d8817e4Smiod r_length = g->howto->size; /* Size as a power of two */ 146*3d8817e4Smiod r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ 147*3d8817e4Smiod /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ 148*3d8817e4Smiod r_baserel = 0; 149*3d8817e4Smiod r_jmptable = 0; 150*3d8817e4Smiod r_relative = 0; 151*3d8817e4Smiod 152*3d8817e4Smiod r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; 153*3d8817e4Smiod 154*3d8817e4Smiod /* name was clobbered by aout_write_syms to be symbol index */ 155*3d8817e4Smiod 156*3d8817e4Smiod /* If this relocation is relative to a symbol then set the 157*3d8817e4Smiod r_index to the symbols index, and the r_extern bit. 158*3d8817e4Smiod 159*3d8817e4Smiod Absolute symbols can come in in two ways, either as an offset 160*3d8817e4Smiod from the abs section, or as a symbol which has an abs value. 161*3d8817e4Smiod check for that here 162*3d8817e4Smiod */ 163*3d8817e4Smiod 164*3d8817e4Smiod 165*3d8817e4Smiod if (bfd_is_com_section (output_section) 166*3d8817e4Smiod || bfd_is_abs_section (output_section) 167*3d8817e4Smiod || bfd_is_und_section (output_section)) 168*3d8817e4Smiod { 169*3d8817e4Smiod if (bfd_abs_section_ptr->symbol == sym) 170*3d8817e4Smiod { 171*3d8817e4Smiod /* Whoops, looked like an abs symbol, but is really an offset 172*3d8817e4Smiod from the abs section */ 173*3d8817e4Smiod r_index = 0; 174*3d8817e4Smiod r_extern = 0; 175*3d8817e4Smiod } 176*3d8817e4Smiod else 177*3d8817e4Smiod { 178*3d8817e4Smiod /* Fill in symbol */ 179*3d8817e4Smiod r_extern = 1; 180*3d8817e4Smiod r_index = (*g->sym_ptr_ptr)->KEEPIT; 181*3d8817e4Smiod } 182*3d8817e4Smiod } 183*3d8817e4Smiod else 184*3d8817e4Smiod { 185*3d8817e4Smiod /* Just an ordinary section */ 186*3d8817e4Smiod r_extern = 0; 187*3d8817e4Smiod r_index = output_section->target_index; 188*3d8817e4Smiod } 189*3d8817e4Smiod 190*3d8817e4Smiod /* now the fun stuff */ 191*3d8817e4Smiod if (bfd_header_big_endian (abfd)) 192*3d8817e4Smiod { 193*3d8817e4Smiod natptr->r_index[0] = r_index >> 16; 194*3d8817e4Smiod natptr->r_index[1] = r_index >> 8; 195*3d8817e4Smiod natptr->r_index[2] = r_index; 196*3d8817e4Smiod natptr->r_type[0] = 197*3d8817e4Smiod (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 198*3d8817e4Smiod | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 199*3d8817e4Smiod | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) 200*3d8817e4Smiod | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) 201*3d8817e4Smiod | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) 202*3d8817e4Smiod | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); 203*3d8817e4Smiod } 204*3d8817e4Smiod else 205*3d8817e4Smiod { 206*3d8817e4Smiod natptr->r_index[2] = r_index >> 16; 207*3d8817e4Smiod natptr->r_index[1] = r_index >> 8; 208*3d8817e4Smiod natptr->r_index[0] = r_index; 209*3d8817e4Smiod natptr->r_type[0] = 210*3d8817e4Smiod (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 211*3d8817e4Smiod | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 212*3d8817e4Smiod | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) 213*3d8817e4Smiod | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) 214*3d8817e4Smiod | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) 215*3d8817e4Smiod | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); 216*3d8817e4Smiod } 217*3d8817e4Smiod } 218*3d8817e4Smiod 219*3d8817e4Smiod 220*3d8817e4Smiod /* Extended stuff */ 221*3d8817e4Smiod /* Output extended relocation information to a file in target byte order. */ 222*3d8817e4Smiod 223*3d8817e4Smiod void 224*3d8817e4Smiod NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr) 225*3d8817e4Smiod bfd *abfd; 226*3d8817e4Smiod arelent *g; 227*3d8817e4Smiod register struct reloc_ext_external *natptr; 228*3d8817e4Smiod { 229*3d8817e4Smiod int r_index; 230*3d8817e4Smiod int r_extern; 231*3d8817e4Smiod unsigned int r_type; 232*3d8817e4Smiod unsigned int r_addend; 233*3d8817e4Smiod asymbol *sym = *(g->sym_ptr_ptr); 234*3d8817e4Smiod asection *output_section = sym->section->output_section; 235*3d8817e4Smiod 236*3d8817e4Smiod PUT_WORD (abfd, g->address, natptr->r_address); 237*3d8817e4Smiod 238*3d8817e4Smiod r_type = (unsigned int) g->howto->type; 239*3d8817e4Smiod 240*3d8817e4Smiod r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; 241*3d8817e4Smiod 242*3d8817e4Smiod 243*3d8817e4Smiod /* If this relocation is relative to a symbol then set the 244*3d8817e4Smiod r_index to the symbols index, and the r_extern bit. 245*3d8817e4Smiod 246*3d8817e4Smiod Absolute symbols can come in in two ways, either as an offset 247*3d8817e4Smiod from the abs section, or as a symbol which has an abs value. 248*3d8817e4Smiod check for that here 249*3d8817e4Smiod */ 250*3d8817e4Smiod 251*3d8817e4Smiod if (bfd_is_com_section (output_section) 252*3d8817e4Smiod || bfd_is_abs_section (output_section) 253*3d8817e4Smiod || bfd_is_und_section (output_section)) 254*3d8817e4Smiod { 255*3d8817e4Smiod if (bfd_abs_section_ptr->symbol == sym) 256*3d8817e4Smiod { 257*3d8817e4Smiod /* Whoops, looked like an abs symbol, but is really an offset 258*3d8817e4Smiod from the abs section */ 259*3d8817e4Smiod r_index = 0; 260*3d8817e4Smiod r_extern = 0; 261*3d8817e4Smiod } 262*3d8817e4Smiod else 263*3d8817e4Smiod { 264*3d8817e4Smiod r_extern = 1; 265*3d8817e4Smiod r_index = (*g->sym_ptr_ptr)->KEEPIT; 266*3d8817e4Smiod } 267*3d8817e4Smiod } 268*3d8817e4Smiod else 269*3d8817e4Smiod { 270*3d8817e4Smiod /* Just an ordinary section */ 271*3d8817e4Smiod r_extern = 0; 272*3d8817e4Smiod r_index = output_section->target_index; 273*3d8817e4Smiod } 274*3d8817e4Smiod 275*3d8817e4Smiod 276*3d8817e4Smiod /* now the fun stuff */ 277*3d8817e4Smiod if (bfd_header_big_endian (abfd)) 278*3d8817e4Smiod { 279*3d8817e4Smiod natptr->r_index[0] = r_index >> 16; 280*3d8817e4Smiod natptr->r_index[1] = r_index >> 8; 281*3d8817e4Smiod natptr->r_index[2] = r_index; 282*3d8817e4Smiod natptr->r_type[0] = 283*3d8817e4Smiod (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) 284*3d8817e4Smiod | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG); 285*3d8817e4Smiod } 286*3d8817e4Smiod else 287*3d8817e4Smiod { 288*3d8817e4Smiod natptr->r_index[2] = r_index >> 16; 289*3d8817e4Smiod natptr->r_index[1] = r_index >> 8; 290*3d8817e4Smiod natptr->r_index[0] = r_index; 291*3d8817e4Smiod natptr->r_type[0] = 292*3d8817e4Smiod (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) 293*3d8817e4Smiod | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); 294*3d8817e4Smiod } 295*3d8817e4Smiod 296*3d8817e4Smiod PUT_WORD (abfd, r_addend, natptr->r_addend); 297*3d8817e4Smiod } 298*3d8817e4Smiod 299*3d8817e4Smiod /* BFD deals internally with all things based from the section they're 300*3d8817e4Smiod in. so, something in 10 bytes into a text section with a base of 301*3d8817e4Smiod 50 would have a symbol (.text+10) and know .text vma was 50. 302*3d8817e4Smiod 303*3d8817e4Smiod Aout keeps all it's symbols based from zero, so the symbol would 304*3d8817e4Smiod contain 60. This macro subs the base of each section from the value 305*3d8817e4Smiod to give the true offset from the section */ 306*3d8817e4Smiod 307*3d8817e4Smiod 308*3d8817e4Smiod #define MOVE_ADDRESS(ad) \ 309*3d8817e4Smiod if (r_extern) { \ 310*3d8817e4Smiod /* undefined symbol */ \ 311*3d8817e4Smiod cache_ptr->sym_ptr_ptr = symbols + r_index; \ 312*3d8817e4Smiod cache_ptr->addend = ad; \ 313*3d8817e4Smiod } else { \ 314*3d8817e4Smiod /* defined, section relative. replace symbol with pointer to \ 315*3d8817e4Smiod symbol which points to section */ \ 316*3d8817e4Smiod switch (r_index) { \ 317*3d8817e4Smiod case N_TEXT: \ 318*3d8817e4Smiod case N_TEXT | N_EXT: \ 319*3d8817e4Smiod cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ 320*3d8817e4Smiod cache_ptr->addend = ad - su->textsec->vma; \ 321*3d8817e4Smiod break; \ 322*3d8817e4Smiod case N_DATA: \ 323*3d8817e4Smiod case N_DATA | N_EXT: \ 324*3d8817e4Smiod cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ 325*3d8817e4Smiod cache_ptr->addend = ad - su->datasec->vma; \ 326*3d8817e4Smiod break; \ 327*3d8817e4Smiod case N_BSS: \ 328*3d8817e4Smiod case N_BSS | N_EXT: \ 329*3d8817e4Smiod cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ 330*3d8817e4Smiod cache_ptr->addend = ad - su->bsssec->vma; \ 331*3d8817e4Smiod break; \ 332*3d8817e4Smiod default: \ 333*3d8817e4Smiod case N_ABS: \ 334*3d8817e4Smiod case N_ABS | N_EXT: \ 335*3d8817e4Smiod cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ 336*3d8817e4Smiod cache_ptr->addend = ad; \ 337*3d8817e4Smiod break; \ 338*3d8817e4Smiod } \ 339*3d8817e4Smiod } \ 340*3d8817e4Smiod 341*3d8817e4Smiod void 342*3d8817e4Smiod NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) 343*3d8817e4Smiod bfd *abfd; 344*3d8817e4Smiod struct reloc_ext_external *bytes; 345*3d8817e4Smiod arelent *cache_ptr; 346*3d8817e4Smiod asymbol **symbols; 347*3d8817e4Smiod bfd_size_type symcount ATTRIBUTE_UNUSED; 348*3d8817e4Smiod { 349*3d8817e4Smiod int r_index; 350*3d8817e4Smiod int r_extern; 351*3d8817e4Smiod unsigned int r_type; 352*3d8817e4Smiod struct aoutdata *su = &(abfd->tdata.aout_data->a); 353*3d8817e4Smiod 354*3d8817e4Smiod cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); 355*3d8817e4Smiod 356*3d8817e4Smiod r_index = bytes->r_index[1]; 357*3d8817e4Smiod r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG)); 358*3d8817e4Smiod r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG) 359*3d8817e4Smiod >> RELOC_EXT_BITS_TYPE_SH_BIG; 360*3d8817e4Smiod 361*3d8817e4Smiod cache_ptr->howto = aout_32_ext_howto_table + r_type; 362*3d8817e4Smiod MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend)); 363*3d8817e4Smiod } 364*3d8817e4Smiod 365*3d8817e4Smiod void 366*3d8817e4Smiod NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) 367*3d8817e4Smiod bfd *abfd; 368*3d8817e4Smiod struct reloc_std_external *bytes; 369*3d8817e4Smiod arelent *cache_ptr; 370*3d8817e4Smiod asymbol **symbols; 371*3d8817e4Smiod bfd_size_type symcount ATTRIBUTE_UNUSED; 372*3d8817e4Smiod { 373*3d8817e4Smiod int r_index; 374*3d8817e4Smiod int r_extern; 375*3d8817e4Smiod unsigned int r_length; 376*3d8817e4Smiod int r_pcrel; 377*3d8817e4Smiod int r_baserel, r_jmptable, r_relative; 378*3d8817e4Smiod struct aoutdata *su = &(abfd->tdata.aout_data->a); 379*3d8817e4Smiod 380*3d8817e4Smiod cache_ptr->address = H_GET_32 (abfd, bytes->r_address); 381*3d8817e4Smiod 382*3d8817e4Smiod r_index = bytes->r_index[1]; 383*3d8817e4Smiod r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG)); 384*3d8817e4Smiod r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG)); 385*3d8817e4Smiod r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG)); 386*3d8817e4Smiod r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG)); 387*3d8817e4Smiod r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG)); 388*3d8817e4Smiod r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) 389*3d8817e4Smiod >> RELOC_STD_BITS_LENGTH_SH_BIG; 390*3d8817e4Smiod 391*3d8817e4Smiod cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel; 392*3d8817e4Smiod /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ 393*3d8817e4Smiod 394*3d8817e4Smiod MOVE_ADDRESS (0); 395*3d8817e4Smiod } 396*3d8817e4Smiod 397*3d8817e4Smiod /* Reloc hackery */ 398*3d8817e4Smiod 399*3d8817e4Smiod bfd_boolean 400*3d8817e4Smiod NAME(lynx,slurp_reloc_table) (abfd, asect, symbols) 401*3d8817e4Smiod bfd *abfd; 402*3d8817e4Smiod sec_ptr asect; 403*3d8817e4Smiod asymbol **symbols; 404*3d8817e4Smiod { 405*3d8817e4Smiod bfd_size_type count; 406*3d8817e4Smiod bfd_size_type reloc_size; 407*3d8817e4Smiod PTR relocs; 408*3d8817e4Smiod arelent *reloc_cache; 409*3d8817e4Smiod size_t each_size; 410*3d8817e4Smiod 411*3d8817e4Smiod if (asect->relocation) 412*3d8817e4Smiod return TRUE; 413*3d8817e4Smiod 414*3d8817e4Smiod if (asect->flags & SEC_CONSTRUCTOR) 415*3d8817e4Smiod return TRUE; 416*3d8817e4Smiod 417*3d8817e4Smiod if (asect == obj_datasec (abfd)) 418*3d8817e4Smiod { 419*3d8817e4Smiod reloc_size = exec_hdr (abfd)->a_drsize; 420*3d8817e4Smiod goto doit; 421*3d8817e4Smiod } 422*3d8817e4Smiod 423*3d8817e4Smiod if (asect == obj_textsec (abfd)) 424*3d8817e4Smiod { 425*3d8817e4Smiod reloc_size = exec_hdr (abfd)->a_trsize; 426*3d8817e4Smiod goto doit; 427*3d8817e4Smiod } 428*3d8817e4Smiod 429*3d8817e4Smiod bfd_set_error (bfd_error_invalid_operation); 430*3d8817e4Smiod return FALSE; 431*3d8817e4Smiod 432*3d8817e4Smiod doit: 433*3d8817e4Smiod if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) 434*3d8817e4Smiod return FALSE; 435*3d8817e4Smiod each_size = obj_reloc_entry_size (abfd); 436*3d8817e4Smiod 437*3d8817e4Smiod count = reloc_size / each_size; 438*3d8817e4Smiod 439*3d8817e4Smiod 440*3d8817e4Smiod reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent)); 441*3d8817e4Smiod if (!reloc_cache && count != 0) 442*3d8817e4Smiod return FALSE; 443*3d8817e4Smiod 444*3d8817e4Smiod relocs = (PTR) bfd_alloc (abfd, reloc_size); 445*3d8817e4Smiod if (!relocs && reloc_size != 0) 446*3d8817e4Smiod { 447*3d8817e4Smiod free (reloc_cache); 448*3d8817e4Smiod return FALSE; 449*3d8817e4Smiod } 450*3d8817e4Smiod 451*3d8817e4Smiod if (bfd_bread (relocs, reloc_size, abfd) != reloc_size) 452*3d8817e4Smiod { 453*3d8817e4Smiod bfd_release (abfd, relocs); 454*3d8817e4Smiod free (reloc_cache); 455*3d8817e4Smiod return FALSE; 456*3d8817e4Smiod } 457*3d8817e4Smiod 458*3d8817e4Smiod if (each_size == RELOC_EXT_SIZE) 459*3d8817e4Smiod { 460*3d8817e4Smiod register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; 461*3d8817e4Smiod unsigned int counter = 0; 462*3d8817e4Smiod arelent *cache_ptr = reloc_cache; 463*3d8817e4Smiod 464*3d8817e4Smiod for (; counter < count; counter++, rptr++, cache_ptr++) 465*3d8817e4Smiod { 466*3d8817e4Smiod NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, 467*3d8817e4Smiod (bfd_size_type) bfd_get_symcount (abfd)); 468*3d8817e4Smiod } 469*3d8817e4Smiod } 470*3d8817e4Smiod else 471*3d8817e4Smiod { 472*3d8817e4Smiod register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; 473*3d8817e4Smiod unsigned int counter = 0; 474*3d8817e4Smiod arelent *cache_ptr = reloc_cache; 475*3d8817e4Smiod 476*3d8817e4Smiod for (; counter < count; counter++, rptr++, cache_ptr++) 477*3d8817e4Smiod { 478*3d8817e4Smiod NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, 479*3d8817e4Smiod (bfd_size_type) bfd_get_symcount (abfd)); 480*3d8817e4Smiod } 481*3d8817e4Smiod 482*3d8817e4Smiod } 483*3d8817e4Smiod 484*3d8817e4Smiod bfd_release (abfd, relocs); 485*3d8817e4Smiod asect->relocation = reloc_cache; 486*3d8817e4Smiod asect->reloc_count = count; 487*3d8817e4Smiod return TRUE; 488*3d8817e4Smiod } 489*3d8817e4Smiod 490*3d8817e4Smiod 491*3d8817e4Smiod 492*3d8817e4Smiod /* Write out a relocation section into an object file. */ 493*3d8817e4Smiod 494*3d8817e4Smiod bfd_boolean 495*3d8817e4Smiod NAME(lynx,squirt_out_relocs) (abfd, section) 496*3d8817e4Smiod bfd *abfd; 497*3d8817e4Smiod asection *section; 498*3d8817e4Smiod { 499*3d8817e4Smiod arelent **generic; 500*3d8817e4Smiod unsigned char *native, *natptr; 501*3d8817e4Smiod size_t each_size; 502*3d8817e4Smiod 503*3d8817e4Smiod unsigned int count = section->reloc_count; 504*3d8817e4Smiod bfd_size_type natsize; 505*3d8817e4Smiod 506*3d8817e4Smiod if (count == 0) 507*3d8817e4Smiod return TRUE; 508*3d8817e4Smiod 509*3d8817e4Smiod each_size = obj_reloc_entry_size (abfd); 510*3d8817e4Smiod natsize = count; 511*3d8817e4Smiod natsize *= each_size; 512*3d8817e4Smiod native = (unsigned char *) bfd_zalloc (abfd, natsize); 513*3d8817e4Smiod if (!native) 514*3d8817e4Smiod return FALSE; 515*3d8817e4Smiod 516*3d8817e4Smiod generic = section->orelocation; 517*3d8817e4Smiod 518*3d8817e4Smiod if (each_size == RELOC_EXT_SIZE) 519*3d8817e4Smiod { 520*3d8817e4Smiod for (natptr = native; 521*3d8817e4Smiod count != 0; 522*3d8817e4Smiod --count, natptr += each_size, ++generic) 523*3d8817e4Smiod NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr); 524*3d8817e4Smiod } 525*3d8817e4Smiod else 526*3d8817e4Smiod { 527*3d8817e4Smiod for (natptr = native; 528*3d8817e4Smiod count != 0; 529*3d8817e4Smiod --count, natptr += each_size, ++generic) 530*3d8817e4Smiod NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr); 531*3d8817e4Smiod } 532*3d8817e4Smiod 533*3d8817e4Smiod if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize) 534*3d8817e4Smiod { 535*3d8817e4Smiod bfd_release (abfd, native); 536*3d8817e4Smiod return FALSE; 537*3d8817e4Smiod } 538*3d8817e4Smiod bfd_release (abfd, native); 539*3d8817e4Smiod 540*3d8817e4Smiod return TRUE; 541*3d8817e4Smiod } 542*3d8817e4Smiod 543*3d8817e4Smiod /* This is stupid. This function should be a boolean predicate */ 544*3d8817e4Smiod long 545*3d8817e4Smiod NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols) 546*3d8817e4Smiod bfd *abfd; 547*3d8817e4Smiod sec_ptr section; 548*3d8817e4Smiod arelent **relptr; 549*3d8817e4Smiod asymbol **symbols; 550*3d8817e4Smiod { 551*3d8817e4Smiod arelent *tblptr = section->relocation; 552*3d8817e4Smiod unsigned int count; 553*3d8817e4Smiod 554*3d8817e4Smiod if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols))) 555*3d8817e4Smiod return -1; 556*3d8817e4Smiod 557*3d8817e4Smiod if (section->flags & SEC_CONSTRUCTOR) 558*3d8817e4Smiod { 559*3d8817e4Smiod arelent_chain *chain = section->constructor_chain; 560*3d8817e4Smiod for (count = 0; count < section->reloc_count; count++) 561*3d8817e4Smiod { 562*3d8817e4Smiod *relptr++ = &chain->relent; 563*3d8817e4Smiod chain = chain->next; 564*3d8817e4Smiod } 565*3d8817e4Smiod } 566*3d8817e4Smiod else 567*3d8817e4Smiod { 568*3d8817e4Smiod tblptr = section->relocation; 569*3d8817e4Smiod 570*3d8817e4Smiod for (count = 0; count++ < section->reloc_count;) 571*3d8817e4Smiod { 572*3d8817e4Smiod *relptr++ = tblptr++; 573*3d8817e4Smiod } 574*3d8817e4Smiod } 575*3d8817e4Smiod *relptr = 0; 576*3d8817e4Smiod 577*3d8817e4Smiod return section->reloc_count; 578*3d8817e4Smiod } 579*3d8817e4Smiod 580*3d8817e4Smiod #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc) 581*3d8817e4Smiod 582*3d8817e4Smiod #include "aout-target.h" 583