12159047fSniklas /* BFD back-end for i386 a.out binaries under LynxOS. 2*c074d1c9Sdrahn Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2001, 2002, 2003 3b305b0f1Sespie Free Software Foundation, Inc. 42159047fSniklas 52159047fSniklas This file is part of BFD, the Binary File Descriptor library. 62159047fSniklas 72159047fSniklas This program is free software; you can redistribute it and/or modify 82159047fSniklas it under the terms of the GNU General Public License as published by 92159047fSniklas the Free Software Foundation; either version 2 of the License, or 102159047fSniklas (at your option) any later version. 112159047fSniklas 122159047fSniklas This program is distributed in the hope that it will be useful, 132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of 142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 152159047fSniklas GNU General Public License for more details. 162159047fSniklas 172159047fSniklas You should have received a copy of the GNU General Public License 182159047fSniklas along with this program; if not, write to the Free Software 192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 202159047fSniklas 212159047fSniklas #define N_SHARED_LIB(x) 0 222159047fSniklas 232159047fSniklas #define TEXT_START_ADDR 0 242159047fSniklas #define TARGET_PAGE_SIZE 4096 252159047fSniklas #define SEGMENT_SIZE TARGET_PAGE_SIZE 262159047fSniklas #define DEFAULT_ARCH bfd_arch_i386 272159047fSniklas 28*c074d1c9Sdrahn /* Do not "beautify" the CONCAT* macro args. Traditional C will not 29*c074d1c9Sdrahn remove whitespace added here, and thus will fail to concatenate 30*c074d1c9Sdrahn the tokens. */ 31*c074d1c9Sdrahn #define MY(OP) CONCAT2 (i386lynx_aout_,OP) 322159047fSniklas #define TARGETNAME "a.out-i386-lynx" 332159047fSniklas 342159047fSniklas #include "bfd.h" 352159047fSniklas #include "sysdep.h" 362159047fSniklas #include "libbfd.h" 372159047fSniklas 382159047fSniklas #ifndef WRITE_HEADERS 392159047fSniklas #define WRITE_HEADERS(abfd, execp) \ 402159047fSniklas { \ 412159047fSniklas bfd_size_type text_size; /* dummy vars */ \ 422159047fSniklas file_ptr text_end; \ 432159047fSniklas if (adata(abfd).magic == undecided_magic) \ 442159047fSniklas NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ 452159047fSniklas \ 462159047fSniklas execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ 472159047fSniklas execp->a_entry = bfd_get_start_address (abfd); \ 482159047fSniklas \ 492159047fSniklas execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ 502159047fSniklas obj_reloc_entry_size (abfd)); \ 512159047fSniklas execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ 522159047fSniklas obj_reloc_entry_size (abfd)); \ 532159047fSniklas NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ 542159047fSniklas \ 55*c074d1c9Sdrahn if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \ 56*c074d1c9Sdrahn || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \ 57*c074d1c9Sdrahn abfd) != EXEC_BYTES_SIZE) \ 58*c074d1c9Sdrahn return FALSE; \ 592159047fSniklas /* Now write out reloc info, followed by syms and strings */ \ 602159047fSniklas \ 612159047fSniklas if (bfd_get_symcount (abfd) != 0) \ 622159047fSniklas { \ 632159047fSniklas if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) \ 642159047fSniklas != 0) \ 65*c074d1c9Sdrahn return FALSE; \ 662159047fSniklas \ 67*c074d1c9Sdrahn if (! NAME(aout,write_syms) (abfd)) return FALSE; \ 682159047fSniklas \ 692159047fSniklas if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) \ 702159047fSniklas != 0) \ 71*c074d1c9Sdrahn return FALSE; \ 722159047fSniklas \ 732159047fSniklas if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \ 74*c074d1c9Sdrahn return FALSE; \ 752159047fSniklas if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) \ 762159047fSniklas != 0) \ 772159047fSniklas return 0; \ 782159047fSniklas \ 792159047fSniklas if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd))) \ 80*c074d1c9Sdrahn return FALSE; \ 812159047fSniklas } \ 822159047fSniklas } 832159047fSniklas #endif 842159047fSniklas 852159047fSniklas #include "libaout.h" 862159047fSniklas #include "aout/aout64.h" 872159047fSniklas 88*c074d1c9Sdrahn void NAME (lynx,swap_std_reloc_out) 89*c074d1c9Sdrahn PARAMS ((bfd *, arelent *, struct reloc_std_external *)); 90*c074d1c9Sdrahn void NAME (lynx,swap_ext_reloc_out) 91*c074d1c9Sdrahn PARAMS ((bfd *, arelent *, struct reloc_ext_external *)); 92*c074d1c9Sdrahn void NAME (lynx,swap_ext_reloc_in) 93*c074d1c9Sdrahn PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **, 94*c074d1c9Sdrahn bfd_size_type)); 95*c074d1c9Sdrahn void NAME (lynx,swap_std_reloc_in) 96*c074d1c9Sdrahn PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **, 97*c074d1c9Sdrahn bfd_size_type)); 98*c074d1c9Sdrahn bfd_boolean NAME (lynx,slurp_reloc_table) 99*c074d1c9Sdrahn PARAMS ((bfd *, sec_ptr, asymbol **)); 100*c074d1c9Sdrahn bfd_boolean NAME (lynx,squirt_out_relocs) 101*c074d1c9Sdrahn PARAMS ((bfd *, asection *)); 102*c074d1c9Sdrahn long NAME (lynx,canonicalize_reloc) 103*c074d1c9Sdrahn PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); 104*c074d1c9Sdrahn 1052159047fSniklas #ifdef LYNX_CORE 1062159047fSniklas 1072159047fSniklas char *lynx_core_file_failing_command (); 1082159047fSniklas int lynx_core_file_failing_signal (); 109*c074d1c9Sdrahn bfd_boolean lynx_core_file_matches_executable_p (); 1102159047fSniklas const bfd_target *lynx_core_file_p (); 1112159047fSniklas 1122159047fSniklas #define MY_core_file_failing_command lynx_core_file_failing_command 1132159047fSniklas #define MY_core_file_failing_signal lynx_core_file_failing_signal 1142159047fSniklas #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p 1152159047fSniklas #define MY_core_file_p lynx_core_file_p 1162159047fSniklas 1172159047fSniklas #endif /* LYNX_CORE */ 1182159047fSniklas 1192159047fSniklas 1200c6d0228Sniklas #define KEEPIT udata.i 1212159047fSniklas 1222159047fSniklas extern reloc_howto_type aout_32_ext_howto_table[]; 1232159047fSniklas extern reloc_howto_type aout_32_std_howto_table[]; 1242159047fSniklas 1252159047fSniklas /* Standard reloc stuff */ 1262159047fSniklas /* Output standard relocation information to a file in target byte order. */ 1272159047fSniklas 1282159047fSniklas void 1292159047fSniklas NAME(lynx,swap_std_reloc_out) (abfd, g, natptr) 1302159047fSniklas bfd *abfd; 1312159047fSniklas arelent *g; 1322159047fSniklas struct reloc_std_external *natptr; 1332159047fSniklas { 1342159047fSniklas int r_index; 1352159047fSniklas asymbol *sym = *(g->sym_ptr_ptr); 1362159047fSniklas int r_extern; 1372159047fSniklas unsigned int r_length; 1382159047fSniklas int r_pcrel; 1392159047fSniklas int r_baserel, r_jmptable, r_relative; 1402159047fSniklas unsigned int r_addend; 1412159047fSniklas asection *output_section = sym->section->output_section; 1422159047fSniklas 1432159047fSniklas PUT_WORD (abfd, g->address, natptr->r_address); 1442159047fSniklas 1452159047fSniklas r_length = g->howto->size; /* Size as a power of two */ 1462159047fSniklas r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ 1472159047fSniklas /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ 1482159047fSniklas r_baserel = 0; 1492159047fSniklas r_jmptable = 0; 1502159047fSniklas r_relative = 0; 1512159047fSniklas 1522159047fSniklas r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; 1532159047fSniklas 1542159047fSniklas /* name was clobbered by aout_write_syms to be symbol index */ 1552159047fSniklas 1562159047fSniklas /* If this relocation is relative to a symbol then set the 1572159047fSniklas r_index to the symbols index, and the r_extern bit. 1582159047fSniklas 1592159047fSniklas Absolute symbols can come in in two ways, either as an offset 1602159047fSniklas from the abs section, or as a symbol which has an abs value. 1612159047fSniklas check for that here 1622159047fSniklas */ 1632159047fSniklas 1642159047fSniklas 1652159047fSniklas if (bfd_is_com_section (output_section) 1662159047fSniklas || bfd_is_abs_section (output_section) 1672159047fSniklas || bfd_is_und_section (output_section)) 1682159047fSniklas { 1692159047fSniklas if (bfd_abs_section_ptr->symbol == sym) 1702159047fSniklas { 1712159047fSniklas /* Whoops, looked like an abs symbol, but is really an offset 1722159047fSniklas from the abs section */ 1732159047fSniklas r_index = 0; 1742159047fSniklas r_extern = 0; 1752159047fSniklas } 1762159047fSniklas else 1772159047fSniklas { 1782159047fSniklas /* Fill in symbol */ 1792159047fSniklas r_extern = 1; 1800c6d0228Sniklas r_index = (*g->sym_ptr_ptr)->KEEPIT; 1812159047fSniklas } 1822159047fSniklas } 1832159047fSniklas else 1842159047fSniklas { 1852159047fSniklas /* Just an ordinary section */ 1862159047fSniklas r_extern = 0; 1872159047fSniklas r_index = output_section->target_index; 1882159047fSniklas } 1892159047fSniklas 1902159047fSniklas /* now the fun stuff */ 191c88b1d6cSniklas if (bfd_header_big_endian (abfd)) 1922159047fSniklas { 1932159047fSniklas natptr->r_index[0] = r_index >> 16; 1942159047fSniklas natptr->r_index[1] = r_index >> 8; 1952159047fSniklas natptr->r_index[2] = r_index; 1962159047fSniklas natptr->r_type[0] = 1972159047fSniklas (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 1982159047fSniklas | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 1992159047fSniklas | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) 2002159047fSniklas | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) 2012159047fSniklas | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) 2022159047fSniklas | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); 2032159047fSniklas } 2042159047fSniklas else 2052159047fSniklas { 2062159047fSniklas natptr->r_index[2] = r_index >> 16; 2072159047fSniklas natptr->r_index[1] = r_index >> 8; 2082159047fSniklas natptr->r_index[0] = r_index; 2092159047fSniklas natptr->r_type[0] = 2102159047fSniklas (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 2112159047fSniklas | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 2122159047fSniklas | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) 2132159047fSniklas | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) 2142159047fSniklas | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) 2152159047fSniklas | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); 2162159047fSniklas } 2172159047fSniklas } 2182159047fSniklas 2192159047fSniklas 2202159047fSniklas /* Extended stuff */ 2212159047fSniklas /* Output extended relocation information to a file in target byte order. */ 2222159047fSniklas 2232159047fSniklas void 2242159047fSniklas NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr) 2252159047fSniklas bfd *abfd; 2262159047fSniklas arelent *g; 2272159047fSniklas register struct reloc_ext_external *natptr; 2282159047fSniklas { 2292159047fSniklas int r_index; 2302159047fSniklas int r_extern; 2312159047fSniklas unsigned int r_type; 2322159047fSniklas unsigned int r_addend; 2332159047fSniklas asymbol *sym = *(g->sym_ptr_ptr); 2342159047fSniklas asection *output_section = sym->section->output_section; 2352159047fSniklas 2362159047fSniklas PUT_WORD (abfd, g->address, natptr->r_address); 2372159047fSniklas 2382159047fSniklas r_type = (unsigned int) g->howto->type; 2392159047fSniklas 2402159047fSniklas r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; 2412159047fSniklas 2422159047fSniklas 2432159047fSniklas /* If this relocation is relative to a symbol then set the 2442159047fSniklas r_index to the symbols index, and the r_extern bit. 2452159047fSniklas 2462159047fSniklas Absolute symbols can come in in two ways, either as an offset 2472159047fSniklas from the abs section, or as a symbol which has an abs value. 2482159047fSniklas check for that here 2492159047fSniklas */ 2502159047fSniklas 2512159047fSniklas if (bfd_is_com_section (output_section) 2522159047fSniklas || bfd_is_abs_section (output_section) 2532159047fSniklas || bfd_is_und_section (output_section)) 2542159047fSniklas { 2552159047fSniklas if (bfd_abs_section_ptr->symbol == sym) 2562159047fSniklas { 2572159047fSniklas /* Whoops, looked like an abs symbol, but is really an offset 2582159047fSniklas from the abs section */ 2592159047fSniklas r_index = 0; 2602159047fSniklas r_extern = 0; 2612159047fSniklas } 2622159047fSniklas else 2632159047fSniklas { 2642159047fSniklas r_extern = 1; 2650c6d0228Sniklas r_index = (*g->sym_ptr_ptr)->KEEPIT; 2662159047fSniklas } 2672159047fSniklas } 2682159047fSniklas else 2692159047fSniklas { 2702159047fSniklas /* Just an ordinary section */ 2712159047fSniklas r_extern = 0; 2722159047fSniklas r_index = output_section->target_index; 2732159047fSniklas } 2742159047fSniklas 2752159047fSniklas 2762159047fSniklas /* now the fun stuff */ 277c88b1d6cSniklas if (bfd_header_big_endian (abfd)) 2782159047fSniklas { 2792159047fSniklas natptr->r_index[0] = r_index >> 16; 2802159047fSniklas natptr->r_index[1] = r_index >> 8; 2812159047fSniklas natptr->r_index[2] = r_index; 2822159047fSniklas natptr->r_type[0] = 2832159047fSniklas (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) 2842159047fSniklas | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG); 2852159047fSniklas } 2862159047fSniklas else 2872159047fSniklas { 2882159047fSniklas natptr->r_index[2] = r_index >> 16; 2892159047fSniklas natptr->r_index[1] = r_index >> 8; 2902159047fSniklas natptr->r_index[0] = r_index; 2912159047fSniklas natptr->r_type[0] = 2922159047fSniklas (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) 2932159047fSniklas | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); 2942159047fSniklas } 2952159047fSniklas 2962159047fSniklas PUT_WORD (abfd, r_addend, natptr->r_addend); 2972159047fSniklas } 2982159047fSniklas 2992159047fSniklas /* BFD deals internally with all things based from the section they're 3002159047fSniklas in. so, something in 10 bytes into a text section with a base of 3012159047fSniklas 50 would have a symbol (.text+10) and know .text vma was 50. 3022159047fSniklas 3032159047fSniklas Aout keeps all it's symbols based from zero, so the symbol would 3042159047fSniklas contain 60. This macro subs the base of each section from the value 3052159047fSniklas to give the true offset from the section */ 3062159047fSniklas 3072159047fSniklas 3082159047fSniklas #define MOVE_ADDRESS(ad) \ 3092159047fSniklas if (r_extern) { \ 3102159047fSniklas /* undefined symbol */ \ 3112159047fSniklas cache_ptr->sym_ptr_ptr = symbols + r_index; \ 3122159047fSniklas cache_ptr->addend = ad; \ 3132159047fSniklas } else { \ 3142159047fSniklas /* defined, section relative. replace symbol with pointer to \ 3152159047fSniklas symbol which points to section */ \ 3162159047fSniklas switch (r_index) { \ 3172159047fSniklas case N_TEXT: \ 3182159047fSniklas case N_TEXT | N_EXT: \ 3192159047fSniklas cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ 3202159047fSniklas cache_ptr->addend = ad - su->textsec->vma; \ 3212159047fSniklas break; \ 3222159047fSniklas case N_DATA: \ 3232159047fSniklas case N_DATA | N_EXT: \ 3242159047fSniklas cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ 3252159047fSniklas cache_ptr->addend = ad - su->datasec->vma; \ 3262159047fSniklas break; \ 3272159047fSniklas case N_BSS: \ 3282159047fSniklas case N_BSS | N_EXT: \ 3292159047fSniklas cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ 3302159047fSniklas cache_ptr->addend = ad - su->bsssec->vma; \ 3312159047fSniklas break; \ 3322159047fSniklas default: \ 3332159047fSniklas case N_ABS: \ 3342159047fSniklas case N_ABS | N_EXT: \ 3352159047fSniklas cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ 3362159047fSniklas cache_ptr->addend = ad; \ 3372159047fSniklas break; \ 3382159047fSniklas } \ 3392159047fSniklas } \ 3402159047fSniklas 3412159047fSniklas void 3422159047fSniklas NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) 3432159047fSniklas bfd *abfd; 3442159047fSniklas struct reloc_ext_external *bytes; 3452159047fSniklas arelent *cache_ptr; 3462159047fSniklas asymbol **symbols; 347b305b0f1Sespie bfd_size_type symcount ATTRIBUTE_UNUSED; 3482159047fSniklas { 3492159047fSniklas int r_index; 3502159047fSniklas int r_extern; 3512159047fSniklas unsigned int r_type; 3522159047fSniklas struct aoutdata *su = &(abfd->tdata.aout_data->a); 3532159047fSniklas 3542159047fSniklas cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); 3552159047fSniklas 3562159047fSniklas r_index = bytes->r_index[1]; 3572159047fSniklas r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG)); 3582159047fSniklas r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG) 3592159047fSniklas >> RELOC_EXT_BITS_TYPE_SH_BIG; 3602159047fSniklas 3612159047fSniklas cache_ptr->howto = aout_32_ext_howto_table + r_type; 3622159047fSniklas MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend)); 3632159047fSniklas } 3642159047fSniklas 3652159047fSniklas void 3662159047fSniklas NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) 3672159047fSniklas bfd *abfd; 3682159047fSniklas struct reloc_std_external *bytes; 3692159047fSniklas arelent *cache_ptr; 3702159047fSniklas asymbol **symbols; 371b305b0f1Sespie bfd_size_type symcount ATTRIBUTE_UNUSED; 3722159047fSniklas { 3732159047fSniklas int r_index; 3742159047fSniklas int r_extern; 3752159047fSniklas unsigned int r_length; 3762159047fSniklas int r_pcrel; 3772159047fSniklas int r_baserel, r_jmptable, r_relative; 3782159047fSniklas struct aoutdata *su = &(abfd->tdata.aout_data->a); 3792159047fSniklas 380*c074d1c9Sdrahn cache_ptr->address = H_GET_32 (abfd, bytes->r_address); 3812159047fSniklas 3822159047fSniklas r_index = bytes->r_index[1]; 3832159047fSniklas r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG)); 3842159047fSniklas r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG)); 3852159047fSniklas r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG)); 3862159047fSniklas r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG)); 3872159047fSniklas r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG)); 3882159047fSniklas r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) 3892159047fSniklas >> RELOC_STD_BITS_LENGTH_SH_BIG; 3902159047fSniklas 3912159047fSniklas cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel; 3922159047fSniklas /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ 3932159047fSniklas 3942159047fSniklas MOVE_ADDRESS (0); 3952159047fSniklas } 3962159047fSniklas 3972159047fSniklas /* Reloc hackery */ 3982159047fSniklas 399*c074d1c9Sdrahn bfd_boolean 4002159047fSniklas NAME(lynx,slurp_reloc_table) (abfd, asect, symbols) 4012159047fSniklas bfd *abfd; 4022159047fSniklas sec_ptr asect; 4032159047fSniklas asymbol **symbols; 4042159047fSniklas { 405*c074d1c9Sdrahn bfd_size_type count; 4062159047fSniklas bfd_size_type reloc_size; 4072159047fSniklas PTR relocs; 4082159047fSniklas arelent *reloc_cache; 4092159047fSniklas size_t each_size; 4102159047fSniklas 4112159047fSniklas if (asect->relocation) 412*c074d1c9Sdrahn return TRUE; 4132159047fSniklas 4142159047fSniklas if (asect->flags & SEC_CONSTRUCTOR) 415*c074d1c9Sdrahn return TRUE; 4162159047fSniklas 4172159047fSniklas if (asect == obj_datasec (abfd)) 4182159047fSniklas { 4192159047fSniklas reloc_size = exec_hdr (abfd)->a_drsize; 4202159047fSniklas goto doit; 4212159047fSniklas } 4222159047fSniklas 4232159047fSniklas if (asect == obj_textsec (abfd)) 4242159047fSniklas { 4252159047fSniklas reloc_size = exec_hdr (abfd)->a_trsize; 4262159047fSniklas goto doit; 4272159047fSniklas } 4282159047fSniklas 4292159047fSniklas bfd_set_error (bfd_error_invalid_operation); 430*c074d1c9Sdrahn return FALSE; 4312159047fSniklas 4322159047fSniklas doit: 4332159047fSniklas if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) 434*c074d1c9Sdrahn return FALSE; 4352159047fSniklas each_size = obj_reloc_entry_size (abfd); 4362159047fSniklas 4372159047fSniklas count = reloc_size / each_size; 4382159047fSniklas 4392159047fSniklas 440*c074d1c9Sdrahn reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent)); 4412159047fSniklas if (!reloc_cache && count != 0) 442*c074d1c9Sdrahn return FALSE; 4432159047fSniklas 4442159047fSniklas relocs = (PTR) bfd_alloc (abfd, reloc_size); 4452159047fSniklas if (!relocs && reloc_size != 0) 4462159047fSniklas { 4472159047fSniklas free (reloc_cache); 448*c074d1c9Sdrahn return FALSE; 4492159047fSniklas } 4502159047fSniklas 451*c074d1c9Sdrahn if (bfd_bread (relocs, reloc_size, abfd) != reloc_size) 4522159047fSniklas { 4532159047fSniklas bfd_release (abfd, relocs); 4542159047fSniklas free (reloc_cache); 455*c074d1c9Sdrahn return FALSE; 4562159047fSniklas } 4572159047fSniklas 4582159047fSniklas if (each_size == RELOC_EXT_SIZE) 4592159047fSniklas { 4602159047fSniklas register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; 4612159047fSniklas unsigned int counter = 0; 4622159047fSniklas arelent *cache_ptr = reloc_cache; 4632159047fSniklas 4642159047fSniklas for (; counter < count; counter++, rptr++, cache_ptr++) 4652159047fSniklas { 4662159047fSniklas NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, 467*c074d1c9Sdrahn (bfd_size_type) bfd_get_symcount (abfd)); 4682159047fSniklas } 4692159047fSniklas } 4702159047fSniklas else 4712159047fSniklas { 4722159047fSniklas register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; 4732159047fSniklas unsigned int counter = 0; 4742159047fSniklas arelent *cache_ptr = reloc_cache; 4752159047fSniklas 4762159047fSniklas for (; counter < count; counter++, rptr++, cache_ptr++) 4772159047fSniklas { 4782159047fSniklas NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, 479*c074d1c9Sdrahn (bfd_size_type) bfd_get_symcount (abfd)); 4802159047fSniklas } 4812159047fSniklas 4822159047fSniklas } 4832159047fSniklas 4842159047fSniklas bfd_release (abfd, relocs); 4852159047fSniklas asect->relocation = reloc_cache; 4862159047fSniklas asect->reloc_count = count; 487*c074d1c9Sdrahn return TRUE; 4882159047fSniklas } 4892159047fSniklas 4902159047fSniklas 4912159047fSniklas 4922159047fSniklas /* Write out a relocation section into an object file. */ 4932159047fSniklas 494*c074d1c9Sdrahn bfd_boolean 4952159047fSniklas NAME(lynx,squirt_out_relocs) (abfd, section) 4962159047fSniklas bfd *abfd; 4972159047fSniklas asection *section; 4982159047fSniklas { 4992159047fSniklas arelent **generic; 5002159047fSniklas unsigned char *native, *natptr; 5012159047fSniklas size_t each_size; 5022159047fSniklas 5032159047fSniklas unsigned int count = section->reloc_count; 504*c074d1c9Sdrahn bfd_size_type natsize; 5052159047fSniklas 5062159047fSniklas if (count == 0) 507*c074d1c9Sdrahn return TRUE; 5082159047fSniklas 5092159047fSniklas each_size = obj_reloc_entry_size (abfd); 510*c074d1c9Sdrahn natsize = count; 511*c074d1c9Sdrahn natsize *= each_size; 5122159047fSniklas native = (unsigned char *) bfd_zalloc (abfd, natsize); 5132159047fSniklas if (!native) 514*c074d1c9Sdrahn return FALSE; 5152159047fSniklas 5162159047fSniklas generic = section->orelocation; 5172159047fSniklas 5182159047fSniklas if (each_size == RELOC_EXT_SIZE) 5192159047fSniklas { 5202159047fSniklas for (natptr = native; 5212159047fSniklas count != 0; 5222159047fSniklas --count, natptr += each_size, ++generic) 5232159047fSniklas NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr); 5242159047fSniklas } 5252159047fSniklas else 5262159047fSniklas { 5272159047fSniklas for (natptr = native; 5282159047fSniklas count != 0; 5292159047fSniklas --count, natptr += each_size, ++generic) 5302159047fSniklas NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr); 5312159047fSniklas } 5322159047fSniklas 533*c074d1c9Sdrahn if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize) 5342159047fSniklas { 5352159047fSniklas bfd_release (abfd, native); 536*c074d1c9Sdrahn return FALSE; 5372159047fSniklas } 5382159047fSniklas bfd_release (abfd, native); 5392159047fSniklas 540*c074d1c9Sdrahn return TRUE; 5412159047fSniklas } 5422159047fSniklas 5432159047fSniklas /* This is stupid. This function should be a boolean predicate */ 5442159047fSniklas long 5452159047fSniklas NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols) 5462159047fSniklas bfd *abfd; 5472159047fSniklas sec_ptr section; 5482159047fSniklas arelent **relptr; 5492159047fSniklas asymbol **symbols; 5502159047fSniklas { 5512159047fSniklas arelent *tblptr = section->relocation; 5522159047fSniklas unsigned int count; 5532159047fSniklas 5542159047fSniklas if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols))) 5552159047fSniklas return -1; 5562159047fSniklas 5572159047fSniklas if (section->flags & SEC_CONSTRUCTOR) 5582159047fSniklas { 5592159047fSniklas arelent_chain *chain = section->constructor_chain; 5602159047fSniklas for (count = 0; count < section->reloc_count; count++) 5612159047fSniklas { 5622159047fSniklas *relptr++ = &chain->relent; 5632159047fSniklas chain = chain->next; 5642159047fSniklas } 5652159047fSniklas } 5662159047fSniklas else 5672159047fSniklas { 5682159047fSniklas tblptr = section->relocation; 5692159047fSniklas 5702159047fSniklas for (count = 0; count++ < section->reloc_count;) 5712159047fSniklas { 5722159047fSniklas *relptr++ = tblptr++; 5732159047fSniklas } 5742159047fSniklas } 5752159047fSniklas *relptr = 0; 5762159047fSniklas 5772159047fSniklas return section->reloc_count; 5782159047fSniklas } 5792159047fSniklas 5802159047fSniklas #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc) 5812159047fSniklas 5822159047fSniklas #include "aout-target.h" 583