1 1.1 christos /* BFD semi-generic back-end for a.out binaries. 2 1.1.1.10 christos Copyright (C) 1990-2024 Free Software Foundation, Inc. 3 1.1 christos Written by Cygnus Support. 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos /* 23 1.1 christos SECTION 24 1.1 christos a.out backends 25 1.1 christos 26 1.1 christos DESCRIPTION 27 1.1 christos 28 1.1 christos BFD supports a number of different flavours of a.out format, 29 1.1 christos though the major differences are only the sizes of the 30 1.1 christos structures on disk, and the shape of the relocation 31 1.1 christos information. 32 1.1 christos 33 1.1 christos The support is split into a basic support file @file{aoutx.h} 34 1.1 christos and other files which derive functions from the base. One 35 1.1 christos derivation file is @file{aoutf1.h} (for a.out flavour 1), and 36 1.1.1.7 christos adds to the basic a.out functions support for sun3, sun4, and 37 1.1.1.7 christos 386 a.out files, to create a target jump vector for a specific 38 1.1.1.7 christos target. 39 1.1 christos 40 1.1 christos This information is further split out into more specific files 41 1.1 christos for each machine, including @file{sunos.c} for sun3 and sun4, 42 1.1.1.7 christos and @file{demo64.c} for a demonstration of a 64 bit a.out format. 43 1.1 christos 44 1.1 christos The base file @file{aoutx.h} defines general mechanisms for 45 1.1 christos reading and writing records to and from disk and various 46 1.1 christos other methods which BFD requires. It is included by 47 1.1 christos @file{aout32.c} and @file{aout64.c} to form the names 48 1.1 christos <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc. 49 1.1 christos 50 1.1 christos As an example, this is what goes on to make the back end for a 51 1.1 christos sun4, from @file{aout32.c}: 52 1.1 christos 53 1.1 christos | #define ARCH_SIZE 32 54 1.1 christos | #include "aoutx.h" 55 1.1 christos 56 1.1 christos Which exports names: 57 1.1 christos 58 1.1 christos | ... 59 1.1 christos | aout_32_canonicalize_reloc 60 1.1 christos | aout_32_find_nearest_line 61 1.1 christos | aout_32_get_lineno 62 1.1 christos | aout_32_get_reloc_upper_bound 63 1.1 christos | ... 64 1.1 christos 65 1.1 christos from @file{sunos.c}: 66 1.1 christos 67 1.1 christos | #define TARGET_NAME "a.out-sunos-big" 68 1.1.1.3 christos | #define VECNAME sparc_aout_sunos_be_vec 69 1.1 christos | #include "aoutf1.h" 70 1.1 christos 71 1.1 christos requires all the names from @file{aout32.c}, and produces the jump vector 72 1.1 christos 73 1.1.1.3 christos | sparc_aout_sunos_be_vec 74 1.1 christos 75 1.1 christos The file @file{host-aout.c} is a special case. It is for a large set 76 1.1 christos of hosts that use ``more or less standard'' a.out files, and 77 1.1 christos for which cross-debugging is not interesting. It uses the 78 1.1 christos standard 32-bit a.out support routines, but determines the 79 1.1 christos file offsets and addresses of the text, data, and BSS 80 1.1 christos sections, the machine architecture and machine type, and the 81 1.1 christos entry point address, in a host-dependent manner. Once these 82 1.1 christos values have been determined, generic code is used to handle 83 1.1 christos the object file. 84 1.1 christos 85 1.1 christos When porting it to run on a new system, you must supply: 86 1.1 christos 87 1.1 christos | HOST_PAGE_SIZE 88 1.1 christos | HOST_SEGMENT_SIZE 89 1.1 christos | HOST_MACHINE_ARCH (optional) 90 1.1 christos | HOST_MACHINE_MACHINE (optional) 91 1.1 christos | HOST_TEXT_START_ADDR 92 1.1 christos | HOST_STACK_END_ADDR 93 1.1 christos 94 1.1 christos in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These 95 1.1 christos values, plus the structures and macros defined in @file{a.out.h} on 96 1.1 christos your host system, will produce a BFD target that will access 97 1.1 christos ordinary a.out files on your host. To configure a new machine 98 1.1 christos to use @file{host-aout.c}, specify: 99 1.1 christos 100 1.1 christos | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec 101 1.1 christos | TDEPFILES= host-aout.o trad-core.o 102 1.1 christos 103 1.1.1.3 christos in the @file{config/@var{XXX}.mt} file, and modify @file{configure.ac} 104 1.1 christos to use the 105 1.1 christos @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your 106 1.1 christos configuration is selected. */ 107 1.1 christos 108 1.1 christos /* Some assumptions: 109 1.1 christos * Any BFD with D_PAGED set is ZMAGIC, and vice versa. 110 1.1 christos Doesn't matter what the setting of WP_TEXT is on output, but it'll 111 1.1 christos get set on input. 112 1.1 christos * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC. 113 1.1 christos * Any BFD with both flags clear is OMAGIC. 114 1.1 christos (Just want to make these explicit, so the conditions tested in this 115 1.1 christos file make sense if you're more familiar with a.out than with BFD.) */ 116 1.1 christos 117 1.1 christos #define KEEPIT udata.i 118 1.1 christos 119 1.1 christos #include "sysdep.h" 120 1.1.1.7 christos #include <limits.h> 121 1.1 christos #include "bfd.h" 122 1.1 christos #include "safe-ctype.h" 123 1.1 christos #include "bfdlink.h" 124 1.1 christos 125 1.1 christos #include "libaout.h" 126 1.1 christos #include "libbfd.h" 127 1.1 christos #include "aout/aout64.h" 128 1.1 christos #include "aout/stab_gnu.h" 129 1.1 christos #include "aout/ar.h" 130 1.1 christos 131 1.1.1.8 christos #ifdef BMAGIC 132 1.1.1.8 christos #define N_IS_BMAGIC(x) (N_MAGIC (x) == BMAGIC) 133 1.1.1.8 christos #else 134 1.1.1.8 christos #define N_IS_BMAGIC(x) (0) 135 1.1.1.8 christos #endif 136 1.1.1.8 christos 137 1.1.1.8 christos #ifdef QMAGIC 138 1.1.1.8 christos #define N_SET_QMAGIC(x) N_SET_MAGIC (x, QMAGIC) 139 1.1.1.8 christos #else 140 1.1.1.8 christos #define N_SET_QMAGIC(x) do { /**/ } while (0) 141 1.1.1.8 christos #endif 142 1.1.1.8 christos 143 1.1 christos /* 144 1.1 christos SUBSECTION 145 1.1 christos Relocations 146 1.1 christos 147 1.1 christos DESCRIPTION 148 1.1 christos The file @file{aoutx.h} provides for both the @emph{standard} 149 1.1 christos and @emph{extended} forms of a.out relocation records. 150 1.1 christos 151 1.1.1.7 christos The standard records contain only an address, a symbol index, 152 1.1.1.7 christos and a type field. The extended records also have a full 153 1.1.1.7 christos integer for an addend. */ 154 1.1 christos 155 1.1 christos #ifndef CTOR_TABLE_RELOC_HOWTO 156 1.1 christos #define CTOR_TABLE_RELOC_IDX 2 157 1.1 christos #define CTOR_TABLE_RELOC_HOWTO(BFD) \ 158 1.1 christos ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE \ 159 1.1 christos ? howto_table_ext : howto_table_std) \ 160 1.1 christos + CTOR_TABLE_RELOC_IDX) 161 1.1 christos #endif 162 1.1 christos 163 1.1 christos #ifndef MY_swap_std_reloc_in 164 1.1 christos #define MY_swap_std_reloc_in NAME (aout, swap_std_reloc_in) 165 1.1 christos #endif 166 1.1 christos 167 1.1 christos #ifndef MY_swap_ext_reloc_in 168 1.1 christos #define MY_swap_ext_reloc_in NAME (aout, swap_ext_reloc_in) 169 1.1 christos #endif 170 1.1 christos 171 1.1 christos #ifndef MY_swap_std_reloc_out 172 1.1 christos #define MY_swap_std_reloc_out NAME (aout, swap_std_reloc_out) 173 1.1 christos #endif 174 1.1 christos 175 1.1 christos #ifndef MY_swap_ext_reloc_out 176 1.1 christos #define MY_swap_ext_reloc_out NAME (aout, swap_ext_reloc_out) 177 1.1 christos #endif 178 1.1 christos 179 1.1 christos #ifndef MY_final_link_relocate 180 1.1 christos #define MY_final_link_relocate _bfd_final_link_relocate 181 1.1 christos #endif 182 1.1 christos 183 1.1 christos #ifndef MY_relocate_contents 184 1.1 christos #define MY_relocate_contents _bfd_relocate_contents 185 1.1 christos #endif 186 1.1 christos 187 1.1 christos #define howto_table_ext NAME (aout, ext_howto_table) 188 1.1 christos #define howto_table_std NAME (aout, std_howto_table) 189 1.1 christos 190 1.1 christos reloc_howto_type howto_table_ext[] = 191 1.1 christos { 192 1.1.1.7 christos /* Type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */ 193 1.1.1.9 christos HOWTO (RELOC_8, 0, 1, 8, false, 0, complain_overflow_bitfield, 0, "8", false, 0, 0x000000ff, false), 194 1.1.1.9 christos HOWTO (RELOC_16, 0, 2, 16, false, 0, complain_overflow_bitfield, 0, "16", false, 0, 0x0000ffff, false), 195 1.1.1.9 christos HOWTO (RELOC_32, 0, 4, 32, false, 0, complain_overflow_bitfield, 0, "32", false, 0, 0xffffffff, false), 196 1.1.1.9 christos HOWTO (RELOC_DISP8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "DISP8", false, 0, 0x000000ff, false), 197 1.1.1.9 christos HOWTO (RELOC_DISP16, 0, 2, 16, true, 0, complain_overflow_signed, 0, "DISP16", false, 0, 0x0000ffff, false), 198 1.1.1.9 christos HOWTO (RELOC_DISP32, 0, 4, 32, true, 0, complain_overflow_signed, 0, "DISP32", false, 0, 0xffffffff, false), 199 1.1.1.9 christos HOWTO (RELOC_WDISP30, 2, 4, 30, true, 0, complain_overflow_signed, 0, "WDISP30", false, 0, 0x3fffffff, false), 200 1.1.1.9 christos HOWTO (RELOC_WDISP22, 2, 4, 22, true, 0, complain_overflow_signed, 0, "WDISP22", false, 0, 0x003fffff, false), 201 1.1.1.9 christos HOWTO (RELOC_HI22, 10, 4, 22, false, 0, complain_overflow_bitfield, 0, "HI22", false, 0, 0x003fffff, false), 202 1.1.1.9 christos HOWTO (RELOC_22, 0, 4, 22, false, 0, complain_overflow_bitfield, 0, "22", false, 0, 0x003fffff, false), 203 1.1.1.9 christos HOWTO (RELOC_13, 0, 4, 13, false, 0, complain_overflow_bitfield, 0, "13", false, 0, 0x00001fff, false), 204 1.1.1.9 christos HOWTO (RELOC_LO10, 0, 4, 10, false, 0, complain_overflow_dont, 0, "LO10", false, 0, 0x000003ff, false), 205 1.1.1.9 christos HOWTO (RELOC_SFA_BASE,0, 4, 32, false, 0, complain_overflow_bitfield, 0, "SFA_BASE", false, 0, 0xffffffff, false), 206 1.1.1.9 christos HOWTO (RELOC_SFA_OFF13,0, 4, 32, false, 0, complain_overflow_bitfield, 0, "SFA_OFF13", false, 0, 0xffffffff, false), 207 1.1.1.9 christos HOWTO (RELOC_BASE10, 0, 4, 10, false, 0, complain_overflow_dont, 0, "BASE10", false, 0, 0x000003ff, false), 208 1.1.1.9 christos HOWTO (RELOC_BASE13, 0, 4, 13, false, 0, complain_overflow_signed, 0, "BASE13", false, 0, 0x00001fff, false), 209 1.1.1.9 christos HOWTO (RELOC_BASE22, 10, 4, 22, false, 0, complain_overflow_bitfield, 0, "BASE22", false, 0, 0x003fffff, false), 210 1.1.1.9 christos HOWTO (RELOC_PC10, 0, 4, 10, true, 0, complain_overflow_dont, 0, "PC10", false, 0, 0x000003ff, true), 211 1.1.1.9 christos HOWTO (RELOC_PC22, 10, 4, 22, true, 0, complain_overflow_signed, 0, "PC22", false, 0, 0x003fffff, true), 212 1.1.1.9 christos HOWTO (RELOC_JMP_TBL, 2, 4, 30, true, 0, complain_overflow_signed, 0, "JMP_TBL", false, 0, 0x3fffffff, false), 213 1.1.1.9 christos HOWTO (RELOC_SEGOFF16,0, 4, 0, false, 0, complain_overflow_bitfield, 0, "SEGOFF16", false, 0, 0x00000000, false), 214 1.1.1.9 christos HOWTO (RELOC_GLOB_DAT,0, 4, 0, false, 0, complain_overflow_bitfield, 0, "GLOB_DAT", false, 0, 0x00000000, false), 215 1.1.1.9 christos HOWTO (RELOC_JMP_SLOT,0, 4, 0, false, 0, complain_overflow_bitfield, 0, "JMP_SLOT", false, 0, 0x00000000, false), 216 1.1.1.9 christos HOWTO (RELOC_RELATIVE,0, 4, 0, false, 0, complain_overflow_bitfield, 0, "RELATIVE", false, 0, 0x00000000, false), 217 1.1.1.9 christos HOWTO (0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE",false, 0, 0x00000000, true), 218 1.1.1.9 christos HOWTO (0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE",false, 0, 0x00000000, true), 219 1.1 christos #define RELOC_SPARC_REV32 RELOC_WDISP19 220 1.1.1.9 christos HOWTO (RELOC_SPARC_REV32, 0, 4, 32, false, 0, complain_overflow_dont, 0,"R_SPARC_REV32",false, 0, 0xffffffff, false), 221 1.1 christos }; 222 1.1 christos 223 1.1 christos /* Convert standard reloc records to "arelent" format (incl byte swap). */ 224 1.1 christos 225 1.1 christos reloc_howto_type howto_table_std[] = 226 1.1 christos { 227 1.1.1.7 christos /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */ 228 1.1.1.9 christos HOWTO ( 0, 0, 1, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false), 229 1.1.1.9 christos HOWTO ( 1, 0, 2, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false), 230 1.1.1.9 christos HOWTO ( 2, 0, 4, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false), 231 1.1.1.9 christos HOWTO ( 3, 0, 8, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false), 232 1.1.1.9 christos HOWTO ( 4, 0, 1, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false), 233 1.1.1.9 christos HOWTO ( 5, 0, 2, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false), 234 1.1.1.9 christos HOWTO ( 6, 0, 4, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false), 235 1.1.1.9 christos HOWTO ( 7, 0, 8, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false), 236 1.1.1.9 christos HOWTO ( 8, 0, 4, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false), 237 1.1.1.9 christos HOWTO ( 9, 0, 2, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false), 238 1.1.1.9 christos HOWTO (10, 0, 4, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false), 239 1.1 christos EMPTY_HOWTO (-1), 240 1.1 christos EMPTY_HOWTO (-1), 241 1.1 christos EMPTY_HOWTO (-1), 242 1.1 christos EMPTY_HOWTO (-1), 243 1.1 christos EMPTY_HOWTO (-1), 244 1.1.1.9 christos HOWTO (16, 0, 4, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false), 245 1.1 christos EMPTY_HOWTO (-1), 246 1.1 christos EMPTY_HOWTO (-1), 247 1.1 christos EMPTY_HOWTO (-1), 248 1.1 christos EMPTY_HOWTO (-1), 249 1.1 christos EMPTY_HOWTO (-1), 250 1.1 christos EMPTY_HOWTO (-1), 251 1.1 christos EMPTY_HOWTO (-1), 252 1.1 christos EMPTY_HOWTO (-1), 253 1.1 christos EMPTY_HOWTO (-1), 254 1.1 christos EMPTY_HOWTO (-1), 255 1.1 christos EMPTY_HOWTO (-1), 256 1.1 christos EMPTY_HOWTO (-1), 257 1.1 christos EMPTY_HOWTO (-1), 258 1.1 christos EMPTY_HOWTO (-1), 259 1.1 christos EMPTY_HOWTO (-1), 260 1.1.1.9 christos HOWTO (32, 0, 4, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false), 261 1.1 christos EMPTY_HOWTO (-1), 262 1.1 christos EMPTY_HOWTO (-1), 263 1.1 christos EMPTY_HOWTO (-1), 264 1.1 christos EMPTY_HOWTO (-1), 265 1.1 christos EMPTY_HOWTO (-1), 266 1.1 christos EMPTY_HOWTO (-1), 267 1.1 christos EMPTY_HOWTO (-1), 268 1.1.1.9 christos HOWTO (40, 0, 4, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false), 269 1.1 christos }; 270 1.1 christos 271 1.1 christos #define TABLE_SIZE(TABLE) (sizeof (TABLE) / sizeof (TABLE[0])) 272 1.1 christos 273 1.1 christos reloc_howto_type * 274 1.1 christos NAME (aout, reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code) 275 1.1 christos { 276 1.1 christos #define EXT(i, j) case i: return & howto_table_ext [j] 277 1.1 christos #define STD(i, j) case i: return & howto_table_std [j] 278 1.1 christos int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE; 279 1.1 christos 280 1.1 christos if (code == BFD_RELOC_CTOR) 281 1.1 christos switch (bfd_arch_bits_per_address (abfd)) 282 1.1 christos { 283 1.1 christos case 32: 284 1.1 christos code = BFD_RELOC_32; 285 1.1 christos break; 286 1.1 christos case 64: 287 1.1 christos code = BFD_RELOC_64; 288 1.1 christos break; 289 1.1 christos } 290 1.1 christos 291 1.1 christos if (ext) 292 1.1 christos switch (code) 293 1.1 christos { 294 1.1 christos EXT (BFD_RELOC_8, 0); 295 1.1 christos EXT (BFD_RELOC_16, 1); 296 1.1 christos EXT (BFD_RELOC_32, 2); 297 1.1 christos EXT (BFD_RELOC_HI22, 8); 298 1.1 christos EXT (BFD_RELOC_LO10, 11); 299 1.1 christos EXT (BFD_RELOC_32_PCREL_S2, 6); 300 1.1 christos EXT (BFD_RELOC_SPARC_WDISP22, 7); 301 1.1 christos EXT (BFD_RELOC_SPARC13, 10); 302 1.1 christos EXT (BFD_RELOC_SPARC_GOT10, 14); 303 1.1 christos EXT (BFD_RELOC_SPARC_BASE13, 15); 304 1.1 christos EXT (BFD_RELOC_SPARC_GOT13, 15); 305 1.1 christos EXT (BFD_RELOC_SPARC_GOT22, 16); 306 1.1 christos EXT (BFD_RELOC_SPARC_PC10, 17); 307 1.1 christos EXT (BFD_RELOC_SPARC_PC22, 18); 308 1.1 christos EXT (BFD_RELOC_SPARC_WPLT30, 19); 309 1.1 christos EXT (BFD_RELOC_SPARC_REV32, 26); 310 1.1 christos default: 311 1.1 christos return NULL; 312 1.1 christos } 313 1.1 christos else 314 1.1 christos /* std relocs. */ 315 1.1 christos switch (code) 316 1.1 christos { 317 1.1 christos STD (BFD_RELOC_8, 0); 318 1.1 christos STD (BFD_RELOC_16, 1); 319 1.1 christos STD (BFD_RELOC_32, 2); 320 1.1 christos STD (BFD_RELOC_8_PCREL, 4); 321 1.1 christos STD (BFD_RELOC_16_PCREL, 5); 322 1.1 christos STD (BFD_RELOC_32_PCREL, 6); 323 1.1 christos STD (BFD_RELOC_16_BASEREL, 9); 324 1.1 christos STD (BFD_RELOC_32_BASEREL, 10); 325 1.1 christos default: 326 1.1 christos return NULL; 327 1.1 christos } 328 1.1 christos } 329 1.1 christos 330 1.1 christos reloc_howto_type * 331 1.1 christos NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name) 332 1.1 christos { 333 1.1 christos unsigned int i, size; 334 1.1 christos reloc_howto_type *howto_table; 335 1.1 christos 336 1.1 christos if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE) 337 1.1 christos { 338 1.1 christos howto_table = howto_table_ext; 339 1.1 christos size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]); 340 1.1 christos } 341 1.1 christos else 342 1.1 christos { 343 1.1 christos howto_table = howto_table_std; 344 1.1 christos size = sizeof (howto_table_std) / sizeof (howto_table_std[0]); 345 1.1 christos } 346 1.1 christos 347 1.1 christos for (i = 0; i < size; i++) 348 1.1 christos if (howto_table[i].name != NULL 349 1.1 christos && strcasecmp (howto_table[i].name, r_name) == 0) 350 1.1 christos return &howto_table[i]; 351 1.1 christos 352 1.1 christos return NULL; 353 1.1 christos } 354 1.1 christos 355 1.1 christos /* 356 1.1 christos SUBSECTION 357 1.1 christos Internal entry points 358 1.1 christos 359 1.1 christos DESCRIPTION 360 1.1 christos @file{aoutx.h} exports several routines for accessing the 361 1.1 christos contents of an a.out file, which are gathered and exported in 362 1.1 christos turn by various format specific files (eg sunos.c). 363 1.1 christos */ 364 1.1 christos 365 1.1 christos /* 366 1.1 christos FUNCTION 367 1.1 christos aout_@var{size}_swap_exec_header_in 368 1.1 christos 369 1.1 christos SYNOPSIS 370 1.1 christos void aout_@var{size}_swap_exec_header_in, 371 1.1.1.7 christos (bfd *abfd, 372 1.1.1.7 christos struct external_exec *bytes, 373 1.1.1.7 christos struct internal_exec *execp); 374 1.1 christos 375 1.1 christos DESCRIPTION 376 1.1 christos Swap the information in an executable header @var{raw_bytes} taken 377 1.1 christos from a raw byte stream memory image into the internal exec header 378 1.1 christos structure @var{execp}. 379 1.1 christos */ 380 1.1 christos 381 1.1 christos #ifndef NAME_swap_exec_header_in 382 1.1 christos void 383 1.1 christos NAME (aout, swap_exec_header_in) (bfd *abfd, 384 1.1 christos struct external_exec *bytes, 385 1.1 christos struct internal_exec *execp) 386 1.1 christos { 387 1.1 christos /* The internal_exec structure has some fields that are unused in this 388 1.1 christos configuration (IE for i960), so ensure that all such uninitialized 389 1.1 christos fields are zero'd out. There are places where two of these structs 390 1.1 christos are memcmp'd, and thus the contents do matter. */ 391 1.1 christos memset ((void *) execp, 0, sizeof (struct internal_exec)); 392 1.1 christos /* Now fill in fields in the execp, from the bytes in the raw data. */ 393 1.1 christos execp->a_info = H_GET_32 (abfd, bytes->e_info); 394 1.1 christos execp->a_text = GET_WORD (abfd, bytes->e_text); 395 1.1 christos execp->a_data = GET_WORD (abfd, bytes->e_data); 396 1.1 christos execp->a_bss = GET_WORD (abfd, bytes->e_bss); 397 1.1 christos execp->a_syms = GET_WORD (abfd, bytes->e_syms); 398 1.1 christos execp->a_entry = GET_WORD (abfd, bytes->e_entry); 399 1.1 christos execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); 400 1.1 christos execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); 401 1.1 christos } 402 1.1 christos #define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in) 403 1.1 christos #endif 404 1.1 christos 405 1.1 christos /* 406 1.1 christos FUNCTION 407 1.1 christos aout_@var{size}_swap_exec_header_out 408 1.1 christos 409 1.1 christos SYNOPSIS 410 1.1.1.10 christos bool aout_@var{size}_swap_exec_header_out 411 1.1 christos (bfd *abfd, 412 1.1 christos struct internal_exec *execp, 413 1.1 christos struct external_exec *raw_bytes); 414 1.1 christos 415 1.1 christos DESCRIPTION 416 1.1 christos Swap the information in an internal exec header structure 417 1.1 christos @var{execp} into the buffer @var{raw_bytes} ready for writing to disk. 418 1.1 christos */ 419 1.1.1.10 christos bool 420 1.1 christos NAME (aout, swap_exec_header_out) (bfd *abfd, 421 1.1 christos struct internal_exec *execp, 422 1.1 christos struct external_exec *bytes) 423 1.1 christos { 424 1.1.1.10 christos const char *err = NULL; 425 1.1.1.10 christos uint64_t val; 426 1.1.1.10 christos #define MAXVAL(x) ((UINT64_C (1) << (8 * sizeof (x) - 1) << 1) - 1) 427 1.1.1.10 christos if ((val = execp->a_text) > MAXVAL (bytes->e_text)) 428 1.1.1.10 christos err = "e_text"; 429 1.1.1.10 christos else if ((val = execp->a_data) > MAXVAL (bytes->e_data)) 430 1.1.1.10 christos err = "e_data"; 431 1.1.1.10 christos else if ((val = execp->a_bss) > MAXVAL (bytes->e_bss)) 432 1.1.1.10 christos err = "e_bss"; 433 1.1.1.10 christos else if ((val = execp->a_syms) > MAXVAL (bytes->e_syms)) 434 1.1.1.10 christos err = "e_syms"; 435 1.1.1.10 christos else if ((val = execp->a_entry) > MAXVAL (bytes->e_entry)) 436 1.1.1.10 christos err = "e_entry"; 437 1.1.1.10 christos else if ((val = execp->a_trsize) > MAXVAL (bytes->e_trsize)) 438 1.1.1.10 christos err = "e_trsize"; 439 1.1.1.10 christos else if ((val = execp->a_drsize) > MAXVAL (bytes->e_drsize)) 440 1.1.1.10 christos err = "e_drsize"; 441 1.1.1.10 christos #undef MAXVAL 442 1.1.1.10 christos if (err) 443 1.1.1.10 christos { 444 1.1.1.10 christos _bfd_error_handler (_("%pB: %#" PRIx64 " overflows header %s field"), 445 1.1.1.10 christos abfd, val, err); 446 1.1.1.10 christos bfd_set_error (bfd_error_file_too_big); 447 1.1.1.10 christos return false; 448 1.1.1.10 christos } 449 1.1.1.10 christos 450 1.1 christos /* Now fill in fields in the raw data, from the fields in the exec struct. */ 451 1.1 christos H_PUT_32 (abfd, execp->a_info , bytes->e_info); 452 1.1 christos PUT_WORD (abfd, execp->a_text , bytes->e_text); 453 1.1 christos PUT_WORD (abfd, execp->a_data , bytes->e_data); 454 1.1 christos PUT_WORD (abfd, execp->a_bss , bytes->e_bss); 455 1.1 christos PUT_WORD (abfd, execp->a_syms , bytes->e_syms); 456 1.1 christos PUT_WORD (abfd, execp->a_entry , bytes->e_entry); 457 1.1 christos PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); 458 1.1 christos PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); 459 1.1.1.10 christos return true; 460 1.1 christos } 461 1.1 christos 462 1.1 christos /* Make all the section for an a.out file. */ 463 1.1 christos 464 1.1.1.9 christos bool 465 1.1 christos NAME (aout, make_sections) (bfd *abfd) 466 1.1 christos { 467 1.1 christos if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL) 468 1.1.1.9 christos return false; 469 1.1 christos if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL) 470 1.1.1.9 christos return false; 471 1.1 christos if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == NULL) 472 1.1.1.9 christos return false; 473 1.1.1.9 christos return true; 474 1.1 christos } 475 1.1 christos 476 1.1 christos /* 477 1.1 christos FUNCTION 478 1.1 christos aout_@var{size}_some_aout_object_p 479 1.1 christos 480 1.1 christos SYNOPSIS 481 1.1.1.9 christos bfd_cleanup aout_@var{size}_some_aout_object_p 482 1.1 christos (bfd *abfd, 483 1.1.1.7 christos struct internal_exec *execp, 484 1.1.1.9 christos bfd_cleanup (*callback_to_real_object_p) (bfd *)); 485 1.1 christos 486 1.1 christos DESCRIPTION 487 1.1 christos Some a.out variant thinks that the file open in @var{abfd} 488 1.1 christos checking is an a.out file. Do some more checking, and set up 489 1.1 christos for access if it really is. Call back to the calling 490 1.1 christos environment's "finish up" function just before returning, to 491 1.1 christos handle any last-minute setup. 492 1.1 christos */ 493 1.1 christos 494 1.1.1.8 christos bfd_cleanup 495 1.1 christos NAME (aout, some_aout_object_p) (bfd *abfd, 496 1.1 christos struct internal_exec *execp, 497 1.1.1.8 christos bfd_cleanup (*callback_to_real_object_p) (bfd *)) 498 1.1 christos { 499 1.1.1.11 christos struct aout_data_struct *rawptr; 500 1.1.1.8 christos bfd_cleanup result; 501 1.1 christos 502 1.1.1.11 christos rawptr = bfd_zalloc (abfd, sizeof (*rawptr)); 503 1.1 christos if (rawptr == NULL) 504 1.1 christos return NULL; 505 1.1 christos abfd->tdata.aout_data = rawptr; 506 1.1 christos 507 1.1 christos abfd->tdata.aout_data->a.hdr = &rawptr->e; 508 1.1 christos /* Copy in the internal_exec struct. */ 509 1.1 christos *(abfd->tdata.aout_data->a.hdr) = *execp; 510 1.1 christos execp = abfd->tdata.aout_data->a.hdr; 511 1.1 christos 512 1.1 christos /* Set the file flags. */ 513 1.1 christos abfd->flags = BFD_NO_FLAGS; 514 1.1 christos if (execp->a_drsize || execp->a_trsize) 515 1.1 christos abfd->flags |= HAS_RELOC; 516 1.1 christos /* Setting of EXEC_P has been deferred to the bottom of this function. */ 517 1.1 christos if (execp->a_syms) 518 1.1 christos abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; 519 1.1.1.5 christos if (N_DYNAMIC (execp)) 520 1.1 christos abfd->flags |= DYNAMIC; 521 1.1 christos 522 1.1.1.5 christos if (N_MAGIC (execp) == ZMAGIC) 523 1.1 christos { 524 1.1 christos abfd->flags |= D_PAGED | WP_TEXT; 525 1.1 christos adata (abfd).magic = z_magic; 526 1.1 christos } 527 1.1.1.8 christos else if (N_IS_QMAGIC (execp)) 528 1.1 christos { 529 1.1 christos abfd->flags |= D_PAGED | WP_TEXT; 530 1.1 christos adata (abfd).magic = z_magic; 531 1.1 christos adata (abfd).subformat = q_magic_format; 532 1.1 christos } 533 1.1.1.5 christos else if (N_MAGIC (execp) == NMAGIC) 534 1.1 christos { 535 1.1 christos abfd->flags |= WP_TEXT; 536 1.1 christos adata (abfd).magic = n_magic; 537 1.1 christos } 538 1.1.1.8 christos else if (N_MAGIC (execp) == OMAGIC || N_IS_BMAGIC (execp)) 539 1.1 christos adata (abfd).magic = o_magic; 540 1.1 christos else 541 1.1 christos /* Should have been checked with N_BADMAG before this routine 542 1.1 christos was called. */ 543 1.1 christos abort (); 544 1.1 christos 545 1.1.1.8 christos abfd->start_address = execp->a_entry; 546 1.1 christos 547 1.1.1.8 christos abfd->symcount = execp->a_syms / sizeof (struct external_nlist); 548 1.1 christos 549 1.1 christos /* The default relocation entry size is that of traditional V7 Unix. */ 550 1.1 christos obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 551 1.1 christos 552 1.1 christos /* The default symbol entry size is that of traditional Unix. */ 553 1.1 christos obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE; 554 1.1 christos 555 1.1 christos if (! NAME (aout, make_sections) (abfd)) 556 1.1 christos goto error_ret; 557 1.1 christos 558 1.1 christos obj_datasec (abfd)->size = execp->a_data; 559 1.1 christos obj_bsssec (abfd)->size = execp->a_bss; 560 1.1 christos 561 1.1 christos obj_textsec (abfd)->flags = 562 1.1 christos (execp->a_trsize != 0 563 1.1 christos ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) 564 1.1 christos : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); 565 1.1 christos obj_datasec (abfd)->flags = 566 1.1 christos (execp->a_drsize != 0 567 1.1 christos ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) 568 1.1 christos : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); 569 1.1 christos obj_bsssec (abfd)->flags = SEC_ALLOC; 570 1.1 christos 571 1.1 christos #ifdef THIS_IS_ONLY_DOCUMENTATION 572 1.1 christos /* The common code can't fill in these things because they depend 573 1.1 christos on either the start address of the text segment, the rounding 574 1.1 christos up of virtual addresses between segments, or the starting file 575 1.1 christos position of the text segment -- all of which varies among different 576 1.1 christos versions of a.out. */ 577 1.1 christos 578 1.1 christos /* Call back to the format-dependent code to fill in the rest of the 579 1.1 christos fields and do any further cleanup. Things that should be filled 580 1.1 christos in by the callback: */ 581 1.1 christos struct exec *execp = exec_hdr (abfd); 582 1.1 christos 583 1.1.1.5 christos obj_textsec (abfd)->size = N_TXTSIZE (execp); 584 1.1 christos /* Data and bss are already filled in since they're so standard. */ 585 1.1 christos 586 1.1 christos /* The virtual memory addresses of the sections. */ 587 1.1.1.5 christos obj_textsec (abfd)->vma = N_TXTADDR (execp); 588 1.1.1.5 christos obj_datasec (abfd)->vma = N_DATADDR (execp); 589 1.1.1.5 christos obj_bsssec (abfd)->vma = N_BSSADDR (execp); 590 1.1 christos 591 1.1 christos /* The file offsets of the sections. */ 592 1.1.1.5 christos obj_textsec (abfd)->filepos = N_TXTOFF (execp); 593 1.1.1.5 christos obj_datasec (abfd)->filepos = N_DATOFF (execp); 594 1.1 christos 595 1.1 christos /* The file offsets of the relocation info. */ 596 1.1.1.5 christos obj_textsec (abfd)->rel_filepos = N_TRELOFF (execp); 597 1.1.1.5 christos obj_datasec (abfd)->rel_filepos = N_DRELOFF (execp); 598 1.1 christos 599 1.1 christos /* The file offsets of the string table and symbol table. */ 600 1.1.1.5 christos obj_str_filepos (abfd) = N_STROFF (execp); 601 1.1.1.5 christos obj_sym_filepos (abfd) = N_SYMOFF (execp); 602 1.1 christos 603 1.1 christos /* Determine the architecture and machine type of the object file. */ 604 1.1.1.10 christos abfd->obj_arch = bfd_arch_obscure; 605 1.1 christos 606 1.1 christos adata (abfd)->page_size = TARGET_PAGE_SIZE; 607 1.1 christos adata (abfd)->segment_size = SEGMENT_SIZE; 608 1.1 christos adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE; 609 1.1 christos 610 1.1.1.10 christos return _bfd_no_cleanup; 611 1.1 christos 612 1.1 christos /* The architecture is encoded in various ways in various a.out variants, 613 1.1 christos or is not encoded at all in some of them. The relocation size depends 614 1.1 christos on the architecture and the a.out variant. Finally, the return value 615 1.1 christos is the bfd_target vector in use. If an error occurs, return zero and 616 1.1 christos set bfd_error to the appropriate error code. 617 1.1 christos 618 1.1 christos Formats such as b.out, which have additional fields in the a.out 619 1.1 christos header, should cope with them in this callback as well. */ 620 1.1.1.10 christos #endif /* DOCUMENTATION */ 621 1.1 christos 622 1.1 christos result = (*callback_to_real_object_p) (abfd); 623 1.1 christos 624 1.1 christos /* Now that the segment addresses have been worked out, take a better 625 1.1 christos guess at whether the file is executable. If the entry point 626 1.1 christos is within the text segment, assume it is. (This makes files 627 1.1 christos executable even if their entry point address is 0, as long as 628 1.1 christos their text starts at zero.). 629 1.1 christos 630 1.1 christos This test had to be changed to deal with systems where the text segment 631 1.1 christos runs at a different location than the default. The problem is that the 632 1.1 christos entry address can appear to be outside the text segment, thus causing an 633 1.1 christos erroneous conclusion that the file isn't executable. 634 1.1 christos 635 1.1 christos To fix this, we now accept any non-zero entry point as an indication of 636 1.1 christos executability. This will work most of the time, since only the linker 637 1.1 christos sets the entry point, and that is likely to be non-zero for most systems. */ 638 1.1 christos 639 1.1 christos if (execp->a_entry != 0 640 1.1 christos || (execp->a_entry >= obj_textsec (abfd)->vma 641 1.1 christos && execp->a_entry < (obj_textsec (abfd)->vma 642 1.1 christos + obj_textsec (abfd)->size) 643 1.1 christos && execp->a_trsize == 0 644 1.1 christos && execp->a_drsize == 0)) 645 1.1 christos abfd->flags |= EXEC_P; 646 1.1 christos #ifdef STAT_FOR_EXEC 647 1.1 christos else 648 1.1 christos { 649 1.1 christos struct stat stat_buf; 650 1.1 christos 651 1.1 christos /* The original heuristic doesn't work in some important cases. 652 1.1.1.7 christos The a.out file has no information about the text start 653 1.1.1.7 christos address. For files (like kernels) linked to non-standard 654 1.1.1.7 christos addresses (ld -Ttext nnn) the entry point may not be between 655 1.1.1.7 christos the default text start (obj_textsec(abfd)->vma) and 656 1.1.1.7 christos (obj_textsec(abfd)->vma) + text size. This is not just a mach 657 1.1.1.7 christos issue. Many kernels are loaded at non standard addresses. */ 658 1.1 christos if (abfd->iostream != NULL 659 1.1 christos && (abfd->flags & BFD_IN_MEMORY) == 0 660 1.1 christos && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0) 661 1.1 christos && ((stat_buf.st_mode & 0111) != 0)) 662 1.1 christos abfd->flags |= EXEC_P; 663 1.1 christos } 664 1.1 christos #endif /* STAT_FOR_EXEC */ 665 1.1 christos 666 1.1 christos if (result) 667 1.1 christos return result; 668 1.1 christos 669 1.1 christos error_ret: 670 1.1 christos bfd_release (abfd, rawptr); 671 1.1 christos return NULL; 672 1.1 christos } 673 1.1 christos 674 1.1 christos /* 675 1.1 christos FUNCTION 676 1.1 christos aout_@var{size}_mkobject 677 1.1 christos 678 1.1 christos SYNOPSIS 679 1.1.1.9 christos bool aout_@var{size}_mkobject, (bfd *abfd); 680 1.1 christos 681 1.1 christos DESCRIPTION 682 1.1 christos Initialize BFD @var{abfd} for use with a.out files. 683 1.1 christos */ 684 1.1 christos 685 1.1.1.9 christos bool 686 1.1 christos NAME (aout, mkobject) (bfd *abfd) 687 1.1 christos { 688 1.1 christos struct aout_data_struct *rawptr; 689 1.1.1.8 christos size_t amt = sizeof (* rawptr); 690 1.1 christos 691 1.1 christos bfd_set_error (bfd_error_system_call); 692 1.1 christos 693 1.1 christos rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt); 694 1.1 christos if (rawptr == NULL) 695 1.1.1.9 christos return false; 696 1.1 christos 697 1.1 christos abfd->tdata.aout_data = rawptr; 698 1.1 christos exec_hdr (abfd) = &(rawptr->e); 699 1.1 christos 700 1.1 christos obj_textsec (abfd) = NULL; 701 1.1 christos obj_datasec (abfd) = NULL; 702 1.1 christos obj_bsssec (abfd) = NULL; 703 1.1 christos 704 1.1.1.9 christos return true; 705 1.1 christos } 706 1.1 christos 707 1.1 christos /* 708 1.1 christos FUNCTION 709 1.1 christos aout_@var{size}_machine_type 710 1.1 christos 711 1.1 christos SYNOPSIS 712 1.1 christos enum machine_type aout_@var{size}_machine_type 713 1.1 christos (enum bfd_architecture arch, 714 1.1 christos unsigned long machine, 715 1.1.1.9 christos bool *unknown); 716 1.1 christos 717 1.1 christos DESCRIPTION 718 1.1 christos Keep track of machine architecture and machine type for 719 1.1 christos a.out's. Return the <<machine_type>> for a particular 720 1.1 christos architecture and machine, or <<M_UNKNOWN>> if that exact architecture 721 1.1 christos and machine can't be represented in a.out format. 722 1.1 christos 723 1.1 christos If the architecture is understood, machine type 0 (default) 724 1.1 christos is always understood. 725 1.1 christos */ 726 1.1 christos 727 1.1 christos enum machine_type 728 1.1 christos NAME (aout, machine_type) (enum bfd_architecture arch, 729 1.1 christos unsigned long machine, 730 1.1.1.9 christos bool *unknown) 731 1.1 christos { 732 1.1 christos enum machine_type arch_flags; 733 1.1 christos 734 1.1 christos arch_flags = M_UNKNOWN; 735 1.1.1.9 christos *unknown = true; 736 1.1 christos 737 1.1 christos switch (arch) 738 1.1 christos { 739 1.1 christos case bfd_arch_sparc: 740 1.1 christos if (machine == 0 741 1.1 christos || machine == bfd_mach_sparc 742 1.1 christos || machine == bfd_mach_sparc_sparclite 743 1.1 christos || machine == bfd_mach_sparc_sparclite_le 744 1.1 christos || machine == bfd_mach_sparc_v8plus 745 1.1 christos || machine == bfd_mach_sparc_v8plusa 746 1.1 christos || machine == bfd_mach_sparc_v8plusb 747 1.1.1.7 christos || machine == bfd_mach_sparc_v8plusc 748 1.1.1.7 christos || machine == bfd_mach_sparc_v8plusd 749 1.1.1.7 christos || machine == bfd_mach_sparc_v8pluse 750 1.1.1.7 christos || machine == bfd_mach_sparc_v8plusv 751 1.1.1.7 christos || machine == bfd_mach_sparc_v8plusm 752 1.1.1.7 christos || machine == bfd_mach_sparc_v8plusm8 753 1.1 christos || machine == bfd_mach_sparc_v9 754 1.1 christos || machine == bfd_mach_sparc_v9a 755 1.1.1.5 christos || machine == bfd_mach_sparc_v9b 756 1.1.1.7 christos || machine == bfd_mach_sparc_v9c 757 1.1.1.7 christos || machine == bfd_mach_sparc_v9d 758 1.1.1.7 christos || machine == bfd_mach_sparc_v9e 759 1.1.1.7 christos || machine == bfd_mach_sparc_v9v 760 1.1.1.7 christos || machine == bfd_mach_sparc_v9m 761 1.1.1.7 christos || machine == bfd_mach_sparc_v9m8) 762 1.1 christos arch_flags = M_SPARC; 763 1.1 christos else if (machine == bfd_mach_sparc_sparclet) 764 1.1 christos arch_flags = M_SPARCLET; 765 1.1 christos break; 766 1.1 christos 767 1.1 christos case bfd_arch_i386: 768 1.1 christos if (machine == 0 769 1.1 christos || machine == bfd_mach_i386_i386 770 1.1 christos || machine == bfd_mach_i386_i386_intel_syntax) 771 1.1 christos arch_flags = M_386; 772 1.1 christos break; 773 1.1 christos 774 1.1 christos case bfd_arch_arm: 775 1.1 christos if (machine == 0) 776 1.1 christos arch_flags = M_ARM; 777 1.1 christos break; 778 1.1 christos 779 1.1 christos case bfd_arch_mips: 780 1.1 christos switch (machine) 781 1.1 christos { 782 1.1 christos case 0: 783 1.1 christos case bfd_mach_mips3000: 784 1.1 christos case bfd_mach_mips3900: 785 1.1 christos arch_flags = M_MIPS1; 786 1.1 christos break; 787 1.1 christos case bfd_mach_mips6000: 788 1.1 christos arch_flags = M_MIPS2; 789 1.1 christos break; 790 1.1 christos case bfd_mach_mips4000: 791 1.1 christos case bfd_mach_mips4010: 792 1.1 christos case bfd_mach_mips4100: 793 1.1 christos case bfd_mach_mips4300: 794 1.1 christos case bfd_mach_mips4400: 795 1.1 christos case bfd_mach_mips4600: 796 1.1 christos case bfd_mach_mips4650: 797 1.1 christos case bfd_mach_mips8000: 798 1.1 christos case bfd_mach_mips9000: 799 1.1 christos case bfd_mach_mips10000: 800 1.1 christos case bfd_mach_mips12000: 801 1.1 christos case bfd_mach_mips14000: 802 1.1 christos case bfd_mach_mips16000: 803 1.1 christos case bfd_mach_mips16: 804 1.1 christos case bfd_mach_mipsisa32: 805 1.1 christos case bfd_mach_mipsisa32r2: 806 1.1.1.3 christos case bfd_mach_mipsisa32r3: 807 1.1.1.3 christos case bfd_mach_mipsisa32r5: 808 1.1.1.3 christos case bfd_mach_mipsisa32r6: 809 1.1 christos case bfd_mach_mips5: 810 1.1 christos case bfd_mach_mipsisa64: 811 1.1 christos case bfd_mach_mipsisa64r2: 812 1.1.1.3 christos case bfd_mach_mipsisa64r3: 813 1.1.1.3 christos case bfd_mach_mipsisa64r5: 814 1.1.1.3 christos case bfd_mach_mipsisa64r6: 815 1.1 christos case bfd_mach_mips_sb1: 816 1.1 christos case bfd_mach_mips_xlr: 817 1.1 christos /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */ 818 1.1 christos arch_flags = M_MIPS2; 819 1.1 christos break; 820 1.1 christos default: 821 1.1 christos arch_flags = M_UNKNOWN; 822 1.1 christos break; 823 1.1 christos } 824 1.1 christos break; 825 1.1 christos 826 1.1 christos case bfd_arch_ns32k: 827 1.1 christos switch (machine) 828 1.1 christos { 829 1.1.1.7 christos case 0: arch_flags = M_NS32532; break; 830 1.1 christos case 32032: arch_flags = M_NS32032; break; 831 1.1 christos case 32532: arch_flags = M_NS32532; break; 832 1.1 christos default: arch_flags = M_UNKNOWN; break; 833 1.1 christos } 834 1.1 christos break; 835 1.1 christos 836 1.1 christos case bfd_arch_vax: 837 1.1.1.9 christos *unknown = false; 838 1.1 christos break; 839 1.1 christos 840 1.1 christos case bfd_arch_cris: 841 1.1 christos if (machine == 0 || machine == 255) 842 1.1 christos arch_flags = M_CRIS; 843 1.1 christos break; 844 1.1 christos 845 1.1 christos default: 846 1.1 christos arch_flags = M_UNKNOWN; 847 1.1 christos } 848 1.1 christos 849 1.1 christos if (arch_flags != M_UNKNOWN) 850 1.1.1.9 christos *unknown = false; 851 1.1 christos 852 1.1 christos return arch_flags; 853 1.1 christos } 854 1.1 christos 855 1.1 christos /* 856 1.1 christos FUNCTION 857 1.1 christos aout_@var{size}_set_arch_mach 858 1.1 christos 859 1.1 christos SYNOPSIS 860 1.1.1.9 christos bool aout_@var{size}_set_arch_mach, 861 1.1 christos (bfd *, 862 1.1 christos enum bfd_architecture arch, 863 1.1 christos unsigned long machine); 864 1.1 christos 865 1.1 christos DESCRIPTION 866 1.1 christos Set the architecture and the machine of the BFD @var{abfd} to the 867 1.1 christos values @var{arch} and @var{machine}. Verify that @var{abfd}'s format 868 1.1 christos can support the architecture required. 869 1.1 christos */ 870 1.1 christos 871 1.1.1.9 christos bool 872 1.1 christos NAME (aout, set_arch_mach) (bfd *abfd, 873 1.1 christos enum bfd_architecture arch, 874 1.1 christos unsigned long machine) 875 1.1 christos { 876 1.1 christos if (! bfd_default_set_arch_mach (abfd, arch, machine)) 877 1.1.1.9 christos return false; 878 1.1 christos 879 1.1 christos if (arch != bfd_arch_unknown) 880 1.1 christos { 881 1.1.1.9 christos bool unknown; 882 1.1 christos 883 1.1 christos NAME (aout, machine_type) (arch, machine, &unknown); 884 1.1 christos if (unknown) 885 1.1.1.9 christos return false; 886 1.1 christos } 887 1.1 christos 888 1.1 christos /* Determine the size of a relocation entry. */ 889 1.1 christos switch (arch) 890 1.1 christos { 891 1.1 christos case bfd_arch_sparc: 892 1.1 christos case bfd_arch_mips: 893 1.1 christos obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; 894 1.1 christos break; 895 1.1 christos default: 896 1.1 christos obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 897 1.1 christos break; 898 1.1 christos } 899 1.1 christos 900 1.1 christos return (*aout_backend_info (abfd)->set_sizes) (abfd); 901 1.1 christos } 902 1.1 christos 903 1.1 christos static void 904 1.1 christos adjust_o_magic (bfd *abfd, struct internal_exec *execp) 905 1.1 christos { 906 1.1 christos file_ptr pos = adata (abfd).exec_bytes_size; 907 1.1 christos bfd_vma vma = 0; 908 1.1 christos int pad = 0; 909 1.1.1.8 christos asection *text = obj_textsec (abfd); 910 1.1.1.8 christos asection *data = obj_datasec (abfd); 911 1.1.1.8 christos asection *bss = obj_bsssec (abfd); 912 1.1 christos 913 1.1 christos /* Text. */ 914 1.1.1.8 christos text->filepos = pos; 915 1.1.1.8 christos if (!text->user_set_vma) 916 1.1.1.8 christos text->vma = vma; 917 1.1 christos else 918 1.1.1.8 christos vma = text->vma; 919 1.1 christos 920 1.1.1.8 christos pos += execp->a_text; 921 1.1.1.8 christos vma += execp->a_text; 922 1.1 christos 923 1.1 christos /* Data. */ 924 1.1.1.8 christos if (!data->user_set_vma) 925 1.1 christos { 926 1.1 christos pos += pad; 927 1.1 christos vma += pad; 928 1.1.1.8 christos data->vma = vma; 929 1.1 christos } 930 1.1 christos else 931 1.1.1.8 christos vma = data->vma; 932 1.1.1.8 christos execp->a_text += pad; 933 1.1.1.8 christos 934 1.1.1.8 christos data->filepos = pos; 935 1.1.1.8 christos pos += data->size; 936 1.1.1.8 christos vma += data->size; 937 1.1 christos 938 1.1 christos /* BSS. */ 939 1.1.1.8 christos if (!bss->user_set_vma) 940 1.1 christos { 941 1.1 christos pos += pad; 942 1.1 christos vma += pad; 943 1.1.1.8 christos bss->vma = vma; 944 1.1 christos } 945 1.1 christos else 946 1.1 christos { 947 1.1 christos /* The VMA of the .bss section is set by the VMA of the 948 1.1.1.7 christos .data section plus the size of the .data section. We may 949 1.1.1.7 christos need to add padding bytes to make this true. */ 950 1.1.1.8 christos pad = bss->vma - vma; 951 1.1.1.8 christos if (pad < 0) 952 1.1.1.8 christos pad = 0; 953 1.1.1.8 christos pos += pad; 954 1.1 christos } 955 1.1.1.8 christos execp->a_data = data->size + pad; 956 1.1.1.8 christos bss->filepos = pos; 957 1.1.1.8 christos execp->a_bss = bss->size; 958 1.1 christos 959 1.1.1.5 christos N_SET_MAGIC (execp, OMAGIC); 960 1.1 christos } 961 1.1 christos 962 1.1 christos static void 963 1.1 christos adjust_z_magic (bfd *abfd, struct internal_exec *execp) 964 1.1 christos { 965 1.1 christos bfd_size_type data_pad, text_pad; 966 1.1 christos file_ptr text_end; 967 1.1 christos const struct aout_backend_data *abdp; 968 1.1 christos /* TRUE if text includes exec header. */ 969 1.1.1.9 christos bool ztih; 970 1.1.1.8 christos asection *text = obj_textsec (abfd); 971 1.1.1.8 christos asection *data = obj_datasec (abfd); 972 1.1.1.8 christos asection *bss = obj_bsssec (abfd); 973 1.1 christos 974 1.1 christos abdp = aout_backend_info (abfd); 975 1.1 christos 976 1.1 christos /* Text. */ 977 1.1 christos ztih = (abdp != NULL 978 1.1 christos && (abdp->text_includes_header 979 1.1 christos || obj_aout_subformat (abfd) == q_magic_format)); 980 1.1.1.8 christos text->filepos = (ztih 981 1.1.1.8 christos ? adata (abfd).exec_bytes_size 982 1.1.1.8 christos : adata (abfd).zmagic_disk_block_size); 983 1.1.1.8 christos if (!text->user_set_vma) 984 1.1 christos { 985 1.1 christos /* ?? Do we really need to check for relocs here? */ 986 1.1.1.8 christos text->vma = ((abfd->flags & HAS_RELOC) 987 1.1.1.8 christos ? 0 988 1.1.1.8 christos : (ztih 989 1.1.1.8 christos ? abdp->default_text_vma + adata (abfd).exec_bytes_size 990 1.1.1.8 christos : abdp->default_text_vma)); 991 1.1 christos text_pad = 0; 992 1.1 christos } 993 1.1 christos else 994 1.1 christos { 995 1.1 christos /* The .text section is being loaded at an unusual address. We 996 1.1.1.7 christos may need to pad it such that the .data section starts at a page 997 1.1.1.7 christos boundary. */ 998 1.1 christos if (ztih) 999 1.1.1.8 christos text_pad = ((text->filepos - text->vma) 1000 1.1 christos & (adata (abfd).page_size - 1)); 1001 1.1 christos else 1002 1.1.1.8 christos text_pad = (-text->vma 1003 1.1 christos & (adata (abfd).page_size - 1)); 1004 1.1 christos } 1005 1.1 christos 1006 1.1 christos /* Find start of data. */ 1007 1.1 christos if (ztih) 1008 1.1 christos { 1009 1.1.1.8 christos text_end = text->filepos + execp->a_text; 1010 1.1 christos text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; 1011 1.1 christos } 1012 1.1 christos else 1013 1.1 christos { 1014 1.1 christos /* Note that if page_size == zmagic_disk_block_size, then 1015 1.1 christos filepos == page_size, and this case is the same as the ztih 1016 1.1 christos case. */ 1017 1.1.1.8 christos text_end = execp->a_text; 1018 1.1 christos text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; 1019 1.1.1.8 christos text_end += text->filepos; 1020 1.1 christos } 1021 1.1.1.8 christos execp->a_text += text_pad; 1022 1.1 christos 1023 1.1 christos /* Data. */ 1024 1.1.1.8 christos if (!data->user_set_vma) 1025 1.1 christos { 1026 1.1 christos bfd_vma vma; 1027 1.1.1.8 christos vma = text->vma + execp->a_text; 1028 1.1.1.8 christos data->vma = BFD_ALIGN (vma, adata (abfd).segment_size); 1029 1.1 christos } 1030 1.1 christos if (abdp && abdp->zmagic_mapped_contiguous) 1031 1.1 christos { 1032 1.1.1.8 christos text_pad = data->vma - (text->vma + execp->a_text); 1033 1.1 christos /* Only pad the text section if the data 1034 1.1 christos section is going to be placed after it. */ 1035 1.1 christos if (text_pad > 0) 1036 1.1.1.8 christos execp->a_text += text_pad; 1037 1.1 christos } 1038 1.1.1.8 christos data->filepos = text->filepos + execp->a_text; 1039 1.1 christos 1040 1.1 christos /* Fix up exec header while we're at it. */ 1041 1.1 christos if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted))) 1042 1.1 christos execp->a_text += adata (abfd).exec_bytes_size; 1043 1.1 christos if (obj_aout_subformat (abfd) == q_magic_format) 1044 1.1.1.8 christos N_SET_QMAGIC (execp); 1045 1.1 christos else 1046 1.1.1.5 christos N_SET_MAGIC (execp, ZMAGIC); 1047 1.1 christos 1048 1.1 christos /* Spec says data section should be rounded up to page boundary. */ 1049 1.1.1.8 christos execp->a_data = align_power (data->size, bss->alignment_power); 1050 1.1.1.8 christos execp->a_data = BFD_ALIGN (execp->a_data, adata (abfd).page_size); 1051 1.1.1.8 christos data_pad = execp->a_data - data->size; 1052 1.1 christos 1053 1.1 christos /* BSS. */ 1054 1.1.1.8 christos if (!bss->user_set_vma) 1055 1.1.1.8 christos bss->vma = data->vma + execp->a_data; 1056 1.1 christos /* If the BSS immediately follows the data section and extra space 1057 1.1 christos in the page is left after the data section, fudge data 1058 1.1 christos in the header so that the bss section looks smaller by that 1059 1.1 christos amount. We'll start the bss section there, and lie to the OS. 1060 1.1 christos (Note that a linker script, as well as the above assignment, 1061 1.1 christos could have explicitly set the BSS vma to immediately follow 1062 1.1 christos the data section.) */ 1063 1.1.1.8 christos if (align_power (bss->vma, bss->alignment_power) == data->vma + execp->a_data) 1064 1.1.1.8 christos execp->a_bss = data_pad > bss->size ? 0 : bss->size - data_pad; 1065 1.1 christos else 1066 1.1.1.8 christos execp->a_bss = bss->size; 1067 1.1 christos } 1068 1.1 christos 1069 1.1 christos static void 1070 1.1 christos adjust_n_magic (bfd *abfd, struct internal_exec *execp) 1071 1.1 christos { 1072 1.1 christos file_ptr pos = adata (abfd).exec_bytes_size; 1073 1.1 christos bfd_vma vma = 0; 1074 1.1 christos int pad; 1075 1.1.1.8 christos asection *text = obj_textsec (abfd); 1076 1.1.1.8 christos asection *data = obj_datasec (abfd); 1077 1.1.1.8 christos asection *bss = obj_bsssec (abfd); 1078 1.1 christos 1079 1.1 christos /* Text. */ 1080 1.1.1.8 christos text->filepos = pos; 1081 1.1.1.8 christos if (!text->user_set_vma) 1082 1.1.1.8 christos text->vma = vma; 1083 1.1 christos else 1084 1.1.1.8 christos vma = text->vma; 1085 1.1.1.8 christos pos += execp->a_text; 1086 1.1.1.8 christos vma += execp->a_text; 1087 1.1 christos 1088 1.1 christos /* Data. */ 1089 1.1.1.8 christos data->filepos = pos; 1090 1.1.1.8 christos if (!data->user_set_vma) 1091 1.1.1.8 christos data->vma = BFD_ALIGN (vma, adata (abfd).segment_size); 1092 1.1.1.8 christos vma = data->vma; 1093 1.1 christos 1094 1.1 christos /* Since BSS follows data immediately, see if it needs alignment. */ 1095 1.1.1.8 christos vma += data->size; 1096 1.1.1.8 christos pad = align_power (vma, bss->alignment_power) - vma; 1097 1.1.1.8 christos execp->a_data = data->size + pad; 1098 1.1.1.8 christos pos += execp->a_data; 1099 1.1 christos 1100 1.1 christos /* BSS. */ 1101 1.1.1.8 christos if (!bss->user_set_vma) 1102 1.1.1.8 christos bss->vma = vma; 1103 1.1 christos else 1104 1.1.1.8 christos vma = bss->vma; 1105 1.1 christos 1106 1.1 christos /* Fix up exec header. */ 1107 1.1.1.8 christos execp->a_bss = bss->size; 1108 1.1.1.5 christos N_SET_MAGIC (execp, NMAGIC); 1109 1.1 christos } 1110 1.1 christos 1111 1.1.1.9 christos bool 1112 1.1.1.5 christos NAME (aout, adjust_sizes_and_vmas) (bfd *abfd) 1113 1.1 christos { 1114 1.1 christos struct internal_exec *execp = exec_hdr (abfd); 1115 1.1 christos 1116 1.1 christos if (! NAME (aout, make_sections) (abfd)) 1117 1.1.1.9 christos return false; 1118 1.1 christos 1119 1.1 christos if (adata (abfd).magic != undecided_magic) 1120 1.1.1.9 christos return true; 1121 1.1 christos 1122 1.1.1.8 christos execp->a_text = align_power (obj_textsec (abfd)->size, 1123 1.1.1.8 christos obj_textsec (abfd)->alignment_power); 1124 1.1 christos 1125 1.1 christos /* Rule (heuristic) for when to pad to a new page. Note that there 1126 1.1 christos are (at least) two ways demand-paged (ZMAGIC) files have been 1127 1.1 christos handled. Most Berkeley-based systems start the text segment at 1128 1.1 christos (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text 1129 1.1 christos segment right after the exec header; the latter is counted in the 1130 1.1 christos text segment size, and is paged in by the kernel with the rest of 1131 1.1 christos the text. */ 1132 1.1 christos 1133 1.1 christos /* This perhaps isn't the right way to do this, but made it simpler for me 1134 1.1 christos to understand enough to implement it. Better would probably be to go 1135 1.1 christos right from BFD flags to alignment/positioning characteristics. But the 1136 1.1 christos old code was sloppy enough about handling the flags, and had enough 1137 1.1 christos other magic, that it was a little hard for me to understand. I think 1138 1.1 christos I understand it better now, but I haven't time to do the cleanup this 1139 1.1 christos minute. */ 1140 1.1 christos 1141 1.1 christos if (abfd->flags & D_PAGED) 1142 1.1 christos /* Whether or not WP_TEXT is set -- let D_PAGED override. */ 1143 1.1 christos adata (abfd).magic = z_magic; 1144 1.1 christos else if (abfd->flags & WP_TEXT) 1145 1.1 christos adata (abfd).magic = n_magic; 1146 1.1 christos else 1147 1.1 christos adata (abfd).magic = o_magic; 1148 1.1 christos 1149 1.1 christos #ifdef BFD_AOUT_DEBUG /* requires gcc2 */ 1150 1.1 christos #if __GNUC__ >= 2 1151 1.1 christos fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n", 1152 1.1 christos ({ char *str; 1153 1.1 christos switch (adata (abfd).magic) 1154 1.1 christos { 1155 1.1 christos case n_magic: str = "NMAGIC"; break; 1156 1.1 christos case o_magic: str = "OMAGIC"; break; 1157 1.1 christos case z_magic: str = "ZMAGIC"; break; 1158 1.1 christos default: abort (); 1159 1.1 christos } 1160 1.1 christos str; 1161 1.1 christos }), 1162 1.1 christos obj_textsec (abfd)->vma, obj_textsec (abfd)->size, 1163 1.1.1.7 christos obj_textsec (abfd)->alignment_power, 1164 1.1 christos obj_datasec (abfd)->vma, obj_datasec (abfd)->size, 1165 1.1.1.7 christos obj_datasec (abfd)->alignment_power, 1166 1.1 christos obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size, 1167 1.1.1.7 christos obj_bsssec (abfd)->alignment_power); 1168 1.1 christos #endif 1169 1.1 christos #endif 1170 1.1 christos 1171 1.1 christos switch (adata (abfd).magic) 1172 1.1 christos { 1173 1.1 christos case o_magic: 1174 1.1 christos adjust_o_magic (abfd, execp); 1175 1.1 christos break; 1176 1.1 christos case z_magic: 1177 1.1 christos adjust_z_magic (abfd, execp); 1178 1.1 christos break; 1179 1.1 christos case n_magic: 1180 1.1 christos adjust_n_magic (abfd, execp); 1181 1.1 christos break; 1182 1.1 christos default: 1183 1.1 christos abort (); 1184 1.1 christos } 1185 1.1 christos 1186 1.1 christos #ifdef BFD_AOUT_DEBUG 1187 1.1 christos fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n", 1188 1.1.1.8 christos obj_textsec (abfd)->vma, execp->a_text, 1189 1.1.1.7 christos obj_textsec (abfd)->filepos, 1190 1.1.1.8 christos obj_datasec (abfd)->vma, execp->a_data, 1191 1.1.1.7 christos obj_datasec (abfd)->filepos, 1192 1.1.1.8 christos obj_bsssec (abfd)->vma, execp->a_bss); 1193 1.1 christos #endif 1194 1.1 christos 1195 1.1.1.9 christos return true; 1196 1.1 christos } 1197 1.1 christos 1198 1.1 christos /* 1199 1.1 christos FUNCTION 1200 1.1 christos aout_@var{size}_new_section_hook 1201 1.1 christos 1202 1.1 christos SYNOPSIS 1203 1.1.1.9 christos bool aout_@var{size}_new_section_hook, 1204 1.1 christos (bfd *abfd, 1205 1.1 christos asection *newsect); 1206 1.1 christos 1207 1.1 christos DESCRIPTION 1208 1.1 christos Called by the BFD in response to a @code{bfd_make_section} 1209 1.1 christos request. 1210 1.1 christos */ 1211 1.1.1.9 christos bool 1212 1.1 christos NAME (aout, new_section_hook) (bfd *abfd, asection *newsect) 1213 1.1 christos { 1214 1.1 christos /* Align to double at least. */ 1215 1.1 christos newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power; 1216 1.1 christos 1217 1.1 christos if (bfd_get_format (abfd) == bfd_object) 1218 1.1 christos { 1219 1.1 christos if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text")) 1220 1.1 christos { 1221 1.1 christos obj_textsec (abfd)= newsect; 1222 1.1 christos newsect->target_index = N_TEXT; 1223 1.1 christos } 1224 1.1 christos else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data")) 1225 1.1 christos { 1226 1.1 christos obj_datasec (abfd) = newsect; 1227 1.1 christos newsect->target_index = N_DATA; 1228 1.1 christos } 1229 1.1 christos else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss")) 1230 1.1 christos { 1231 1.1 christos obj_bsssec (abfd) = newsect; 1232 1.1 christos newsect->target_index = N_BSS; 1233 1.1 christos } 1234 1.1 christos } 1235 1.1 christos 1236 1.1 christos /* We allow more than three sections internally. */ 1237 1.1 christos return _bfd_generic_new_section_hook (abfd, newsect); 1238 1.1 christos } 1239 1.1 christos 1240 1.1.1.9 christos bool 1241 1.1 christos NAME (aout, set_section_contents) (bfd *abfd, 1242 1.1 christos sec_ptr section, 1243 1.1 christos const void * location, 1244 1.1 christos file_ptr offset, 1245 1.1 christos bfd_size_type count) 1246 1.1 christos { 1247 1.1 christos if (! abfd->output_has_begun) 1248 1.1 christos { 1249 1.1.1.5 christos if (! NAME (aout, adjust_sizes_and_vmas) (abfd)) 1250 1.1.1.9 christos return false; 1251 1.1 christos } 1252 1.1 christos 1253 1.1 christos if (section == obj_bsssec (abfd)) 1254 1.1 christos { 1255 1.1 christos bfd_set_error (bfd_error_no_contents); 1256 1.1.1.9 christos return false; 1257 1.1 christos } 1258 1.1 christos 1259 1.1 christos if (section != obj_textsec (abfd) 1260 1.1 christos && section != obj_datasec (abfd)) 1261 1.1 christos { 1262 1.1 christos if (aout_section_merge_with_text_p (abfd, section)) 1263 1.1 christos section->filepos = obj_textsec (abfd)->filepos + 1264 1.1 christos (section->vma - obj_textsec (abfd)->vma); 1265 1.1 christos else 1266 1.1 christos { 1267 1.1.1.6 christos _bfd_error_handler 1268 1.1.1.6 christos /* xgettext:c-format */ 1269 1.1.1.7 christos (_("%pB: can not represent section `%pA' in a.out object file format"), 1270 1.1.1.6 christos abfd, section); 1271 1.1.1.7 christos bfd_set_error (bfd_error_nonrepresentable_section); 1272 1.1.1.9 christos return false; 1273 1.1 christos } 1274 1.1 christos } 1275 1.1 christos 1276 1.1 christos if (count != 0) 1277 1.1 christos { 1278 1.1 christos if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 1279 1.1.1.10 christos || bfd_write (location, count, abfd) != count) 1280 1.1.1.9 christos return false; 1281 1.1 christos } 1282 1.1 christos 1283 1.1.1.9 christos return true; 1284 1.1 christos } 1285 1.1 christos 1286 1.1 christos /* Read the external symbols from an a.out file. */ 1288 1.1.1.9 christos 1289 1.1 christos static bool 1290 1.1 christos aout_get_external_symbols (bfd *abfd) 1291 1.1 christos { 1292 1.1 christos if (obj_aout_external_syms (abfd) == NULL) 1293 1.1 christos { 1294 1.1.1.10 christos bfd_size_type count; 1295 1.1.1.3 christos struct external_nlist *syms = NULL; 1296 1.1 christos bfd_size_type amt = exec_hdr (abfd)->a_syms; 1297 1.1.1.3 christos 1298 1.1 christos count = amt / EXTERNAL_NLIST_SIZE; 1299 1.1.1.10 christos if (count == 0) 1300 1.1 christos return true; 1301 1.1 christos 1302 1.1 christos /* We allocate using malloc to make the values easy to free 1303 1.1 christos later on. If we put them on the objalloc it might not be 1304 1.1.1.8 christos possible to free them. */ 1305 1.1.1.9 christos if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) 1306 1.1.1.10 christos return false; 1307 1.1 christos syms = _bfd_malloc_and_read (abfd, amt, amt); 1308 1.1.1.9 christos if (syms == NULL) 1309 1.1 christos return false; 1310 1.1 christos 1311 1.1 christos obj_aout_external_syms (abfd) = syms; 1312 1.1 christos obj_aout_external_sym_count (abfd) = count; 1313 1.1 christos } 1314 1.1 christos 1315 1.1 christos if (obj_aout_external_strings (abfd) == NULL 1316 1.1 christos && exec_hdr (abfd)->a_syms != 0) 1317 1.1 christos { 1318 1.1 christos unsigned char string_chars[BYTES_IN_WORD]; 1319 1.1 christos bfd_size_type stringsize; 1320 1.1 christos char *strings; 1321 1.1 christos bfd_size_type amt = BYTES_IN_WORD; 1322 1.1 christos 1323 1.1 christos /* Get the size of the strings. */ 1324 1.1.1.10 christos if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 1325 1.1.1.9 christos || bfd_read (string_chars, amt, abfd) != amt) 1326 1.1 christos return false; 1327 1.1.1.7 christos stringsize = GET_WORD (abfd, string_chars); 1328 1.1.1.7 christos if (stringsize == 0) 1329 1.1.1.10 christos stringsize = 1; 1330 1.1.1.7 christos else if (stringsize + 1 < BYTES_IN_WORD + 1 1331 1.1.1.7 christos || (size_t) stringsize != stringsize) 1332 1.1.1.7 christos { 1333 1.1.1.9 christos bfd_set_error (bfd_error_bad_value); 1334 1.1.1.7 christos return false; 1335 1.1 christos } 1336 1.1.1.10 christos 1337 1.1.1.10 christos strings = (char *) bfd_malloc (stringsize + 1); 1338 1.1.1.10 christos if (strings == NULL) 1339 1.1.1.10 christos return false; 1340 1.1.1.7 christos 1341 1.1 christos if (stringsize >= BYTES_IN_WORD) 1342 1.1.1.10 christos { 1343 1.1.1.10 christos amt = stringsize - BYTES_IN_WORD; 1344 1.1.1.7 christos if (bfd_read (strings + BYTES_IN_WORD, amt, abfd) != amt) 1345 1.1.1.10 christos { 1346 1.1.1.10 christos free (strings); 1347 1.1.1.7 christos return false; 1348 1.1.1.7 christos } 1349 1.1.1.10 christos } 1350 1.1 christos 1351 1.1.1.9 christos /* Ensure that a zero index yields an empty string. */ 1352 1.1.1.9 christos if (stringsize >= BYTES_IN_WORD) 1353 1.1 christos memset (strings, 0, BYTES_IN_WORD); 1354 1.1.1.7 christos 1355 1.1.1.7 christos /* Ensure that the string buffer is NUL terminated. */ 1356 1.1 christos strings[stringsize] = 0; 1357 1.1 christos 1358 1.1 christos obj_aout_external_strings (abfd) = strings; 1359 1.1 christos obj_aout_external_string_size (abfd) = stringsize; 1360 1.1 christos } 1361 1.1.1.9 christos 1362 1.1 christos return true; 1363 1.1 christos } 1364 1.1 christos 1365 1.1 christos /* Translate an a.out symbol into a BFD symbol. The desc, other, type 1366 1.1 christos and symbol->value fields of CACHE_PTR will be set from the a.out 1367 1.1 christos nlist structure. This function is responsible for setting 1368 1.1 christos symbol->flags and symbol->section, and adjusting symbol->value. */ 1369 1.1.1.9 christos 1370 1.1 christos static bool 1371 1.1 christos translate_from_native_sym_flags (bfd *abfd, aout_symbol_type *cache_ptr) 1372 1.1 christos { 1373 1.1 christos flagword visible; 1374 1.1 christos 1375 1.1 christos if ((cache_ptr->type & N_STAB) != 0 1376 1.1 christos || cache_ptr->type == N_FN) 1377 1.1 christos { 1378 1.1 christos asection *sec; 1379 1.1 christos 1380 1.1 christos /* This is a debugging symbol. */ 1381 1.1 christos cache_ptr->symbol.flags = BSF_DEBUGGING; 1382 1.1 christos 1383 1.1 christos /* Work out the symbol section. */ 1384 1.1 christos switch (cache_ptr->type & N_TYPE) 1385 1.1 christos { 1386 1.1 christos case N_TEXT: 1387 1.1 christos case N_FN: 1388 1.1 christos sec = obj_textsec (abfd); 1389 1.1 christos break; 1390 1.1 christos case N_DATA: 1391 1.1 christos sec = obj_datasec (abfd); 1392 1.1 christos break; 1393 1.1 christos case N_BSS: 1394 1.1 christos sec = obj_bsssec (abfd); 1395 1.1 christos break; 1396 1.1 christos default: 1397 1.1 christos case N_ABS: 1398 1.1 christos sec = bfd_abs_section_ptr; 1399 1.1 christos break; 1400 1.1 christos } 1401 1.1 christos 1402 1.1 christos cache_ptr->symbol.section = sec; 1403 1.1 christos cache_ptr->symbol.value -= sec->vma; 1404 1.1.1.9 christos 1405 1.1 christos return true; 1406 1.1 christos } 1407 1.1 christos 1408 1.1 christos /* Get the default visibility. This does not apply to all types, so 1409 1.1 christos we just hold it in a local variable to use if wanted. */ 1410 1.1 christos if ((cache_ptr->type & N_EXT) == 0) 1411 1.1 christos visible = BSF_LOCAL; 1412 1.1 christos else 1413 1.1 christos visible = BSF_GLOBAL; 1414 1.1 christos 1415 1.1 christos switch (cache_ptr->type) 1416 1.1 christos { 1417 1.1 christos default: 1418 1.1 christos case N_ABS: case N_ABS | N_EXT: 1419 1.1 christos cache_ptr->symbol.section = bfd_abs_section_ptr; 1420 1.1 christos cache_ptr->symbol.flags = visible; 1421 1.1 christos break; 1422 1.1 christos 1423 1.1 christos case N_UNDF | N_EXT: 1424 1.1 christos if (cache_ptr->symbol.value != 0) 1425 1.1 christos { 1426 1.1 christos /* This is a common symbol. */ 1427 1.1 christos cache_ptr->symbol.flags = BSF_GLOBAL; 1428 1.1 christos cache_ptr->symbol.section = bfd_com_section_ptr; 1429 1.1 christos } 1430 1.1 christos else 1431 1.1 christos { 1432 1.1 christos cache_ptr->symbol.flags = 0; 1433 1.1 christos cache_ptr->symbol.section = bfd_und_section_ptr; 1434 1.1 christos } 1435 1.1 christos break; 1436 1.1 christos 1437 1.1 christos case N_TEXT: case N_TEXT | N_EXT: 1438 1.1 christos cache_ptr->symbol.section = obj_textsec (abfd); 1439 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1440 1.1 christos cache_ptr->symbol.flags = visible; 1441 1.1 christos break; 1442 1.1 christos 1443 1.1 christos /* N_SETV symbols used to represent set vectors placed in the 1444 1.1 christos data section. They are no longer generated. Theoretically, 1445 1.1 christos it was possible to extract the entries and combine them with 1446 1.1 christos new ones, although I don't know if that was ever actually 1447 1.1 christos done. Unless that feature is restored, treat them as data 1448 1.1 christos symbols. */ 1449 1.1 christos case N_SETV: case N_SETV | N_EXT: 1450 1.1 christos case N_DATA: case N_DATA | N_EXT: 1451 1.1 christos cache_ptr->symbol.section = obj_datasec (abfd); 1452 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1453 1.1 christos cache_ptr->symbol.flags = visible; 1454 1.1 christos break; 1455 1.1 christos 1456 1.1 christos case N_BSS: case N_BSS | N_EXT: 1457 1.1 christos cache_ptr->symbol.section = obj_bsssec (abfd); 1458 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1459 1.1 christos cache_ptr->symbol.flags = visible; 1460 1.1 christos break; 1461 1.1 christos 1462 1.1 christos case N_SETA: case N_SETA | N_EXT: 1463 1.1 christos case N_SETT: case N_SETT | N_EXT: 1464 1.1 christos case N_SETD: case N_SETD | N_EXT: 1465 1.1 christos case N_SETB: case N_SETB | N_EXT: 1466 1.1 christos { 1467 1.1.1.7 christos /* This code is no longer needed. It used to be used to make 1468 1.1.1.7 christos the linker handle set symbols, but they are now handled in 1469 1.1 christos the add_symbols routine instead. */ 1470 1.1 christos switch (cache_ptr->type & N_TYPE) 1471 1.1 christos { 1472 1.1 christos case N_SETA: 1473 1.1 christos cache_ptr->symbol.section = bfd_abs_section_ptr; 1474 1.1 christos break; 1475 1.1 christos case N_SETT: 1476 1.1 christos cache_ptr->symbol.section = obj_textsec (abfd); 1477 1.1 christos break; 1478 1.1 christos case N_SETD: 1479 1.1 christos cache_ptr->symbol.section = obj_datasec (abfd); 1480 1.1 christos break; 1481 1.1 christos case N_SETB: 1482 1.1 christos cache_ptr->symbol.section = obj_bsssec (abfd); 1483 1.1 christos break; 1484 1.1 christos } 1485 1.1 christos 1486 1.1 christos cache_ptr->symbol.flags |= BSF_CONSTRUCTOR; 1487 1.1 christos } 1488 1.1 christos break; 1489 1.1 christos 1490 1.1 christos case N_WARNING: 1491 1.1 christos /* This symbol is the text of a warning message. The next 1492 1.1 christos symbol is the symbol to associate the warning with. If a 1493 1.1 christos reference is made to that symbol, a warning is issued. */ 1494 1.1 christos cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING; 1495 1.1 christos cache_ptr->symbol.section = bfd_abs_section_ptr; 1496 1.1 christos break; 1497 1.1 christos 1498 1.1 christos case N_INDR: case N_INDR | N_EXT: 1499 1.1 christos /* An indirect symbol. This consists of two symbols in a row. 1500 1.1 christos The first symbol is the name of the indirection. The second 1501 1.1 christos symbol is the name of the target. A reference to the first 1502 1.1 christos symbol becomes a reference to the second. */ 1503 1.1 christos cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible; 1504 1.1 christos cache_ptr->symbol.section = bfd_ind_section_ptr; 1505 1.1 christos break; 1506 1.1 christos 1507 1.1 christos case N_WEAKU: 1508 1.1 christos cache_ptr->symbol.section = bfd_und_section_ptr; 1509 1.1 christos cache_ptr->symbol.flags = BSF_WEAK; 1510 1.1 christos break; 1511 1.1 christos 1512 1.1 christos case N_WEAKA: 1513 1.1 christos cache_ptr->symbol.section = bfd_abs_section_ptr; 1514 1.1 christos cache_ptr->symbol.flags = BSF_WEAK; 1515 1.1 christos break; 1516 1.1 christos 1517 1.1 christos case N_WEAKT: 1518 1.1 christos cache_ptr->symbol.section = obj_textsec (abfd); 1519 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1520 1.1 christos cache_ptr->symbol.flags = BSF_WEAK; 1521 1.1 christos break; 1522 1.1 christos 1523 1.1 christos case N_WEAKD: 1524 1.1 christos cache_ptr->symbol.section = obj_datasec (abfd); 1525 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1526 1.1 christos cache_ptr->symbol.flags = BSF_WEAK; 1527 1.1 christos break; 1528 1.1 christos 1529 1.1 christos case N_WEAKB: 1530 1.1 christos cache_ptr->symbol.section = obj_bsssec (abfd); 1531 1.1 christos cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; 1532 1.1 christos cache_ptr->symbol.flags = BSF_WEAK; 1533 1.1 christos break; 1534 1.1 christos } 1535 1.1.1.9 christos 1536 1.1 christos return true; 1537 1.1 christos } 1538 1.1 christos 1539 1.1 christos /* Set the fields of SYM_POINTER according to CACHE_PTR. */ 1540 1.1.1.9 christos 1541 1.1 christos static bool 1542 1.1 christos translate_to_native_sym_flags (bfd *abfd, 1543 1.1 christos asymbol *cache_ptr, 1544 1.1 christos struct external_nlist *sym_pointer) 1545 1.1 christos { 1546 1.1 christos bfd_vma value = cache_ptr->value; 1547 1.1 christos asection *sec; 1548 1.1 christos bfd_vma off; 1549 1.1 christos 1550 1.1 christos /* Mask out any existing type bits in case copying from one section 1551 1.1 christos to another. */ 1552 1.1 christos sym_pointer->e_type[0] &= ~N_TYPE; 1553 1.1.1.8 christos 1554 1.1 christos sec = bfd_asymbol_section (cache_ptr); 1555 1.1 christos off = 0; 1556 1.1 christos 1557 1.1 christos if (sec == NULL) 1558 1.1 christos { 1559 1.1 christos /* This case occurs, e.g., for the *DEBUG* section of a COFF 1560 1.1.1.6 christos file. */ 1561 1.1.1.6 christos _bfd_error_handler 1562 1.1.1.7 christos /* xgettext:c-format */ 1563 1.1.1.6 christos (_("%pB: can not represent section for symbol `%s' in a.out " 1564 1.1.1.6 christos "object file format"), 1565 1.1 christos abfd, 1566 1.1 christos cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*")); 1567 1.1.1.9 christos bfd_set_error (bfd_error_nonrepresentable_section); 1568 1.1 christos return false; 1569 1.1 christos } 1570 1.1 christos 1571 1.1 christos if (sec->output_section != NULL) 1572 1.1 christos { 1573 1.1 christos off = sec->output_offset; 1574 1.1 christos sec = sec->output_section; 1575 1.1 christos } 1576 1.1 christos 1577 1.1 christos if (bfd_is_abs_section (sec)) 1578 1.1 christos sym_pointer->e_type[0] |= N_ABS; 1579 1.1 christos else if (sec == obj_textsec (abfd)) 1580 1.1 christos sym_pointer->e_type[0] |= N_TEXT; 1581 1.1 christos else if (sec == obj_datasec (abfd)) 1582 1.1 christos sym_pointer->e_type[0] |= N_DATA; 1583 1.1 christos else if (sec == obj_bsssec (abfd)) 1584 1.1 christos sym_pointer->e_type[0] |= N_BSS; 1585 1.1 christos else if (bfd_is_und_section (sec)) 1586 1.1 christos sym_pointer->e_type[0] = N_UNDF | N_EXT; 1587 1.1 christos else if (bfd_is_ind_section (sec)) 1588 1.1 christos sym_pointer->e_type[0] = N_INDR; 1589 1.1 christos else if (bfd_is_com_section (sec)) 1590 1.1 christos sym_pointer->e_type[0] = N_UNDF | N_EXT; 1591 1.1 christos else 1592 1.1 christos { 1593 1.1 christos if (aout_section_merge_with_text_p (abfd, sec)) 1594 1.1 christos sym_pointer->e_type[0] |= N_TEXT; 1595 1.1 christos else 1596 1.1.1.6 christos { 1597 1.1.1.6 christos _bfd_error_handler 1598 1.1.1.7 christos /* xgettext:c-format */ 1599 1.1.1.6 christos (_("%pB: can not represent section `%pA' in a.out object file format"), 1600 1.1.1.7 christos abfd, sec); 1601 1.1.1.9 christos bfd_set_error (bfd_error_nonrepresentable_section); 1602 1.1 christos return false; 1603 1.1 christos } 1604 1.1 christos } 1605 1.1 christos 1606 1.1 christos /* Turn the symbol from section relative to absolute again. */ 1607 1.1 christos value += sec->vma + off; 1608 1.1 christos 1609 1.1 christos if ((cache_ptr->flags & BSF_WARNING) != 0) 1610 1.1 christos sym_pointer->e_type[0] = N_WARNING; 1611 1.1 christos 1612 1.1 christos if ((cache_ptr->flags & BSF_DEBUGGING) != 0) 1613 1.1 christos sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type; 1614 1.1 christos else if ((cache_ptr->flags & BSF_GLOBAL) != 0) 1615 1.1 christos sym_pointer->e_type[0] |= N_EXT; 1616 1.1 christos else if ((cache_ptr->flags & BSF_LOCAL) != 0) 1617 1.1 christos sym_pointer->e_type[0] &= ~N_EXT; 1618 1.1 christos 1619 1.1 christos if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0) 1620 1.1 christos { 1621 1.1 christos int type = ((aout_symbol_type *) cache_ptr)->type; 1622 1.1 christos 1623 1.1 christos switch (type) 1624 1.1 christos { 1625 1.1 christos case N_ABS: type = N_SETA; break; 1626 1.1 christos case N_TEXT: type = N_SETT; break; 1627 1.1 christos case N_DATA: type = N_SETD; break; 1628 1.1 christos case N_BSS: type = N_SETB; break; 1629 1.1 christos } 1630 1.1 christos sym_pointer->e_type[0] = type; 1631 1.1 christos } 1632 1.1 christos 1633 1.1 christos if ((cache_ptr->flags & BSF_WEAK) != 0) 1634 1.1 christos { 1635 1.1 christos int type; 1636 1.1 christos 1637 1.1 christos switch (sym_pointer->e_type[0] & N_TYPE) 1638 1.1 christos { 1639 1.1 christos default: 1640 1.1 christos case N_ABS: type = N_WEAKA; break; 1641 1.1 christos case N_TEXT: type = N_WEAKT; break; 1642 1.1 christos case N_DATA: type = N_WEAKD; break; 1643 1.1 christos case N_BSS: type = N_WEAKB; break; 1644 1.1 christos case N_UNDF: type = N_WEAKU; break; 1645 1.1 christos } 1646 1.1 christos sym_pointer->e_type[0] = type; 1647 1.1 christos } 1648 1.1 christos 1649 1.1 christos PUT_WORD (abfd, value, sym_pointer->e_value); 1650 1.1.1.9 christos 1651 1.1 christos return true; 1652 1.1 christos } 1653 1.1 christos 1654 1.1 christos /* Native-level interface to symbols. */ 1656 1.1 christos 1657 1.1 christos asymbol * 1658 1.1.1.8 christos NAME (aout, make_empty_symbol) (bfd *abfd) 1659 1.1 christos { 1660 1.1 christos size_t amt = sizeof (aout_symbol_type); 1661 1.1 christos 1662 1.1 christos aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt); 1663 1.1 christos if (!new_symbol) 1664 1.1 christos return NULL; 1665 1.1 christos new_symbol->symbol.the_bfd = abfd; 1666 1.1 christos 1667 1.1 christos return &new_symbol->symbol; 1668 1.1.1.8 christos } 1669 1.1 christos 1670 1.1.1.9 christos /* Translate a set of external symbols into internal symbols. */ 1671 1.1 christos 1672 1.1 christos bool 1673 1.1 christos NAME (aout, translate_symbol_table) (bfd *abfd, 1674 1.1 christos aout_symbol_type *in, 1675 1.1 christos struct external_nlist *ext, 1676 1.1 christos bfd_size_type count, 1677 1.1.1.9 christos char *str, 1678 1.1 christos bfd_size_type strsize, 1679 1.1 christos bool dynamic) 1680 1.1 christos { 1681 1.1 christos struct external_nlist *ext_end; 1682 1.1 christos 1683 1.1 christos ext_end = ext + count; 1684 1.1 christos for (; ext < ext_end; ext++, in++) 1685 1.1 christos { 1686 1.1 christos bfd_vma x; 1687 1.1 christos 1688 1.1 christos x = GET_WORD (abfd, ext->e_strx); 1689 1.1 christos in->symbol.the_bfd = abfd; 1690 1.1 christos 1691 1.1 christos /* For the normal symbols, the zero index points at the number 1692 1.1 christos of bytes in the string table but is to be interpreted as the 1693 1.1 christos null string. For the dynamic symbols, the number of bytes in 1694 1.1 christos the string table is stored in the __DYNAMIC structure and the 1695 1.1 christos zero index points at an actual string. */ 1696 1.1 christos if (x == 0 && ! dynamic) 1697 1.1 christos in->symbol.name = ""; 1698 1.1 christos else if (x < strsize) 1699 1.1.1.7 christos in->symbol.name = str + x; 1700 1.1.1.7 christos else 1701 1.1.1.7 christos { 1702 1.1.1.7 christos _bfd_error_handler 1703 1.1.1.7 christos (_("%pB: invalid string offset %" PRIu64 " >= %" PRIu64), 1704 1.1.1.9 christos abfd, (uint64_t) x, (uint64_t) strsize); 1705 1.1.1.7 christos bfd_set_error (bfd_error_bad_value); 1706 1.1 christos return false; 1707 1.1 christos } 1708 1.1 christos 1709 1.1 christos in->symbol.value = GET_SWORD (abfd, ext->e_value); 1710 1.1 christos in->desc = H_GET_16 (abfd, ext->e_desc); 1711 1.1 christos in->other = H_GET_8 (abfd, ext->e_other); 1712 1.1 christos in->type = H_GET_8 (abfd, ext->e_type); 1713 1.1 christos in->symbol.udata.p = NULL; 1714 1.1.1.9 christos 1715 1.1 christos if (! translate_from_native_sym_flags (abfd, in)) 1716 1.1 christos return false; 1717 1.1 christos 1718 1.1 christos if (dynamic) 1719 1.1 christos in->symbol.flags |= BSF_DYNAMIC; 1720 1.1.1.9 christos } 1721 1.1 christos 1722 1.1 christos return true; 1723 1.1 christos } 1724 1.1 christos 1725 1.1 christos /* We read the symbols into a buffer, which is discarded when this 1726 1.1 christos function exits. We read the strings into a buffer large enough to 1727 1.1.1.9 christos hold them all plus all the cached symbol entries. */ 1728 1.1 christos 1729 1.1 christos bool 1730 1.1 christos NAME (aout, slurp_symbol_table) (bfd *abfd) 1731 1.1 christos { 1732 1.1 christos struct external_nlist *old_external_syms; 1733 1.1 christos aout_symbol_type *cached; 1734 1.1 christos bfd_size_type cached_size; 1735 1.1 christos 1736 1.1.1.9 christos /* If there's no work to be done, don't do any. */ 1737 1.1 christos if (obj_aout_symbols (abfd) != NULL) 1738 1.1 christos return true; 1739 1.1 christos 1740 1.1 christos old_external_syms = obj_aout_external_syms (abfd); 1741 1.1.1.9 christos 1742 1.1 christos if (! aout_get_external_symbols (abfd)) 1743 1.1 christos return false; 1744 1.1 christos 1745 1.1.1.9 christos cached_size = obj_aout_external_sym_count (abfd); 1746 1.1 christos if (cached_size == 0) 1747 1.1 christos return true; /* Nothing to do. */ 1748 1.1 christos 1749 1.1 christos cached_size *= sizeof (aout_symbol_type); 1750 1.1.1.9 christos cached = (aout_symbol_type *) bfd_zmalloc (cached_size); 1751 1.1 christos if (cached == NULL) 1752 1.1 christos return false; 1753 1.1 christos 1754 1.1 christos /* Convert from external symbol information to internal. */ 1755 1.1 christos if (! (NAME (aout, translate_symbol_table) 1756 1.1 christos (abfd, cached, 1757 1.1 christos obj_aout_external_syms (abfd), 1758 1.1 christos obj_aout_external_sym_count (abfd), 1759 1.1.1.9 christos obj_aout_external_strings (abfd), 1760 1.1 christos obj_aout_external_string_size (abfd), 1761 1.1 christos false))) 1762 1.1.1.9 christos { 1763 1.1 christos free (cached); 1764 1.1 christos return false; 1765 1.1.1.8 christos } 1766 1.1 christos 1767 1.1 christos abfd->symcount = obj_aout_external_sym_count (abfd); 1768 1.1 christos 1769 1.1 christos obj_aout_symbols (abfd) = cached; 1770 1.1 christos 1771 1.1 christos /* It is very likely that anybody who calls this function will not 1772 1.1 christos want the external symbol information, so if it was allocated 1773 1.1 christos because of our call to aout_get_external_symbols, we free it up 1774 1.1 christos right away to save space. */ 1775 1.1 christos if (old_external_syms == NULL 1776 1.1 christos && obj_aout_external_syms (abfd) != NULL) 1777 1.1 christos { 1778 1.1 christos free (obj_aout_external_syms (abfd)); 1779 1.1 christos obj_aout_external_syms (abfd) = NULL; 1780 1.1.1.9 christos } 1781 1.1 christos 1782 1.1 christos return true; 1783 1.1 christos } 1784 1.1 christos 1785 1.1 christos /* We use a hash table when writing out symbols so that we only write 1787 1.1 christos out a particular string once. This helps particularly when the 1788 1.1 christos linker writes out stabs debugging entries, because each different 1789 1.1 christos contributing object file tends to have many duplicate stabs 1790 1.1 christos strings. 1791 1.1 christos 1792 1.1 christos This hash table code breaks dbx on SunOS 4.1.3, so we don't do it 1793 1.1 christos if BFD_TRADITIONAL_FORMAT is set. */ 1794 1.1 christos 1795 1.1 christos /* Get the index of a string in a strtab, adding it if it is not 1796 1.1 christos already present. */ 1797 1.1 christos 1798 1.1 christos static inline bfd_size_type 1799 1.1.1.9 christos add_to_stringtab (bfd *abfd, 1800 1.1 christos struct bfd_strtab_hash *tab, 1801 1.1.1.9 christos const char *str, 1802 1.1 christos bool copy) 1803 1.1 christos { 1804 1.1 christos bool hash; 1805 1.1 christos bfd_size_type str_index; 1806 1.1 christos 1807 1.1 christos /* An index of 0 always means the empty string. */ 1808 1.1 christos if (str == 0 || *str == '\0') 1809 1.1 christos return 0; 1810 1.1.1.9 christos 1811 1.1 christos /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx 1812 1.1.1.9 christos doesn't understand a hashed string table. */ 1813 1.1 christos hash = true; 1814 1.1 christos if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0) 1815 1.1 christos hash = false; 1816 1.1 christos 1817 1.1 christos str_index = _bfd_stringtab_add (tab, str, hash, copy); 1818 1.1 christos 1819 1.1 christos if (str_index != (bfd_size_type) -1) 1820 1.1 christos /* Add BYTES_IN_WORD to the return value to account for the 1821 1.1 christos space taken up by the string table size. */ 1822 1.1 christos str_index += BYTES_IN_WORD; 1823 1.1 christos 1824 1.1 christos return str_index; 1825 1.1 christos } 1826 1.1 christos 1827 1.1.1.9 christos /* Write out a strtab. ABFD is already at the right location in the 1828 1.1 christos file. */ 1829 1.1 christos 1830 1.1 christos static bool 1831 1.1.1.8 christos emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab) 1832 1.1 christos { 1833 1.1 christos bfd_byte buffer[BYTES_IN_WORD]; 1834 1.1 christos size_t amt = BYTES_IN_WORD; 1835 1.1.1.10 christos 1836 1.1.1.9 christos /* The string table starts with the size. */ 1837 1.1 christos PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer); 1838 1.1 christos if (bfd_write (buffer, amt, abfd) != amt) 1839 1.1 christos return false; 1840 1.1 christos 1841 1.1.1.9 christos return _bfd_stringtab_emit (abfd, tab); 1842 1.1 christos } 1843 1.1 christos 1844 1.1 christos bool 1846 1.1 christos NAME (aout, write_syms) (bfd *abfd) 1847 1.1 christos { 1848 1.1 christos unsigned int count ; 1849 1.1 christos asymbol **generic = bfd_get_outsymbols (abfd); 1850 1.1.1.9 christos struct bfd_strtab_hash *strtab; 1851 1.1 christos 1852 1.1 christos strtab = _bfd_stringtab_init (); 1853 1.1 christos if (strtab == NULL) 1854 1.1 christos return false; 1855 1.1 christos 1856 1.1 christos for (count = 0; count < bfd_get_symcount (abfd); count++) 1857 1.1.1.8 christos { 1858 1.1 christos asymbol *g = generic[count]; 1859 1.1.1.9 christos bfd_size_type indx; 1860 1.1 christos struct external_nlist nsp; 1861 1.1 christos size_t amt; 1862 1.1 christos 1863 1.1 christos indx = add_to_stringtab (abfd, strtab, g->name, false); 1864 1.1 christos if (indx == (bfd_size_type) -1) 1865 1.1 christos goto error_return; 1866 1.1 christos PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx); 1867 1.1 christos 1868 1.1 christos if (bfd_asymbol_flavour (g) == abfd->xvec->flavour) 1869 1.1 christos { 1870 1.1 christos H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc); 1871 1.1 christos H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other); 1872 1.1 christos H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type); 1873 1.1 christos } 1874 1.1 christos else 1875 1.1 christos { 1876 1.1 christos H_PUT_16 (abfd, 0, nsp.e_desc); 1877 1.1 christos H_PUT_8 (abfd, 0, nsp.e_other); 1878 1.1 christos H_PUT_8 (abfd, 0, nsp.e_type); 1879 1.1 christos } 1880 1.1 christos 1881 1.1.1.10 christos if (! translate_to_native_sym_flags (abfd, g, &nsp)) 1882 1.1 christos goto error_return; 1883 1.1 christos 1884 1.1 christos amt = EXTERNAL_NLIST_SIZE; 1885 1.1 christos if (bfd_write (&nsp, amt, abfd) != amt) 1886 1.1 christos goto error_return; 1887 1.1 christos 1888 1.1 christos /* NB: `KEEPIT' currently overlays `udata.p', so set this only 1889 1.1 christos here, at the end. */ 1890 1.1 christos g->KEEPIT = count; 1891 1.1 christos } 1892 1.1 christos 1893 1.1 christos if (! emit_stringtab (abfd, strtab)) 1894 1.1.1.9 christos goto error_return; 1895 1.1 christos 1896 1.1.1.8 christos _bfd_stringtab_free (strtab); 1897 1.1 christos 1898 1.1.1.9 christos return true; 1899 1.1 christos 1900 1.1 christos error_return: 1901 1.1 christos _bfd_stringtab_free (strtab); 1902 1.1 christos return false; 1903 1.1 christos } 1904 1.1 christos 1905 1.1 christos long 1907 1.1 christos NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location) 1908 1.1 christos { 1909 1.1 christos unsigned int counter = 0; 1910 1.1 christos aout_symbol_type *symbase; 1911 1.1 christos 1912 1.1 christos if (!NAME (aout, slurp_symbol_table) (abfd)) 1913 1.1 christos return -1; 1914 1.1 christos 1915 1.1 christos for (symbase = obj_aout_symbols (abfd); 1916 1.1 christos counter++ < bfd_get_symcount (abfd); 1917 1.1 christos ) 1918 1.1 christos *(location++) = (asymbol *) (symbase++); 1919 1.1 christos *location++ =0; 1920 1.1 christos return bfd_get_symcount (abfd); 1921 1.1 christos } 1922 1.1 christos 1923 1.1 christos /* Standard reloc stuff. */ 1925 1.1 christos /* Output standard relocation information to a file in target byte order. */ 1926 1.1 christos 1927 1.1 christos extern void NAME (aout, swap_std_reloc_out) 1928 1.1 christos (bfd *, arelent *, struct reloc_std_external *); 1929 1.1 christos 1930 1.1 christos void 1931 1.1 christos NAME (aout, swap_std_reloc_out) (bfd *abfd, 1932 1.1.1.9 christos arelent *g, 1933 1.1 christos struct reloc_std_external *natptr) 1934 1.1 christos { 1935 1.1 christos int r_index; 1936 1.1 christos asymbol *sym = *(g->sym_ptr_ptr); 1937 1.1 christos int r_extern; 1938 1.1 christos unsigned int r_length, r_size; 1939 1.1.1.6 christos int r_pcrel; 1940 1.1.1.8 christos int r_baserel, r_jmptable, r_relative; 1941 1.1.1.9 christos asection *output_section = sym->section->output_section; 1942 1.1.1.9 christos 1943 1.1.1.9 christos PUT_WORD (abfd, g->address, natptr->r_address); 1944 1.1.1.8 christos 1945 1.1.1.8 christos BFD_ASSERT (g->howto != NULL); 1946 1.1.1.9 christos 1947 1.1.1.8 christos r_size = bfd_get_reloc_size (g->howto); 1948 1.1.1.8 christos r_length = bfd_log2 (r_size); 1949 1.1.1.8 christos if (1u << r_length != r_size) 1950 1.1.1.8 christos { 1951 1.1 christos _bfd_error_handler (_("%pB: unsupported AOUT relocation size: %d"), 1952 1.1 christos abfd, r_size); 1953 1.1 christos bfd_set_error (bfd_error_bad_value); 1954 1.1 christos return; 1955 1.1 christos } 1956 1.1 christos 1957 1.1 christos r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ 1958 1.1 christos /* XXX This relies on relocs coming from a.out files. */ 1959 1.1 christos r_baserel = (g->howto->type & 8) != 0; 1960 1.1 christos r_jmptable = (g->howto->type & 16) != 0; 1961 1.1 christos r_relative = (g->howto->type & 32) != 0; 1962 1.1 christos 1963 1.1 christos /* Name was clobbered by aout_write_syms to be symbol index. */ 1964 1.1 christos 1965 1.1 christos /* If this relocation is relative to a symbol then set the 1966 1.1 christos r_index to the symbols index, and the r_extern bit. 1967 1.1 christos 1968 1.1 christos Absolute symbols can come in in two ways, either as an offset 1969 1.1 christos from the abs section, or as a symbol which has an abs value. 1970 1.1 christos check for that here. */ 1971 1.1 christos 1972 1.1 christos if (bfd_is_com_section (output_section) 1973 1.1 christos || bfd_is_abs_section (output_section) 1974 1.1 christos || bfd_is_und_section (output_section) 1975 1.1 christos /* PR gas/3041 a.out relocs against weak symbols 1976 1.1 christos must be treated as if they were against externs. */ 1977 1.1 christos || (sym->flags & BSF_WEAK)) 1978 1.1 christos { 1979 1.1 christos if (bfd_abs_section_ptr->symbol == sym) 1980 1.1 christos { 1981 1.1 christos /* Whoops, looked like an abs symbol, but is 1982 1.1 christos really an offset from the abs section. */ 1983 1.1 christos r_index = N_ABS; 1984 1.1 christos r_extern = 0; 1985 1.1 christos } 1986 1.1 christos else 1987 1.1 christos { 1988 1.1 christos /* Fill in symbol. */ 1989 1.1 christos r_extern = 1; 1990 1.1 christos r_index = (*(g->sym_ptr_ptr))->KEEPIT; 1991 1.1 christos } 1992 1.1 christos } 1993 1.1 christos else 1994 1.1 christos { 1995 1.1 christos /* Just an ordinary section. */ 1996 1.1 christos r_extern = 0; 1997 1.1 christos r_index = output_section->target_index; 1998 1.1 christos } 1999 1.1 christos 2000 1.1 christos /* Now the fun stuff. */ 2001 1.1 christos if (bfd_header_big_endian (abfd)) 2002 1.1 christos { 2003 1.1 christos natptr->r_index[0] = r_index >> 16; 2004 1.1 christos natptr->r_index[1] = r_index >> 8; 2005 1.1 christos natptr->r_index[2] = r_index; 2006 1.1 christos natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 2007 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 2008 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) 2009 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) 2010 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) 2011 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 2012 1.1 christos } 2013 1.1 christos else 2014 1.1 christos { 2015 1.1 christos natptr->r_index[2] = r_index >> 16; 2016 1.1 christos natptr->r_index[1] = r_index >> 8; 2017 1.1 christos natptr->r_index[0] = r_index; 2018 1.1 christos natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 2019 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 2020 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) 2021 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) 2022 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) 2023 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 2024 1.1 christos } 2025 1.1 christos } 2026 1.1 christos 2027 1.1 christos /* Extended stuff. */ 2028 1.1 christos /* Output extended relocation information to a file in target byte order. */ 2029 1.1 christos 2030 1.1 christos extern void NAME (aout, swap_ext_reloc_out) 2031 1.1 christos (bfd *, arelent *, struct reloc_ext_external *); 2032 1.1 christos 2033 1.1 christos void 2034 1.1 christos NAME (aout, swap_ext_reloc_out) (bfd *abfd, 2035 1.1 christos arelent *g, 2036 1.1 christos struct reloc_ext_external *natptr) 2037 1.1 christos { 2038 1.1 christos int r_index; 2039 1.1 christos int r_extern; 2040 1.1 christos unsigned int r_type; 2041 1.1 christos bfd_vma r_addend; 2042 1.1 christos asymbol *sym = *(g->sym_ptr_ptr); 2043 1.1 christos asection *output_section = sym->section->output_section; 2044 1.1 christos 2045 1.1 christos PUT_WORD (abfd, g->address, natptr->r_address); 2046 1.1 christos 2047 1.1 christos r_type = (unsigned int) g->howto->type; 2048 1.1 christos 2049 1.1 christos r_addend = g->addend; 2050 1.1 christos if ((sym->flags & BSF_SECTION_SYM) != 0) 2051 1.1 christos r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma; 2052 1.1 christos 2053 1.1.1.8 christos /* If this relocation is relative to a symbol then set the 2054 1.1 christos r_index to the symbols index, and the r_extern bit. 2055 1.1 christos 2056 1.1 christos Absolute symbols can come in in two ways, either as an offset 2057 1.1 christos from the abs section, or as a symbol which has an abs value. 2058 1.1 christos check for that here. */ 2059 1.1 christos if (bfd_is_abs_section (bfd_asymbol_section (sym))) 2060 1.1.1.8 christos { 2061 1.1 christos r_extern = 0; 2062 1.1 christos r_index = N_ABS; 2063 1.1 christos } 2064 1.1 christos else if ((sym->flags & BSF_SECTION_SYM) == 0) 2065 1.1 christos { 2066 1.1 christos if (bfd_is_und_section (bfd_asymbol_section (sym)) 2067 1.1 christos || (sym->flags & BSF_GLOBAL) != 0) 2068 1.1 christos r_extern = 1; 2069 1.1 christos else 2070 1.1 christos r_extern = 0; 2071 1.1 christos r_index = (*(g->sym_ptr_ptr))->KEEPIT; 2072 1.1 christos } 2073 1.1 christos else 2074 1.1 christos { 2075 1.1 christos /* Just an ordinary section. */ 2076 1.1 christos r_extern = 0; 2077 1.1 christos r_index = output_section->target_index; 2078 1.1 christos } 2079 1.1 christos 2080 1.1 christos /* Now the fun stuff. */ 2081 1.1 christos if (bfd_header_big_endian (abfd)) 2082 1.1 christos { 2083 1.1 christos natptr->r_index[0] = r_index >> 16; 2084 1.1 christos natptr->r_index[1] = r_index >> 8; 2085 1.1 christos natptr->r_index[2] = r_index; 2086 1.1 christos natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) 2087 1.1 christos | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG)); 2088 1.1 christos } 2089 1.1 christos else 2090 1.1 christos { 2091 1.1 christos natptr->r_index[2] = r_index >> 16; 2092 1.1 christos natptr->r_index[1] = r_index >> 8; 2093 1.1 christos natptr->r_index[0] = r_index; 2094 1.1 christos natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) 2095 1.1 christos | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE)); 2096 1.1 christos } 2097 1.1 christos 2098 1.1 christos PUT_WORD (abfd, r_addend, natptr->r_addend); 2099 1.1 christos } 2100 1.1 christos 2101 1.1 christos /* BFD deals internally with all things based from the section they're 2102 1.1 christos in. so, something in 10 bytes into a text section with a base of 2103 1.1 christos 50 would have a symbol (.text+10) and know .text vma was 50. 2104 1.1 christos 2105 1.1 christos Aout keeps all it's symbols based from zero, so the symbol would 2106 1.1 christos contain 60. This macro subs the base of each section from the value 2107 1.1.1.9 christos to give the true offset from the section. */ 2108 1.1.1.9 christos 2109 1.1.1.9 christos #define MOVE_ADDRESS(ad) \ 2110 1.1.1.11 christos if (r_extern) \ 2111 1.1 christos { \ 2112 1.1 christos /* Undefined symbol. */ \ 2113 1.1 christos if (symbols != NULL && r_index < bfd_get_symcount (abfd)) \ 2114 1.1 christos cache_ptr->sym_ptr_ptr = symbols + r_index; \ 2115 1.1 christos else \ 2116 1.1 christos cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; \ 2117 1.1 christos cache_ptr->addend = ad; \ 2118 1.1 christos } \ 2119 1.1 christos else \ 2120 1.1 christos { \ 2121 1.1.1.11 christos /* Defined, section relative. Replace symbol with pointer to \ 2122 1.1 christos symbol which points to section. */ \ 2123 1.1 christos switch (r_index) \ 2124 1.1 christos { \ 2125 1.1 christos case N_TEXT: \ 2126 1.1.1.11 christos case N_TEXT | N_EXT: \ 2127 1.1 christos cache_ptr->sym_ptr_ptr = &obj_textsec (abfd)->symbol; \ 2128 1.1 christos cache_ptr->addend = ad - su->textsec->vma; \ 2129 1.1 christos break; \ 2130 1.1 christos case N_DATA: \ 2131 1.1.1.11 christos case N_DATA | N_EXT: \ 2132 1.1 christos cache_ptr->sym_ptr_ptr = &obj_datasec (abfd)->symbol; \ 2133 1.1 christos cache_ptr->addend = ad - su->datasec->vma; \ 2134 1.1 christos break; \ 2135 1.1 christos case N_BSS: \ 2136 1.1 christos case N_BSS | N_EXT: \ 2137 1.1.1.11 christos cache_ptr->sym_ptr_ptr = &obj_bsssec (abfd)->symbol; \ 2138 1.1 christos cache_ptr->addend = ad - su->bsssec->vma; \ 2139 1.1 christos break; \ 2140 1.1 christos default: \ 2141 1.1 christos case N_ABS: \ 2142 1.1 christos case N_ABS | N_EXT: \ 2143 1.1 christos cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; \ 2144 1.1 christos cache_ptr->addend = ad; \ 2145 1.1 christos break; \ 2146 1.1 christos } \ 2147 1.1 christos } 2148 1.1 christos 2149 1.1 christos void 2150 1.1 christos NAME (aout, swap_ext_reloc_in) (bfd *abfd, 2151 1.1 christos struct reloc_ext_external *bytes, 2152 1.1 christos arelent *cache_ptr, 2153 1.1 christos asymbol **symbols, 2154 1.1 christos bfd_size_type symcount) 2155 1.1 christos { 2156 1.1 christos unsigned int r_index; 2157 1.1 christos int r_extern; 2158 1.1 christos unsigned int r_type; 2159 1.1 christos struct aoutdata *su = &(abfd->tdata.aout_data->a); 2160 1.1 christos 2161 1.1 christos cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); 2162 1.1 christos 2163 1.1 christos /* Now the fun stuff. */ 2164 1.1 christos if (bfd_header_big_endian (abfd)) 2165 1.1 christos { 2166 1.1 christos r_index = (((unsigned int) bytes->r_index[0] << 16) 2167 1.1 christos | ((unsigned int) bytes->r_index[1] << 8) 2168 1.1 christos | bytes->r_index[2]); 2169 1.1 christos r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); 2170 1.1 christos r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) 2171 1.1 christos >> RELOC_EXT_BITS_TYPE_SH_BIG); 2172 1.1 christos } 2173 1.1 christos else 2174 1.1 christos { 2175 1.1 christos r_index = (((unsigned int) bytes->r_index[2] << 16) 2176 1.1 christos | ((unsigned int) bytes->r_index[1] << 8) 2177 1.1 christos | bytes->r_index[0]); 2178 1.1 christos r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); 2179 1.1 christos r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) 2180 1.1 christos >> RELOC_EXT_BITS_TYPE_SH_LITTLE); 2181 1.1 christos } 2182 1.1 christos 2183 1.1 christos if (r_type < TABLE_SIZE (howto_table_ext)) 2184 1.1 christos cache_ptr->howto = howto_table_ext + r_type; 2185 1.1 christos else 2186 1.1 christos cache_ptr->howto = NULL; 2187 1.1 christos 2188 1.1 christos /* Base relative relocs are always against the symbol table, 2189 1.1 christos regardless of the setting of r_extern. r_extern just reflects 2190 1.1 christos whether the symbol the reloc is against is local or global. */ 2191 1.1 christos if (r_type == (unsigned int) RELOC_BASE10 2192 1.1 christos || r_type == (unsigned int) RELOC_BASE13 2193 1.1.1.7 christos || r_type == (unsigned int) RELOC_BASE22) 2194 1.1 christos r_extern = 1; 2195 1.1 christos 2196 1.1 christos if (r_extern && r_index > symcount) 2197 1.1 christos { 2198 1.1 christos /* We could arrange to return an error, but it might be useful 2199 1.1 christos to see the file even if it is bad. */ 2200 1.1 christos r_extern = 0; 2201 1.1 christos r_index = N_ABS; 2202 1.1 christos } 2203 1.1 christos 2204 1.1 christos MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend)); 2205 1.1 christos } 2206 1.1 christos 2207 1.1 christos void 2208 1.1 christos NAME (aout, swap_std_reloc_in) (bfd *abfd, 2209 1.1 christos struct reloc_std_external *bytes, 2210 1.1 christos arelent *cache_ptr, 2211 1.1 christos asymbol **symbols, 2212 1.1 christos bfd_size_type symcount) 2213 1.1 christos { 2214 1.1 christos unsigned int r_index; 2215 1.1 christos int r_extern; 2216 1.1 christos unsigned int r_length; 2217 1.1 christos int r_pcrel; 2218 1.1 christos int r_baserel, r_jmptable, r_relative; 2219 1.1 christos struct aoutdata *su = &(abfd->tdata.aout_data->a); 2220 1.1 christos unsigned int howto_idx; 2221 1.1 christos 2222 1.1 christos cache_ptr->address = H_GET_32 (abfd, bytes->r_address); 2223 1.1 christos 2224 1.1 christos /* Now the fun stuff. */ 2225 1.1 christos if (bfd_header_big_endian (abfd)) 2226 1.1 christos { 2227 1.1 christos r_index = (((unsigned int) bytes->r_index[0] << 16) 2228 1.1 christos | ((unsigned int) bytes->r_index[1] << 8) 2229 1.1 christos | bytes->r_index[2]); 2230 1.1 christos r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); 2231 1.1 christos r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); 2232 1.1 christos r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); 2233 1.1 christos r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); 2234 1.1 christos r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); 2235 1.1 christos r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 2236 1.1 christos >> RELOC_STD_BITS_LENGTH_SH_BIG); 2237 1.1 christos } 2238 1.1 christos else 2239 1.1 christos { 2240 1.1 christos r_index = (((unsigned int) bytes->r_index[2] << 16) 2241 1.1 christos | ((unsigned int) bytes->r_index[1] << 8) 2242 1.1 christos | bytes->r_index[0]); 2243 1.1 christos r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); 2244 1.1 christos r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); 2245 1.1 christos r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); 2246 1.1 christos r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); 2247 1.1 christos r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE)); 2248 1.1 christos r_length = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 2249 1.1 christos >> RELOC_STD_BITS_LENGTH_SH_LITTLE); 2250 1.1 christos } 2251 1.1 christos 2252 1.1 christos howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel 2253 1.1 christos + 16 * r_jmptable + 32 * r_relative); 2254 1.1 christos if (howto_idx < TABLE_SIZE (howto_table_std)) 2255 1.1 christos { 2256 1.1 christos cache_ptr->howto = howto_table_std + howto_idx; 2257 1.1 christos if (cache_ptr->howto->type == (unsigned int) -1) 2258 1.1 christos cache_ptr->howto = NULL; 2259 1.1 christos } 2260 1.1 christos else 2261 1.1 christos cache_ptr->howto = NULL; 2262 1.1 christos 2263 1.1.1.7 christos /* Base relative relocs are always against the symbol table, 2264 1.1 christos regardless of the setting of r_extern. r_extern just reflects 2265 1.1 christos whether the symbol the reloc is against is local or global. */ 2266 1.1.1.7 christos if (r_baserel) 2267 1.1.1.7 christos r_extern = 1; 2268 1.1.1.7 christos 2269 1.1 christos if (r_extern && r_index >= symcount) 2270 1.1 christos { 2271 1.1 christos /* We could arrange to return an error, but it might be useful 2272 1.1 christos to see the file even if it is bad. FIXME: Of course this 2273 1.1 christos means that objdump -r *doesn't* see the actual reloc, and 2274 1.1 christos objcopy silently writes a different reloc. */ 2275 1.1 christos r_extern = 0; 2276 1.1 christos r_index = N_ABS; 2277 1.1 christos } 2278 1.1.1.9 christos 2279 1.1 christos MOVE_ADDRESS (0); 2280 1.1 christos } 2281 1.1 christos 2282 1.1 christos /* Read and swap the relocs for a section. */ 2283 1.1 christos 2284 1.1 christos bool 2285 1.1 christos NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols) 2286 1.1 christos { 2287 1.1 christos bfd_size_type count; 2288 1.1 christos bfd_size_type reloc_size; 2289 1.1 christos void * relocs; 2290 1.1 christos arelent *reloc_cache; 2291 1.1.1.9 christos size_t each_size; 2292 1.1 christos unsigned int counter = 0; 2293 1.1 christos arelent *cache_ptr; 2294 1.1.1.9 christos bfd_size_type amt; 2295 1.1 christos 2296 1.1 christos if (asect->relocation) 2297 1.1 christos return true; 2298 1.1 christos 2299 1.1 christos if (asect->flags & SEC_CONSTRUCTOR) 2300 1.1 christos return true; 2301 1.1 christos 2302 1.1 christos if (asect == obj_datasec (abfd)) 2303 1.1 christos reloc_size = exec_hdr (abfd)->a_drsize; 2304 1.1 christos else if (asect == obj_textsec (abfd)) 2305 1.1.1.9 christos reloc_size = exec_hdr (abfd)->a_trsize; 2306 1.1 christos else if (asect == obj_bsssec (abfd)) 2307 1.1 christos reloc_size = 0; 2308 1.1 christos else 2309 1.1 christos { 2310 1.1 christos bfd_set_error (bfd_error_invalid_operation); 2311 1.1.1.9 christos return false; 2312 1.1 christos } 2313 1.1.1.8 christos 2314 1.1.1.9 christos each_size = obj_reloc_entry_size (abfd); 2315 1.1.1.8 christos count = reloc_size / each_size; 2316 1.1 christos if (count == 0) 2317 1.1.1.9 christos return true; /* Nothing to be done. */ 2318 1.1 christos 2319 1.1.1.8 christos if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) 2320 1.1.1.8 christos return false; 2321 1.1.1.8 christos relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size); 2322 1.1 christos if (relocs == NULL) 2323 1.1 christos return false; 2324 1.1.1.9 christos 2325 1.1 christos amt = count * sizeof (arelent); 2326 1.1 christos reloc_cache = (arelent *) bfd_zmalloc (amt); 2327 1.1 christos if (reloc_cache == NULL) 2328 1.1 christos { 2329 1.1 christos free (relocs); 2330 1.1 christos return false; 2331 1.1 christos } 2332 1.1 christos 2333 1.1 christos cache_ptr = reloc_cache; 2334 1.1 christos if (each_size == RELOC_EXT_SIZE) 2335 1.1 christos { 2336 1.1 christos struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; 2337 1.1 christos 2338 1.1 christos for (; counter < count; counter++, rptr++, cache_ptr++) 2339 1.1 christos MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols, 2340 1.1 christos (bfd_size_type) bfd_get_symcount (abfd)); 2341 1.1 christos } 2342 1.1 christos else 2343 1.1 christos { 2344 1.1 christos struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; 2345 1.1 christos 2346 1.1 christos for (; counter < count; counter++, rptr++, cache_ptr++) 2347 1.1 christos MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols, 2348 1.1 christos (bfd_size_type) bfd_get_symcount (abfd)); 2349 1.1 christos } 2350 1.1.1.9 christos 2351 1.1 christos free (relocs); 2352 1.1 christos 2353 1.1 christos asect->relocation = reloc_cache; 2354 1.1 christos asect->reloc_count = cache_ptr - reloc_cache; 2355 1.1.1.9 christos 2356 1.1 christos return true; 2357 1.1 christos } 2358 1.1 christos 2359 1.1 christos /* Write out a relocation section into an object file. */ 2360 1.1 christos 2361 1.1 christos bool 2362 1.1 christos NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section) 2363 1.1 christos { 2364 1.1 christos arelent **generic; 2365 1.1 christos unsigned char *native, *natptr; 2366 1.1.1.9 christos size_t each_size; 2367 1.1 christos 2368 1.1 christos unsigned int count = section->reloc_count; 2369 1.1 christos bfd_size_type natsize; 2370 1.1 christos 2371 1.1 christos if (count == 0 || section->orelocation == NULL) 2372 1.1.1.9 christos return true; 2373 1.1 christos 2374 1.1 christos each_size = obj_reloc_entry_size (abfd); 2375 1.1 christos natsize = (bfd_size_type) each_size * count; 2376 1.1 christos native = (unsigned char *) bfd_zalloc (abfd, natsize); 2377 1.1 christos if (!native) 2378 1.1 christos return false; 2379 1.1 christos 2380 1.1 christos generic = section->orelocation; 2381 1.1.1.6 christos 2382 1.1.1.6 christos if (each_size == RELOC_EXT_SIZE) 2383 1.1.1.6 christos { 2384 1.1.1.6 christos for (natptr = native; 2385 1.1.1.6 christos count != 0; 2386 1.1.1.6 christos --count, natptr += each_size, ++generic) 2387 1.1.1.6 christos { 2388 1.1.1.6 christos /* PR 20921: If the howto field has not been initialised then skip 2389 1.1.1.8 christos this reloc. 2390 1.1.1.8 christos PR 20929: Similarly for the symbol field. */ 2391 1.1.1.9 christos if ((*generic)->howto == NULL 2392 1.1.1.6 christos || (*generic)->sym_ptr_ptr == NULL) 2393 1.1.1.6 christos { 2394 1.1.1.6 christos bfd_set_error (bfd_error_invalid_operation); 2395 1.1.1.6 christos _bfd_error_handler (_("%pB: attempt to write out " 2396 1.1 christos "unknown reloc type"), abfd); 2397 1.1 christos return false; 2398 1.1 christos } 2399 1.1 christos MY_swap_ext_reloc_out (abfd, *generic, 2400 1.1 christos (struct reloc_ext_external *) natptr); 2401 1.1 christos } 2402 1.1.1.6 christos } 2403 1.1.1.6 christos else 2404 1.1.1.6 christos { 2405 1.1.1.6 christos for (natptr = native; 2406 1.1.1.6 christos count != 0; 2407 1.1.1.8 christos --count, natptr += each_size, ++generic) 2408 1.1.1.8 christos { 2409 1.1.1.9 christos if ((*generic)->howto == NULL 2410 1.1.1.6 christos || (*generic)->sym_ptr_ptr == NULL) 2411 1.1.1.6 christos { 2412 1.1.1.6 christos bfd_set_error (bfd_error_invalid_operation); 2413 1.1.1.6 christos _bfd_error_handler (_("%pB: attempt to write out " 2414 1.1 christos "unknown reloc type"), abfd); 2415 1.1 christos return false; 2416 1.1.1.10 christos } 2417 1.1 christos MY_swap_std_reloc_out (abfd, *generic, 2418 1.1 christos (struct reloc_std_external *) natptr); 2419 1.1.1.9 christos } 2420 1.1 christos } 2421 1.1 christos 2422 1.1 christos if (bfd_write (native, natsize, abfd) != natsize) 2423 1.1.1.9 christos { 2424 1.1 christos bfd_release (abfd, native); 2425 1.1 christos return false; 2426 1.1 christos } 2427 1.1 christos bfd_release (abfd, native); 2428 1.1 christos 2429 1.1 christos return true; 2430 1.1 christos } 2431 1.1 christos 2432 1.1 christos /* This is stupid. This function should be a boolean predicate. */ 2433 1.1 christos 2434 1.1 christos long 2435 1.1 christos NAME (aout, canonicalize_reloc) (bfd *abfd, 2436 1.1 christos sec_ptr section, 2437 1.1 christos arelent **relptr, 2438 1.1 christos asymbol **symbols) 2439 1.1 christos { 2440 1.1 christos arelent *tblptr = section->relocation; 2441 1.1 christos unsigned int count; 2442 1.1 christos 2443 1.1 christos if (section == obj_bsssec (abfd)) 2444 1.1 christos { 2445 1.1 christos *relptr = NULL; 2446 1.1 christos return 0; 2447 1.1 christos } 2448 1.1 christos 2449 1.1 christos if (!(tblptr || NAME (aout, slurp_reloc_table) (abfd, section, symbols))) 2450 1.1 christos return -1; 2451 1.1 christos 2452 1.1 christos if (section->flags & SEC_CONSTRUCTOR) 2453 1.1 christos { 2454 1.1 christos arelent_chain *chain = section->constructor_chain; 2455 1.1 christos for (count = 0; count < section->reloc_count; count ++) 2456 1.1 christos { 2457 1.1 christos *relptr ++ = &chain->relent; 2458 1.1 christos chain = chain->next; 2459 1.1 christos } 2460 1.1 christos } 2461 1.1 christos else 2462 1.1 christos { 2463 1.1 christos tblptr = section->relocation; 2464 1.1 christos 2465 1.1 christos for (count = 0; count++ < section->reloc_count; ) 2466 1.1 christos { 2467 1.1 christos *relptr++ = tblptr++; 2468 1.1 christos } 2469 1.1 christos } 2470 1.1 christos *relptr = 0; 2471 1.1 christos 2472 1.1.1.9 christos return section->reloc_count; 2473 1.1 christos } 2474 1.1 christos 2475 1.1.1.7 christos long 2476 1.1.1.7 christos NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) 2477 1.1.1.7 christos { 2478 1.1.1.7 christos size_t count, raw; 2479 1.1.1.7 christos 2480 1.1.1.7 christos if (asect->flags & SEC_CONSTRUCTOR) 2481 1.1.1.7 christos count = asect->reloc_count; 2482 1.1.1.7 christos else if (asect == obj_datasec (abfd)) 2483 1.1.1.7 christos count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd); 2484 1.1.1.7 christos else if (asect == obj_textsec (abfd)) 2485 1.1.1.7 christos count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd); 2486 1.1.1.7 christos else if (asect == obj_bsssec (abfd)) 2487 1.1 christos count = 0; 2488 1.1.1.9 christos else 2489 1.1.1.9 christos { 2490 1.1.1.7 christos bfd_set_error (bfd_error_invalid_operation); 2491 1.1.1.7 christos return -1; 2492 1.1.1.7 christos } 2493 1.1.1.7 christos 2494 1.1.1.9 christos if (count >= LONG_MAX / sizeof (arelent *) 2495 1.1.1.9 christos || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw)) 2496 1.1.1.9 christos { 2497 1.1.1.9 christos bfd_set_error (bfd_error_file_too_big); 2498 1.1.1.9 christos return -1; 2499 1.1.1.9 christos } 2500 1.1.1.9 christos if (!bfd_write_p (abfd)) 2501 1.1.1.9 christos { 2502 1.1.1.9 christos ufile_ptr filesize = bfd_get_file_size (abfd); 2503 1.1.1.7 christos if (filesize != 0 && raw > filesize) 2504 1.1 christos { 2505 1.1 christos bfd_set_error (bfd_error_file_truncated); 2506 1.1 christos return -1; 2507 1.1 christos } 2508 1.1 christos } 2509 1.1 christos return (count + 1) * sizeof (arelent *); 2510 1.1 christos } 2511 1.1 christos 2512 1.1 christos long 2514 1.1 christos NAME (aout, get_symtab_upper_bound) (bfd *abfd) 2515 1.1 christos { 2516 1.1 christos if (!NAME (aout, slurp_symbol_table) (abfd)) 2517 1.1 christos return -1; 2518 1.1 christos 2519 1.1 christos return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *)); 2520 1.1 christos } 2521 1.1 christos 2522 1.1 christos alent * 2523 1.1 christos NAME (aout, get_lineno) (bfd *ignore_abfd ATTRIBUTE_UNUSED, 2524 1.1 christos asymbol *ignore_symbol ATTRIBUTE_UNUSED) 2525 1.1 christos { 2526 1.1 christos return NULL; 2527 1.1 christos } 2528 1.1 christos 2529 1.1 christos void 2530 1.1 christos NAME (aout, get_symbol_info) (bfd *ignore_abfd ATTRIBUTE_UNUSED, 2531 1.1 christos asymbol *symbol, 2532 1.1 christos symbol_info *ret) 2533 1.1 christos { 2534 1.1 christos bfd_symbol_info (symbol, ret); 2535 1.1 christos 2536 1.1 christos if (ret->type == '?') 2537 1.1 christos { 2538 1.1 christos int type_code = aout_symbol (symbol)->type & 0xff; 2539 1.1 christos const char *stab_name = bfd_get_stab_name (type_code); 2540 1.1 christos static char buf[10]; 2541 1.1 christos 2542 1.1 christos if (stab_name == NULL) 2543 1.1 christos { 2544 1.1 christos sprintf (buf, "(%d)", type_code); 2545 1.1 christos stab_name = buf; 2546 1.1 christos } 2547 1.1 christos ret->type = '-'; 2548 1.1 christos ret->stab_type = type_code; 2549 1.1 christos ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff); 2550 1.1 christos ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff); 2551 1.1 christos ret->stab_name = stab_name; 2552 1.1 christos } 2553 1.1 christos } 2554 1.1 christos 2555 1.1 christos void 2556 1.1 christos NAME (aout, print_symbol) (bfd *abfd, 2557 1.1 christos void * afile, 2558 1.1 christos asymbol *symbol, 2559 1.1 christos bfd_print_symbol_type how) 2560 1.1 christos { 2561 1.1 christos FILE *file = (FILE *)afile; 2562 1.1 christos 2563 1.1 christos switch (how) 2564 1.1 christos { 2565 1.1 christos case bfd_print_symbol_name: 2566 1.1 christos if (symbol->name) 2567 1.1 christos fprintf (file,"%s", symbol->name); 2568 1.1 christos break; 2569 1.1 christos case bfd_print_symbol_more: 2570 1.1 christos fprintf (file,"%4x %2x %2x", 2571 1.1 christos (unsigned) (aout_symbol (symbol)->desc & 0xffff), 2572 1.1 christos (unsigned) (aout_symbol (symbol)->other & 0xff), 2573 1.1 christos (unsigned) (aout_symbol (symbol)->type)); 2574 1.1 christos break; 2575 1.1 christos case bfd_print_symbol_all: 2576 1.1 christos { 2577 1.1 christos const char *section_name = symbol->section->name; 2578 1.1 christos 2579 1.1 christos bfd_print_symbol_vandf (abfd, (void *)file, symbol); 2580 1.1 christos 2581 1.1 christos fprintf (file," %-5s %04x %02x %02x", 2582 1.1 christos section_name, 2583 1.1 christos (unsigned) (aout_symbol (symbol)->desc & 0xffff), 2584 1.1 christos (unsigned) (aout_symbol (symbol)->other & 0xff), 2585 1.1 christos (unsigned) (aout_symbol (symbol)->type & 0xff)); 2586 1.1 christos if (symbol->name) 2587 1.1 christos fprintf (file," %s", symbol->name); 2588 1.1 christos } 2589 1.1 christos break; 2590 1.1 christos } 2591 1.1 christos } 2592 1.1 christos 2593 1.1 christos /* If we don't have to allocate more than 1MB to hold the generic 2594 1.1 christos symbols, we use the generic minisymbol methord: it's faster, since 2595 1.1 christos it only translates the symbols once, not multiple times. */ 2596 1.1 christos #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol)) 2597 1.1.1.9 christos 2598 1.1 christos /* Read minisymbols. For minisymbols, we use the unmodified a.out 2599 1.1 christos symbols. The minisymbol_to_symbol function translates these into 2600 1.1 christos BFD asymbol structures. */ 2601 1.1 christos 2602 1.1 christos long 2603 1.1 christos NAME (aout, read_minisymbols) (bfd *abfd, 2604 1.1 christos bool dynamic, 2605 1.1 christos void * *minisymsp, 2606 1.1 christos unsigned int *sizep) 2607 1.1 christos { 2608 1.1 christos if (dynamic) 2609 1.1 christos /* We could handle the dynamic symbols here as well, but it's 2610 1.1 christos easier to hand them off. */ 2611 1.1 christos return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); 2612 1.1 christos 2613 1.1 christos if (! aout_get_external_symbols (abfd)) 2614 1.1 christos return -1; 2615 1.1 christos 2616 1.1 christos if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) 2617 1.1 christos return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); 2618 1.1 christos 2619 1.1 christos *minisymsp = (void *) obj_aout_external_syms (abfd); 2620 1.1 christos 2621 1.1 christos /* By passing the external symbols back from this routine, we are 2622 1.1 christos giving up control over the memory block. Clear 2623 1.1 christos obj_aout_external_syms, so that we do not try to free it 2624 1.1 christos ourselves. */ 2625 1.1 christos obj_aout_external_syms (abfd) = NULL; 2626 1.1 christos 2627 1.1 christos *sizep = EXTERNAL_NLIST_SIZE; 2628 1.1 christos return obj_aout_external_sym_count (abfd); 2629 1.1 christos } 2630 1.1.1.9 christos 2631 1.1 christos /* Convert a minisymbol to a BFD asymbol. A minisymbol is just an 2632 1.1 christos unmodified a.out symbol. The SYM argument is a structure returned 2633 1.1 christos by bfd_make_empty_symbol, which we fill in here. */ 2634 1.1 christos 2635 1.1 christos asymbol * 2636 1.1 christos NAME (aout, minisymbol_to_symbol) (bfd *abfd, 2637 1.1 christos bool dynamic, 2638 1.1 christos const void * minisym, 2639 1.1 christos asymbol *sym) 2640 1.1 christos { 2641 1.1 christos if (dynamic 2642 1.1 christos || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) 2643 1.1 christos return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym); 2644 1.1 christos 2645 1.1 christos memset (sym, 0, sizeof (aout_symbol_type)); 2646 1.1 christos 2647 1.1 christos /* We call translate_symbol_table to translate a single symbol. */ 2648 1.1.1.9 christos if (! (NAME (aout, translate_symbol_table) 2649 1.1 christos (abfd, 2650 1.1 christos (aout_symbol_type *) sym, 2651 1.1 christos (struct external_nlist *) minisym, 2652 1.1 christos (bfd_size_type) 1, 2653 1.1 christos obj_aout_external_strings (abfd), 2654 1.1 christos obj_aout_external_string_size (abfd), 2655 1.1 christos false))) 2656 1.1 christos return NULL; 2657 1.1 christos 2658 1.1.1.9 christos return sym; 2659 1.1 christos } 2660 1.1 christos 2661 1.1.1.3 christos /* Provided a BFD, a section and an offset into the section, calculate 2662 1.1 christos and return the name of the source file and the line nearest to the 2663 1.1 christos wanted location. */ 2664 1.1 christos 2665 1.1.1.3 christos bool 2666 1.1.1.3 christos NAME (aout, find_nearest_line) (bfd *abfd, 2667 1.1 christos asymbol **symbols, 2668 1.1 christos asection *section, 2669 1.1 christos bfd_vma offset, 2670 1.1 christos const char **filename_ptr, 2671 1.1 christos const char **functionname_ptr, 2672 1.1 christos unsigned int *line_ptr, 2673 1.1 christos unsigned int *disriminator_ptr) 2674 1.1 christos { 2675 1.1 christos /* Run down the file looking for the filename, function and linenumber. */ 2676 1.1 christos asymbol **p; 2677 1.1 christos const char *directory_name = NULL; 2678 1.1 christos const char *main_file_name = NULL; 2679 1.1 christos const char *current_file_name = NULL; 2680 1.1 christos const char *line_file_name = NULL; /* Value of current_file_name at line number. */ 2681 1.1.1.8 christos const char *line_directory_name = NULL; /* Value of directory_name at line number. */ 2682 1.1.1.6 christos bfd_vma low_line_vma = 0; 2683 1.1 christos bfd_vma low_func_vma = 0; 2684 1.1.1.3 christos asymbol *func = 0; 2685 1.1.1.3 christos bfd_size_type filelen, funclen; 2686 1.1 christos char *buf; 2687 1.1 christos 2688 1.1 christos *filename_ptr = bfd_get_filename (abfd); 2689 1.1 christos *functionname_ptr = NULL; 2690 1.1 christos *line_ptr = 0; 2691 1.1 christos if (disriminator_ptr) 2692 1.1 christos *disriminator_ptr = 0; 2693 1.1 christos 2694 1.1 christos if (symbols != NULL) 2695 1.1 christos { 2696 1.1 christos for (p = symbols; *p; p++) 2697 1.1 christos { 2698 1.1 christos aout_symbol_type *q = (aout_symbol_type *) (*p); 2699 1.1 christos next: 2700 1.1 christos switch (q->type) 2701 1.1 christos { 2702 1.1 christos case N_TEXT: 2703 1.1 christos /* If this looks like a file name symbol, and it comes after 2704 1.1 christos the line number we have found so far, but before the 2705 1.1 christos offset, then we have probably not found the right line 2706 1.1 christos number. */ 2707 1.1 christos if (q->symbol.value <= offset 2708 1.1 christos && ((q->symbol.value > low_line_vma 2709 1.1 christos && (line_file_name != NULL 2710 1.1.1.7 christos || *line_ptr != 0)) 2711 1.1.1.7 christos || (q->symbol.value > low_func_vma 2712 1.1.1.7 christos && func != NULL))) 2713 1.1.1.7 christos { 2714 1.1 christos const char *symname; 2715 1.1 christos 2716 1.1 christos symname = q->symbol.name; 2717 1.1 christos 2718 1.1 christos if (symname != NULL 2719 1.1 christos && strlen (symname) > 2 2720 1.1 christos && strcmp (symname + strlen (symname) - 2, ".o") == 0) 2721 1.1 christos { 2722 1.1 christos if (q->symbol.value > low_line_vma) 2723 1.1 christos { 2724 1.1 christos *line_ptr = 0; 2725 1.1 christos line_file_name = NULL; 2726 1.1 christos } 2727 1.1 christos if (q->symbol.value > low_func_vma) 2728 1.1 christos func = NULL; 2729 1.1 christos } 2730 1.1 christos } 2731 1.1 christos break; 2732 1.1 christos 2733 1.1 christos case N_SO: 2734 1.1 christos /* If this symbol is less than the offset, but greater than 2735 1.1 christos the line number we have found so far, then we have not 2736 1.1 christos found the right line number. */ 2737 1.1 christos if (q->symbol.value <= offset) 2738 1.1 christos { 2739 1.1 christos if (q->symbol.value > low_line_vma) 2740 1.1 christos { 2741 1.1 christos *line_ptr = 0; 2742 1.1 christos line_file_name = NULL; 2743 1.1 christos } 2744 1.1 christos if (q->symbol.value > low_func_vma) 2745 1.1 christos func = NULL; 2746 1.1 christos } 2747 1.1 christos 2748 1.1 christos main_file_name = current_file_name = q->symbol.name; 2749 1.1 christos /* Look ahead to next symbol to check if that too is an N_SO. */ 2750 1.1 christos p++; 2751 1.1 christos if (*p == NULL) 2752 1.1 christos goto done; 2753 1.1 christos q = (aout_symbol_type *) (*p); 2754 1.1 christos if (q->type != (int)N_SO) 2755 1.1 christos goto next; 2756 1.1 christos 2757 1.1 christos /* Found a second N_SO First is directory; second is filename. */ 2758 1.1 christos directory_name = current_file_name; 2759 1.1 christos main_file_name = current_file_name = q->symbol.name; 2760 1.1 christos if (obj_textsec (abfd) != section) 2761 1.1 christos goto done; 2762 1.1 christos break; 2763 1.1 christos case N_SOL: 2764 1.1 christos current_file_name = q->symbol.name; 2765 1.1 christos break; 2766 1.1 christos 2767 1.1 christos case N_SLINE: 2768 1.1 christos 2769 1.1 christos case N_DSLINE: 2770 1.1 christos case N_BSLINE: 2771 1.1 christos /* We'll keep this if it resolves nearer than the one we have 2772 1.1 christos already. */ 2773 1.1 christos if (q->symbol.value >= low_line_vma 2774 1.1 christos && q->symbol.value <= offset) 2775 1.1 christos { 2776 1.1 christos *line_ptr = q->desc; 2777 1.1 christos low_line_vma = q->symbol.value; 2778 1.1.1.7 christos line_file_name = current_file_name; 2779 1.1.1.7 christos line_directory_name = directory_name; 2780 1.1 christos } 2781 1.1 christos break; 2782 1.1 christos case N_FUN: 2783 1.1 christos { 2784 1.1 christos /* We'll keep this if it is nearer than the one we have already. */ 2785 1.1 christos if (q->symbol.value >= low_func_vma 2786 1.1 christos && q->symbol.value <= offset) 2787 1.1 christos { 2788 1.1 christos low_func_vma = q->symbol.value; 2789 1.1 christos func = (asymbol *)q; 2790 1.1 christos } 2791 1.1 christos else if (q->symbol.value > offset) 2792 1.1 christos goto done; 2793 1.1 christos } 2794 1.1 christos break; 2795 1.1 christos } 2796 1.1 christos } 2797 1.1 christos } 2798 1.1 christos 2799 1.1 christos done: 2800 1.1 christos if (*line_ptr != 0) 2801 1.1 christos { 2802 1.1 christos main_file_name = line_file_name; 2803 1.1 christos directory_name = line_directory_name; 2804 1.1 christos } 2805 1.1 christos 2806 1.1 christos if (main_file_name == NULL 2807 1.1 christos || IS_ABSOLUTE_PATH (main_file_name) 2808 1.1 christos || directory_name == NULL) 2809 1.1 christos filelen = 0; 2810 1.1 christos else 2811 1.1.1.8 christos filelen = strlen (directory_name) + strlen (main_file_name); 2812 1.1 christos 2813 1.1 christos if (func == NULL) 2814 1.1 christos funclen = 0; 2815 1.1 christos else 2816 1.1 christos funclen = strlen (bfd_asymbol_name (func)); 2817 1.1 christos 2818 1.1 christos free (adata (abfd).line_buf); 2819 1.1 christos 2820 1.1.1.9 christos if (filelen + funclen == 0) 2821 1.1 christos adata (abfd).line_buf = buf = NULL; 2822 1.1 christos else 2823 1.1 christos { 2824 1.1 christos buf = (char *) bfd_malloc (filelen + funclen + 3); 2825 1.1 christos adata (abfd).line_buf = buf; 2826 1.1 christos if (buf == NULL) 2827 1.1 christos return false; 2828 1.1 christos } 2829 1.1.1.6 christos 2830 1.1.1.6 christos if (main_file_name != NULL) 2831 1.1.1.6 christos { 2832 1.1.1.6 christos if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL) 2833 1.1.1.6 christos *filename_ptr = main_file_name; 2834 1.1.1.6 christos else 2835 1.1.1.6 christos { 2836 1.1.1.6 christos if (buf == NULL) 2837 1.1.1.6 christos /* PR binutils/20891: In a corrupt input file both 2838 1.1.1.6 christos main_file_name and directory_name can be empty... */ 2839 1.1.1.6 christos * filename_ptr = NULL; 2840 1.1 christos else 2841 1.1 christos { 2842 1.1 christos snprintf (buf, filelen + 1, "%s%s", directory_name, 2843 1.1 christos main_file_name); 2844 1.1 christos *filename_ptr = buf; 2845 1.1 christos buf += filelen + 1; 2846 1.1 christos } 2847 1.1 christos } 2848 1.1.1.6 christos } 2849 1.1.1.6 christos 2850 1.1.1.6 christos if (func) 2851 1.1.1.6 christos { 2852 1.1.1.9 christos const char *function = func->name; 2853 1.1.1.6 christos char *colon; 2854 1.1 christos 2855 1.1 christos if (buf == NULL) 2856 1.1 christos { 2857 1.1 christos /* PR binutils/20892: In a corrupt input file func can be empty. */ 2858 1.1 christos * functionname_ptr = NULL; 2859 1.1 christos return true; 2860 1.1 christos } 2861 1.1 christos /* The caller expects a symbol name. We actually have a 2862 1.1 christos function name, without the leading underscore. Put the 2863 1.1 christos underscore back in, so that the caller gets a symbol name. */ 2864 1.1 christos if (bfd_get_symbol_leading_char (abfd) == '\0') 2865 1.1 christos strcpy (buf, function); 2866 1.1 christos else 2867 1.1 christos { 2868 1.1 christos buf[0] = bfd_get_symbol_leading_char (abfd); 2869 1.1 christos strcpy (buf + 1, function); 2870 1.1 christos } 2871 1.1.1.9 christos /* Have to remove : stuff. */ 2872 1.1 christos colon = strchr (buf, ':'); 2873 1.1 christos if (colon != NULL) 2874 1.1 christos *colon = '\0'; 2875 1.1 christos *functionname_ptr = buf; 2876 1.1 christos } 2877 1.1 christos 2878 1.1 christos return true; 2879 1.1 christos } 2880 1.1 christos 2881 1.1.1.10 christos int 2882 1.1 christos NAME (aout, sizeof_headers) (bfd *abfd, 2883 1.1.1.9 christos struct bfd_link_info *info ATTRIBUTE_UNUSED) 2884 1.1 christos { 2885 1.1 christos return adata (abfd).exec_bytes_size; 2886 1.1.1.10 christos } 2887 1.1.1.10 christos 2888 1.1.1.10 christos /* Throw away most malloc'd and alloc'd information for this BFD. */ 2889 1.1.1.10 christos 2890 1.1.1.8 christos bool 2891 1.1.1.10 christos NAME (aout, bfd_free_cached_info) (bfd *abfd) 2892 1.1.1.10 christos { 2893 1.1.1.10 christos if ((bfd_get_format (abfd) == bfd_object 2894 1.1.1.10 christos || bfd_get_format (abfd) == bfd_core) 2895 1.1.1.10 christos && abfd->tdata.aout_data != NULL) 2896 1.1.1.10 christos { 2897 1.1 christos #define BFCI_FREE(x) do { free (x); x = NULL; } while (0) 2898 1.1.1.10 christos BFCI_FREE (adata (abfd).line_buf); 2899 1.1 christos BFCI_FREE (obj_aout_symbols (abfd)); 2900 1.1.1.10 christos BFCI_FREE (obj_aout_external_syms (abfd)); 2901 1.1 christos BFCI_FREE (obj_aout_external_strings (abfd)); 2902 1.1 christos for (asection *o = abfd->sections; o != NULL; o = o->next) 2903 1.1 christos BFCI_FREE (o->relocation); 2904 1.1 christos #undef BFCI_FREE 2905 1.1 christos } 2906 1.1 christos 2907 1.1 christos return _bfd_generic_bfd_free_cached_info (abfd); 2908 1.1 christos } 2909 1.1 christos 2910 1.1 christos /* a.out link code. */ 2912 1.1 christos 2913 1.1 christos /* Routine to create an entry in an a.out link hash table. */ 2914 1.1 christos 2915 1.1 christos struct bfd_hash_entry * 2916 1.1 christos NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry, 2917 1.1 christos struct bfd_hash_table *table, 2918 1.1.1.7 christos const char *string) 2919 1.1 christos { 2920 1.1 christos struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry; 2921 1.1 christos 2922 1.1 christos /* Allocate the structure if it has not already been allocated by a 2923 1.1 christos subclass. */ 2924 1.1 christos if (ret == NULL) 2925 1.1 christos ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table, 2926 1.1 christos sizeof (* ret)); 2927 1.1 christos if (ret == NULL) 2928 1.1 christos return NULL; 2929 1.1.1.9 christos 2930 1.1 christos /* Call the allocation method of the superclass. */ 2931 1.1 christos ret = ((struct aout_link_hash_entry *) 2932 1.1 christos _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, 2933 1.1 christos table, string)); 2934 1.1 christos if (ret) 2935 1.1 christos { 2936 1.1 christos /* Set local fields. */ 2937 1.1 christos ret->written = false; 2938 1.1.1.9 christos ret->indx = -1; 2939 1.1 christos } 2940 1.1 christos 2941 1.1 christos return (struct bfd_hash_entry *) ret; 2942 1.1 christos } 2943 1.1 christos 2944 1.1 christos /* Initialize an a.out link hash table. */ 2945 1.1 christos 2946 1.1 christos bool 2947 1.1 christos NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table, 2948 1.1 christos bfd *abfd, 2949 1.1 christos struct bfd_hash_entry *(*newfunc) 2950 1.1 christos (struct bfd_hash_entry *, struct bfd_hash_table *, 2951 1.1 christos const char *), 2952 1.1 christos unsigned int entsize) 2953 1.1 christos { 2954 1.1 christos return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize); 2955 1.1.1.8 christos } 2956 1.1 christos 2957 1.1 christos /* Create an a.out link hash table. */ 2958 1.1 christos 2959 1.1 christos struct bfd_link_hash_table * 2960 1.1 christos NAME (aout, link_hash_table_create) (bfd *abfd) 2961 1.1 christos { 2962 1.1 christos struct aout_link_hash_table *ret; 2963 1.1 christos size_t amt = sizeof (* ret); 2964 1.1 christos 2965 1.1 christos ret = (struct aout_link_hash_table *) bfd_malloc (amt); 2966 1.1 christos if (ret == NULL) 2967 1.1 christos return NULL; 2968 1.1 christos 2969 1.1 christos if (!NAME (aout, link_hash_table_init) (ret, abfd, 2970 1.1 christos NAME (aout, link_hash_newfunc), 2971 1.1 christos sizeof (struct aout_link_hash_entry))) 2972 1.1 christos { 2973 1.1.1.9 christos free (ret); 2974 1.1 christos return NULL; 2975 1.1 christos } 2976 1.1.1.9 christos return &ret->root; 2977 1.1 christos } 2978 1.1.1.9 christos 2979 1.1 christos /* Add all symbols from an object file to the hash table. */ 2980 1.1 christos 2981 1.1 christos static bool 2982 1.1.1.9 christos aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 2983 1.1 christos { 2984 1.1 christos bool (*add_one_symbol) 2985 1.1 christos (struct bfd_link_info *, bfd *, const char *, flagword, asection *, 2986 1.1 christos bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **); 2987 1.1 christos struct external_nlist *syms; 2988 1.1 christos bfd_size_type sym_count; 2989 1.1 christos char *strings; 2990 1.1 christos bool copy; 2991 1.1 christos struct aout_link_hash_entry **sym_hash; 2992 1.1.1.9 christos struct external_nlist *p; 2993 1.1 christos struct external_nlist *pend; 2994 1.1.1.9 christos bfd_size_type amt; 2995 1.1 christos 2996 1.1 christos syms = obj_aout_external_syms (abfd); 2997 1.1 christos sym_count = obj_aout_external_sym_count (abfd); 2998 1.1 christos strings = obj_aout_external_strings (abfd); 2999 1.1 christos if (info->keep_memory) 3000 1.1.1.9 christos copy = false; 3001 1.1 christos else 3002 1.1 christos copy = true; 3003 1.1 christos 3004 1.1.1.9 christos if (aout_backend_info (abfd)->add_dynamic_symbols != NULL) 3005 1.1 christos { 3006 1.1 christos if (! ((*aout_backend_info (abfd)->add_dynamic_symbols) 3007 1.1 christos (abfd, info, &syms, &sym_count, &strings))) 3008 1.1 christos return false; 3009 1.1 christos } 3010 1.1 christos 3011 1.1 christos if (sym_count == 0) 3012 1.1 christos return true; /* Nothing to do. */ 3013 1.1.1.9 christos 3014 1.1 christos /* We keep a list of the linker hash table entries that correspond 3015 1.1 christos to particular symbols. We could just look them up in the hash 3016 1.1 christos table, but keeping the list is more efficient. Perhaps this 3017 1.1 christos should be conditional on info->keep_memory. */ 3018 1.1 christos amt = sym_count * sizeof (struct aout_link_hash_entry *); 3019 1.1 christos sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt); 3020 1.1 christos if (sym_hash == NULL) 3021 1.1 christos return false; 3022 1.1 christos obj_aout_sym_hashes (abfd) = sym_hash; 3023 1.1 christos 3024 1.1 christos add_one_symbol = aout_backend_info (abfd)->add_one_symbol; 3025 1.1 christos if (add_one_symbol == NULL) 3026 1.1 christos add_one_symbol = _bfd_generic_link_add_one_symbol; 3027 1.1 christos 3028 1.1 christos p = syms; 3029 1.1 christos pend = p + sym_count; 3030 1.1 christos for (; p < pend; p++, sym_hash++) 3031 1.1 christos { 3032 1.1 christos int type; 3033 1.1 christos const char *name; 3034 1.1 christos bfd_vma value; 3035 1.1 christos asection *section; 3036 1.1 christos flagword flags; 3037 1.1 christos const char *string; 3038 1.1 christos 3039 1.1.1.5 christos *sym_hash = NULL; 3040 1.1.1.6 christos 3041 1.1.1.9 christos type = H_GET_8 (abfd, p->e_type); 3042 1.1 christos 3043 1.1 christos /* Ignore debugging symbols. */ 3044 1.1 christos if ((type & N_STAB) != 0) 3045 1.1 christos continue; 3046 1.1 christos 3047 1.1 christos /* PR 19629: Corrupt binaries can contain illegal string offsets. */ 3048 1.1 christos if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) 3049 1.1 christos return false; 3050 1.1 christos name = strings + GET_WORD (abfd, p->e_strx); 3051 1.1 christos value = GET_WORD (abfd, p->e_value); 3052 1.1 christos flags = BSF_GLOBAL; 3053 1.1 christos string = NULL; 3054 1.1 christos switch (type) 3055 1.1 christos { 3056 1.1 christos default: 3057 1.1 christos abort (); 3058 1.1 christos 3059 1.1 christos case N_UNDF: 3060 1.1 christos case N_ABS: 3061 1.1 christos case N_TEXT: 3062 1.1 christos case N_DATA: 3063 1.1 christos case N_BSS: 3064 1.1 christos case N_FN_SEQ: 3065 1.1 christos case N_COMM: 3066 1.1 christos case N_SETV: 3067 1.1 christos case N_FN: 3068 1.1 christos /* Ignore symbols that are not externally visible. */ 3069 1.1 christos continue; 3070 1.1 christos case N_INDR: 3071 1.1 christos /* Ignore local indirect symbol. */ 3072 1.1 christos ++p; 3073 1.1 christos ++sym_hash; 3074 1.1 christos continue; 3075 1.1 christos 3076 1.1 christos case N_UNDF | N_EXT: 3077 1.1 christos if (value == 0) 3078 1.1 christos { 3079 1.1 christos section = bfd_und_section_ptr; 3080 1.1 christos flags = 0; 3081 1.1 christos } 3082 1.1.1.8 christos else 3083 1.1 christos section = bfd_com_section_ptr; 3084 1.1 christos break; 3085 1.1 christos case N_ABS | N_EXT: 3086 1.1 christos section = bfd_abs_section_ptr; 3087 1.1 christos break; 3088 1.1 christos case N_TEXT | N_EXT: 3089 1.1.1.8 christos section = obj_textsec (abfd); 3090 1.1 christos value -= bfd_section_vma (section); 3091 1.1 christos break; 3092 1.1 christos case N_DATA | N_EXT: 3093 1.1.1.8 christos case N_SETV | N_EXT: 3094 1.1 christos /* Treat N_SETV symbols as N_DATA symbol; see comment in 3095 1.1 christos translate_from_native_sym_flags. */ 3096 1.1 christos section = obj_datasec (abfd); 3097 1.1 christos value -= bfd_section_vma (section); 3098 1.1.1.6 christos break; 3099 1.1.1.6 christos case N_BSS | N_EXT: 3100 1.1.1.9 christos section = obj_bsssec (abfd); 3101 1.1 christos value -= bfd_section_vma (section); 3102 1.1.1.5 christos break; 3103 1.1.1.6 christos case N_INDR | N_EXT: 3104 1.1.1.9 christos /* An indirect symbol. The next symbol is the symbol 3105 1.1 christos which this one really is. */ 3106 1.1 christos /* See PR 20925 for a reproducer. */ 3107 1.1 christos if (p + 1 >= pend) 3108 1.1 christos return false; 3109 1.1 christos ++p; 3110 1.1 christos /* PR 19629: Corrupt binaries can contain illegal string offsets. */ 3111 1.1 christos if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) 3112 1.1 christos return false; 3113 1.1 christos string = strings + GET_WORD (abfd, p->e_strx); 3114 1.1 christos section = bfd_ind_section_ptr; 3115 1.1 christos flags |= BSF_INDIRECT; 3116 1.1 christos break; 3117 1.1 christos case N_COMM | N_EXT: 3118 1.1 christos section = bfd_com_section_ptr; 3119 1.1.1.8 christos break; 3120 1.1 christos case N_SETA: case N_SETA | N_EXT: 3121 1.1 christos section = bfd_abs_section_ptr; 3122 1.1 christos flags |= BSF_CONSTRUCTOR; 3123 1.1 christos break; 3124 1.1.1.8 christos case N_SETT: case N_SETT | N_EXT: 3125 1.1 christos section = obj_textsec (abfd); 3126 1.1 christos flags |= BSF_CONSTRUCTOR; 3127 1.1 christos value -= bfd_section_vma (section); 3128 1.1 christos break; 3129 1.1.1.8 christos case N_SETD: case N_SETD | N_EXT: 3130 1.1 christos section = obj_datasec (abfd); 3131 1.1 christos flags |= BSF_CONSTRUCTOR; 3132 1.1 christos value -= bfd_section_vma (section); 3133 1.1 christos break; 3134 1.1 christos case N_SETB: case N_SETB | N_EXT: 3135 1.1.1.9 christos section = obj_bsssec (abfd); 3136 1.1 christos flags |= BSF_CONSTRUCTOR; 3137 1.1 christos value -= bfd_section_vma (section); 3138 1.1.1.5 christos break; 3139 1.1.1.6 christos case N_WARNING: 3140 1.1.1.9 christos /* A warning symbol. The next symbol is the one to warn 3141 1.1 christos about. If there is no next symbol, just look away. */ 3142 1.1 christos if (p + 1 >= pend) 3143 1.1 christos return true; 3144 1.1 christos ++p; 3145 1.1 christos string = name; 3146 1.1 christos /* PR 19629: Corrupt binaries can contain illegal string offsets. */ 3147 1.1 christos if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) 3148 1.1 christos return false; 3149 1.1 christos name = strings + GET_WORD (abfd, p->e_strx); 3150 1.1 christos section = bfd_und_section_ptr; 3151 1.1 christos flags |= BSF_WARNING; 3152 1.1 christos break; 3153 1.1 christos case N_WEAKU: 3154 1.1 christos section = bfd_und_section_ptr; 3155 1.1.1.8 christos flags = BSF_WEAK; 3156 1.1 christos break; 3157 1.1 christos case N_WEAKA: 3158 1.1 christos section = bfd_abs_section_ptr; 3159 1.1 christos flags = BSF_WEAK; 3160 1.1.1.8 christos break; 3161 1.1 christos case N_WEAKT: 3162 1.1 christos section = obj_textsec (abfd); 3163 1.1 christos value -= bfd_section_vma (section); 3164 1.1 christos flags = BSF_WEAK; 3165 1.1.1.8 christos break; 3166 1.1 christos case N_WEAKD: 3167 1.1 christos section = obj_datasec (abfd); 3168 1.1 christos value -= bfd_section_vma (section); 3169 1.1 christos flags = BSF_WEAK; 3170 1.1 christos break; 3171 1.1.1.9 christos case N_WEAKB: 3172 1.1 christos section = obj_bsssec (abfd); 3173 1.1.1.9 christos value -= bfd_section_vma (section); 3174 1.1 christos flags = BSF_WEAK; 3175 1.1 christos break; 3176 1.1 christos } 3177 1.1 christos 3178 1.1 christos if (! ((*add_one_symbol) 3179 1.1 christos (info, abfd, name, flags, section, value, string, copy, false, 3180 1.1 christos (struct bfd_link_hash_entry **) sym_hash))) 3181 1.1 christos return false; 3182 1.1 christos 3183 1.1 christos /* Restrict the maximum alignment of a common symbol based on 3184 1.1 christos the architecture, since a.out has no way to represent 3185 1.1 christos alignment requirements of a section in a .o file. FIXME: 3186 1.1 christos This isn't quite right: it should use the architecture of the 3187 1.1 christos output file, not the input files. */ 3188 1.1 christos if ((*sym_hash)->root.type == bfd_link_hash_common 3189 1.1 christos && ((*sym_hash)->root.u.c.p->alignment_power > 3190 1.1 christos bfd_get_arch_info (abfd)->section_align_power)) 3191 1.1 christos (*sym_hash)->root.u.c.p->alignment_power = 3192 1.1 christos bfd_get_arch_info (abfd)->section_align_power; 3193 1.1 christos 3194 1.1 christos /* If this is a set symbol, and we are not building sets, then 3195 1.1 christos it is possible for the hash entry to not have been set. In 3196 1.1 christos such a case, treat the symbol as not globally defined. */ 3197 1.1 christos if ((*sym_hash)->root.type == bfd_link_hash_new) 3198 1.1 christos { 3199 1.1.1.9 christos BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0); 3200 1.1 christos *sym_hash = NULL; 3201 1.1 christos } 3202 1.1 christos 3203 1.1 christos if (type == (N_INDR | N_EXT) || type == N_WARNING) 3204 1.1.1.9 christos ++sym_hash; 3205 1.1 christos } 3206 1.1 christos 3207 1.1 christos return true; 3208 1.1 christos } 3209 1.1 christos 3210 1.1 christos /* Free up the internal symbols read from an a.out file. */ 3211 1.1 christos 3212 1.1 christos static bool 3213 1.1 christos aout_link_free_symbols (bfd *abfd) 3214 1.1 christos { 3215 1.1 christos if (obj_aout_external_syms (abfd) != NULL) 3216 1.1 christos { 3217 1.1.1.9 christos free ((void *) obj_aout_external_syms (abfd)); 3218 1.1 christos obj_aout_external_syms (abfd) = NULL; 3219 1.1 christos } 3220 1.1 christos if (obj_aout_external_strings (abfd) != NULL) 3221 1.1 christos { 3222 1.1.1.9 christos free ((void *) obj_aout_external_strings (abfd)); 3223 1.1 christos obj_aout_external_strings (abfd) = NULL; 3224 1.1 christos } 3225 1.1 christos return true; 3226 1.1.1.9 christos } 3227 1.1 christos 3228 1.1.1.9 christos /* Add symbols from an a.out object file. */ 3229 1.1 christos 3230 1.1 christos static bool 3231 1.1 christos aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) 3232 1.1.1.9 christos { 3233 1.1 christos if (! aout_get_external_symbols (abfd)) 3234 1.1.1.9 christos return false; 3235 1.1 christos if (! aout_link_add_symbols (abfd, info)) 3236 1.1 christos return false; 3237 1.1 christos if (! info->keep_memory) 3238 1.1 christos { 3239 1.1 christos if (! aout_link_free_symbols (abfd)) 3240 1.1 christos return false; 3241 1.1 christos } 3242 1.1 christos return true; 3243 1.1 christos } 3244 1.1.1.9 christos 3245 1.1 christos /* Look through the internal symbols to see if this object file should 3246 1.1 christos be included in the link. We should include this object file if it 3247 1.1.1.9 christos defines any symbols which are currently undefined. If this object 3248 1.1 christos file defines a common symbol, then we may adjust the size of the 3249 1.1 christos known symbol but we do not include the object file in the link 3250 1.1 christos (unless there is some other reason to include it). */ 3251 1.1 christos 3252 1.1 christos static bool 3253 1.1 christos aout_link_check_ar_symbols (bfd *abfd, 3254 1.1.1.9 christos struct bfd_link_info *info, 3255 1.1 christos bool *pneeded, 3256 1.1 christos bfd **subsbfd) 3257 1.1 christos { 3258 1.1 christos struct external_nlist *p; 3259 1.1 christos struct external_nlist *pend; 3260 1.1 christos char *strings; 3261 1.1 christos 3262 1.1 christos *pneeded = false; 3263 1.1 christos 3264 1.1 christos /* Look through all the symbols. */ 3265 1.1 christos p = obj_aout_external_syms (abfd); 3266 1.1 christos pend = p + obj_aout_external_sym_count (abfd); 3267 1.1 christos strings = obj_aout_external_strings (abfd); 3268 1.1 christos for (; p < pend; p++) 3269 1.1 christos { 3270 1.1 christos int type = H_GET_8 (abfd, p->e_type); 3271 1.1 christos const char *name; 3272 1.1 christos struct bfd_link_hash_entry *h; 3273 1.1 christos 3274 1.1 christos /* Ignore symbols that are not externally visible. This is an 3275 1.1 christos optimization only, as we check the type more thoroughly 3276 1.1 christos below. */ 3277 1.1 christos if (((type & N_EXT) == 0 3278 1.1 christos || (type & N_STAB) != 0 3279 1.1 christos || type == N_FN) 3280 1.1 christos && type != N_WEAKA 3281 1.1 christos && type != N_WEAKT 3282 1.1 christos && type != N_WEAKD 3283 1.1 christos && type != N_WEAKB) 3284 1.1.1.9 christos { 3285 1.1 christos if (type == N_WARNING 3286 1.1 christos || type == N_INDR) 3287 1.1 christos ++p; 3288 1.1 christos continue; 3289 1.1 christos } 3290 1.1 christos 3291 1.1 christos name = strings + GET_WORD (abfd, p->e_strx); 3292 1.1 christos h = bfd_link_hash_lookup (info->hash, name, false, false, true); 3293 1.1 christos 3294 1.1 christos /* We are only interested in symbols that are currently 3295 1.1 christos undefined or common. */ 3296 1.1 christos if (h == NULL 3297 1.1 christos || (h->type != bfd_link_hash_undefined 3298 1.1 christos && h->type != bfd_link_hash_common)) 3299 1.1 christos { 3300 1.1 christos if (type == (N_INDR | N_EXT)) 3301 1.1 christos ++p; 3302 1.1 christos continue; 3303 1.1 christos } 3304 1.1 christos 3305 1.1 christos if (type == (N_TEXT | N_EXT) 3306 1.1 christos || type == (N_DATA | N_EXT) 3307 1.1.1.7 christos || type == (N_BSS | N_EXT) 3308 1.1 christos || type == (N_ABS | N_EXT) 3309 1.1.1.7 christos || type == (N_INDR | N_EXT)) 3310 1.1 christos { 3311 1.1.1.7 christos /* This object file defines this symbol. We must link it 3312 1.1 christos in. This is true regardless of whether the current 3313 1.1.1.7 christos definition of the symbol is undefined or common. 3314 1.1 christos 3315 1.1 christos If the current definition is common, we have a case in 3316 1.1 christos which we have already seen an object file including: 3317 1.1 christos int a; 3318 1.1 christos and this object file from the archive includes: 3319 1.1 christos int a = 5; 3320 1.1 christos In such a case, whether to include this object is target 3321 1.1 christos dependant for backward compatibility. 3322 1.1 christos 3323 1.1 christos FIXME: The SunOS 4.1.3 linker will pull in the archive 3324 1.1 christos element if the symbol is defined in the .data section, 3325 1.1 christos but not if it is defined in the .text section. That 3326 1.1.1.7 christos seems a bit crazy to me, and it has not been implemented 3327 1.1.1.7 christos yet. However, it might be correct. */ 3328 1.1 christos if (h->type == bfd_link_hash_common) 3329 1.1 christos { 3330 1.1 christos int skip = 0; 3331 1.1 christos 3332 1.1 christos switch (info->common_skip_ar_symbols) 3333 1.1 christos { 3334 1.1 christos case bfd_link_common_skip_none: 3335 1.1 christos break; 3336 1.1 christos case bfd_link_common_skip_text: 3337 1.1 christos skip = (type == (N_TEXT | N_EXT)); 3338 1.1 christos break; 3339 1.1 christos case bfd_link_common_skip_data: 3340 1.1 christos skip = (type == (N_DATA | N_EXT)); 3341 1.1 christos break; 3342 1.1 christos case bfd_link_common_skip_all: 3343 1.1 christos skip = 1; 3344 1.1 christos break; 3345 1.1.1.9 christos } 3346 1.1.1.9 christos 3347 1.1.1.9 christos if (skip) 3348 1.1 christos continue; 3349 1.1 christos } 3350 1.1 christos 3351 1.1 christos if (!(*info->callbacks 3352 1.1 christos ->add_archive_element) (info, abfd, name, subsbfd)) 3353 1.1 christos return false; 3354 1.1 christos *pneeded = true; 3355 1.1 christos return true; 3356 1.1 christos } 3357 1.1 christos 3358 1.1 christos if (type == (N_UNDF | N_EXT)) 3359 1.1 christos { 3360 1.1 christos bfd_vma value; 3361 1.1 christos 3362 1.1 christos value = GET_WORD (abfd, p->e_value); 3363 1.1 christos if (value != 0) 3364 1.1 christos { 3365 1.1 christos /* This symbol is common in the object from the archive 3366 1.1 christos file. */ 3367 1.1 christos if (h->type == bfd_link_hash_undefined) 3368 1.1 christos { 3369 1.1 christos bfd *symbfd; 3370 1.1 christos unsigned int power; 3371 1.1 christos 3372 1.1 christos symbfd = h->u.undef.abfd; 3373 1.1.1.9 christos if (symbfd == NULL) 3374 1.1.1.9 christos { 3375 1.1.1.9 christos /* This symbol was created as undefined from 3376 1.1 christos outside BFD. We assume that we should link 3377 1.1 christos in the object file. This is done for the -u 3378 1.1 christos option in the linker. */ 3379 1.1 christos if (!(*info->callbacks 3380 1.1 christos ->add_archive_element) (info, abfd, name, subsbfd)) 3381 1.1 christos return false; 3382 1.1 christos *pneeded = true; 3383 1.1 christos return true; 3384 1.1.1.9 christos } 3385 1.1 christos /* Turn the current link symbol into a common 3386 1.1 christos symbol. It is already on the undefs list. */ 3387 1.1 christos h->type = bfd_link_hash_common; 3388 1.1 christos h->u.c.p = (struct bfd_link_hash_common_entry *) 3389 1.1 christos bfd_hash_allocate (&info->hash->table, 3390 1.1 christos sizeof (struct bfd_link_hash_common_entry)); 3391 1.1 christos if (h->u.c.p == NULL) 3392 1.1 christos return false; 3393 1.1 christos 3394 1.1 christos h->u.c.size = value; 3395 1.1 christos 3396 1.1 christos /* FIXME: This isn't quite right. The maximum 3397 1.1 christos alignment of a common symbol should be set by the 3398 1.1 christos architecture of the output file, not of the input 3399 1.1 christos file. */ 3400 1.1 christos power = bfd_log2 (value); 3401 1.1 christos if (power > bfd_get_arch_info (abfd)->section_align_power) 3402 1.1 christos power = bfd_get_arch_info (abfd)->section_align_power; 3403 1.1 christos h->u.c.p->alignment_power = power; 3404 1.1 christos 3405 1.1 christos h->u.c.p->section = bfd_make_section_old_way (symbfd, 3406 1.1 christos "COMMON"); 3407 1.1 christos } 3408 1.1 christos else 3409 1.1 christos { 3410 1.1 christos /* Adjust the size of the common symbol if 3411 1.1 christos necessary. */ 3412 1.1 christos if (value > h->u.c.size) 3413 1.1 christos h->u.c.size = value; 3414 1.1 christos } 3415 1.1 christos } 3416 1.1 christos } 3417 1.1 christos 3418 1.1 christos if (type == N_WEAKA 3419 1.1 christos || type == N_WEAKT 3420 1.1 christos || type == N_WEAKD 3421 1.1 christos || type == N_WEAKB) 3422 1.1.1.9 christos { 3423 1.1.1.9 christos /* This symbol is weak but defined. We must pull it in if 3424 1.1.1.9 christos the current link symbol is undefined, but we don't want 3425 1.1 christos it if the current link symbol is common. */ 3426 1.1 christos if (h->type == bfd_link_hash_undefined) 3427 1.1 christos { 3428 1.1 christos if (!(*info->callbacks 3429 1.1 christos ->add_archive_element) (info, abfd, name, subsbfd)) 3430 1.1.1.9 christos return false; 3431 1.1 christos *pneeded = true; 3432 1.1 christos return true; 3433 1.1 christos } 3434 1.1 christos } 3435 1.1 christos } 3436 1.1 christos 3437 1.1.1.9 christos /* We do not need this object file. */ 3438 1.1 christos return true; 3439 1.1 christos } 3440 1.1.1.3 christos /* Check a single archive element to see if we need to include it in 3441 1.1.1.3 christos the link. *PNEEDED is set according to whether this element is 3442 1.1.1.9 christos needed in the link or not. This is called from 3443 1.1 christos _bfd_generic_link_add_archive_symbols. */ 3444 1.1 christos 3445 1.1.1.9 christos static bool 3446 1.1 christos aout_link_check_archive_element (bfd *abfd, 3447 1.1 christos struct bfd_link_info *info, 3448 1.1.1.9 christos struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED, 3449 1.1 christos const char *name ATTRIBUTE_UNUSED, 3450 1.1 christos bool *pneeded) 3451 1.1 christos { 3452 1.1.1.9 christos bfd *oldbfd; 3453 1.1 christos bool needed; 3454 1.1 christos 3455 1.1 christos if (!aout_get_external_symbols (abfd)) 3456 1.1 christos return false; 3457 1.1 christos 3458 1.1 christos oldbfd = abfd; 3459 1.1 christos if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd)) 3460 1.1 christos return false; 3461 1.1 christos 3462 1.1 christos needed = *pneeded; 3463 1.1.1.9 christos if (needed) 3464 1.1 christos { 3465 1.1.1.9 christos /* Potentially, the add_archive_element hook may have set a 3466 1.1 christos substitute BFD for us. */ 3467 1.1 christos if (abfd != oldbfd) 3468 1.1.1.9 christos { 3469 1.1 christos if (!info->keep_memory 3470 1.1 christos && !aout_link_free_symbols (oldbfd)) 3471 1.1 christos return false; 3472 1.1 christos if (!aout_get_external_symbols (abfd)) 3473 1.1 christos return false; 3474 1.1.1.9 christos } 3475 1.1 christos if (!aout_link_add_symbols (abfd, info)) 3476 1.1 christos return false; 3477 1.1.1.9 christos } 3478 1.1 christos 3479 1.1 christos if (!info->keep_memory || !needed) 3480 1.1 christos { 3481 1.1 christos if (!aout_link_free_symbols (abfd)) 3482 1.1 christos return false; 3483 1.1.1.9 christos } 3484 1.1 christos 3485 1.1 christos return true; 3486 1.1 christos } 3487 1.1 christos 3488 1.1 christos /* Given an a.out BFD, add symbols to the global hash table as 3489 1.1 christos appropriate. */ 3490 1.1 christos 3491 1.1 christos bool 3492 1.1 christos NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info) 3493 1.1 christos { 3494 1.1 christos switch (bfd_get_format (abfd)) 3495 1.1.1.9 christos { 3496 1.1 christos case bfd_object: 3497 1.1 christos return aout_link_add_object_symbols (abfd, info); 3498 1.1 christos case bfd_archive: 3499 1.1 christos return _bfd_generic_link_add_archive_symbols 3500 1.1 christos (abfd, info, aout_link_check_archive_element); 3501 1.1 christos default: 3502 1.1 christos bfd_set_error (bfd_error_wrong_format); 3503 1.1 christos return false; 3504 1.1 christos } 3505 1.1 christos } 3506 1.1 christos 3507 1.1 christos /* A hash table used for header files with N_BINCL entries. */ 3509 1.1 christos 3510 1.1 christos struct aout_link_includes_table 3511 1.1 christos { 3512 1.1 christos struct bfd_hash_table root; 3513 1.1 christos }; 3514 1.1 christos 3515 1.1 christos /* A linked list of totals that we have found for a particular header 3516 1.1 christos file. */ 3517 1.1 christos 3518 1.1 christos struct aout_link_includes_totals 3519 1.1 christos { 3520 1.1 christos struct aout_link_includes_totals *next; 3521 1.1 christos bfd_vma total; 3522 1.1 christos }; 3523 1.1 christos 3524 1.1 christos /* An entry in the header file hash table. */ 3525 1.1 christos 3526 1.1 christos struct aout_link_includes_entry 3527 1.1 christos { 3528 1.1 christos struct bfd_hash_entry root; 3529 1.1 christos /* List of totals we have found for this file. */ 3530 1.1 christos struct aout_link_includes_totals *totals; 3531 1.1 christos }; 3532 1.1 christos 3533 1.1 christos /* Look up an entry in an the header file hash table. */ 3534 1.1 christos 3535 1.1 christos #define aout_link_includes_lookup(table, string, create, copy) \ 3536 1.1 christos ((struct aout_link_includes_entry *) \ 3537 1.1 christos bfd_hash_lookup (&(table)->root, (string), (create), (copy))) 3538 1.1 christos 3539 1.1 christos /* During the final link step we need to pass around a bunch of 3540 1.1 christos information, so we do it in an instance of this structure. */ 3541 1.1 christos 3542 1.1 christos struct aout_final_link_info 3543 1.1 christos { 3544 1.1 christos /* General link information. */ 3545 1.1 christos struct bfd_link_info *info; 3546 1.1 christos /* Output bfd. */ 3547 1.1 christos bfd *output_bfd; 3548 1.1 christos /* Reloc file positions. */ 3549 1.1 christos file_ptr treloff, dreloff; 3550 1.1 christos /* File position of symbols. */ 3551 1.1 christos file_ptr symoff; 3552 1.1 christos /* String table. */ 3553 1.1 christos struct bfd_strtab_hash *strtab; 3554 1.1 christos /* Header file hash table. */ 3555 1.1 christos struct aout_link_includes_table includes; 3556 1.1 christos /* A buffer large enough to hold the contents of any section. */ 3557 1.1 christos bfd_byte *contents; 3558 1.1 christos /* A buffer large enough to hold the relocs of any section. */ 3559 1.1 christos void * relocs; 3560 1.1 christos /* A buffer large enough to hold the symbol map of any input BFD. */ 3561 1.1 christos int *symbol_map; 3562 1.1 christos /* A buffer large enough to hold output symbols of any input BFD. */ 3563 1.1 christos struct external_nlist *output_syms; 3564 1.1 christos }; 3565 1.1 christos 3566 1.1 christos /* The function to create a new entry in the header file hash table. */ 3567 1.1 christos 3568 1.1 christos static struct bfd_hash_entry * 3569 1.1 christos aout_link_includes_newfunc (struct bfd_hash_entry *entry, 3570 1.1 christos struct bfd_hash_table *table, 3571 1.1.1.7 christos const char *string) 3572 1.1 christos { 3573 1.1 christos struct aout_link_includes_entry *ret = 3574 1.1 christos (struct aout_link_includes_entry *) entry; 3575 1.1 christos 3576 1.1 christos /* Allocate the structure if it has not already been allocated by a 3577 1.1 christos subclass. */ 3578 1.1 christos if (ret == NULL) 3579 1.1 christos ret = (struct aout_link_includes_entry *) 3580 1.1 christos bfd_hash_allocate (table, sizeof (* ret)); 3581 1.1 christos if (ret == NULL) 3582 1.1 christos return NULL; 3583 1.1 christos 3584 1.1 christos /* Call the allocation method of the superclass. */ 3585 1.1 christos ret = ((struct aout_link_includes_entry *) 3586 1.1 christos bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 3587 1.1 christos if (ret) 3588 1.1 christos { 3589 1.1 christos /* Set local fields. */ 3590 1.1.1.9 christos ret->totals = NULL; 3591 1.1.1.2 christos } 3592 1.1 christos 3593 1.1.1.2 christos return (struct bfd_hash_entry *) ret; 3594 1.1.1.2 christos } 3595 1.1 christos 3596 1.1 christos /* Write out a symbol that was not associated with an a.out input 3597 1.1 christos object. */ 3598 1.1 christos 3599 1.1 christos static bool 3600 1.1.1.8 christos aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data) 3601 1.1 christos { 3602 1.1 christos struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh; 3603 1.1 christos struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data; 3604 1.1 christos bfd *output_bfd; 3605 1.1 christos int type; 3606 1.1.1.9 christos bfd_vma val; 3607 1.1 christos struct external_nlist outsym; 3608 1.1 christos bfd_size_type indx; 3609 1.1.1.2 christos size_t amt; 3610 1.1 christos 3611 1.1 christos if (h->root.type == bfd_link_hash_warning) 3612 1.1 christos { 3613 1.1 christos h = (struct aout_link_hash_entry *) h->root.u.i.link; 3614 1.1.1.2 christos if (h->root.type == bfd_link_hash_new) 3615 1.1 christos return true; 3616 1.1 christos } 3617 1.1 christos 3618 1.1 christos output_bfd = flaginfo->output_bfd; 3619 1.1 christos 3620 1.1 christos if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL) 3621 1.1 christos { 3622 1.1.1.9 christos if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol) 3623 1.1 christos (output_bfd, flaginfo->info, h))) 3624 1.1.1.9 christos { 3625 1.1 christos /* FIXME: No way to handle errors. */ 3626 1.1 christos abort (); 3627 1.1 christos } 3628 1.1.1.2 christos } 3629 1.1.1.2 christos 3630 1.1.1.2 christos if (h->written) 3631 1.1.1.9 christos return true; 3632 1.1.1.9 christos 3633 1.1 christos h->written = true; 3634 1.1 christos 3635 1.1 christos /* An indx of -2 means the symbol must be written. */ 3636 1.1 christos if (h->indx != -2 3637 1.1 christos && (flaginfo->info->strip == strip_all 3638 1.1 christos || (flaginfo->info->strip == strip_some 3639 1.1 christos && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string, 3640 1.1.1.9 christos false, false) == NULL))) 3641 1.1 christos return true; 3642 1.1 christos 3643 1.1.1.7 christos switch (h->root.type) 3644 1.1.1.9 christos { 3645 1.1 christos default: 3646 1.1 christos case bfd_link_hash_warning: 3647 1.1 christos abort (); 3648 1.1 christos /* Avoid variable not initialized warnings. */ 3649 1.1 christos return true; 3650 1.1 christos case bfd_link_hash_new: 3651 1.1 christos /* This can happen for set symbols when sets are not being 3652 1.1 christos built. */ 3653 1.1 christos return true; 3654 1.1 christos case bfd_link_hash_undefined: 3655 1.1 christos type = N_UNDF | N_EXT; 3656 1.1 christos val = 0; 3657 1.1 christos break; 3658 1.1 christos case bfd_link_hash_defined: 3659 1.1 christos case bfd_link_hash_defweak: 3660 1.1 christos { 3661 1.1 christos asection *sec; 3662 1.1 christos 3663 1.1 christos sec = h->root.u.def.section->output_section; 3664 1.1 christos BFD_ASSERT (bfd_is_abs_section (sec) 3665 1.1 christos || sec->owner == output_bfd); 3666 1.1 christos if (sec == obj_textsec (output_bfd)) 3667 1.1 christos type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT; 3668 1.1 christos else if (sec == obj_datasec (output_bfd)) 3669 1.1 christos type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD; 3670 1.1 christos else if (sec == obj_bsssec (output_bfd)) 3671 1.1 christos type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB; 3672 1.1 christos else 3673 1.1 christos type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA; 3674 1.1 christos type |= N_EXT; 3675 1.1 christos val = (h->root.u.def.value 3676 1.1 christos + sec->vma 3677 1.1 christos + h->root.u.def.section->output_offset); 3678 1.1 christos } 3679 1.1 christos break; 3680 1.1 christos case bfd_link_hash_common: 3681 1.1 christos type = N_UNDF | N_EXT; 3682 1.1.1.9 christos val = h->root.u.c.size; 3683 1.1 christos break; 3684 1.1 christos case bfd_link_hash_undefweak: 3685 1.1 christos type = N_WEAKU; 3686 1.1 christos val = 0; 3687 1.1 christos break; 3688 1.1.1.2 christos case bfd_link_hash_indirect: 3689 1.1.1.9 christos /* We ignore these symbols, since the indirected symbol is 3690 1.1 christos already in the hash table. */ 3691 1.1 christos return true; 3692 1.1 christos } 3693 1.1 christos 3694 1.1 christos H_PUT_8 (output_bfd, type, outsym.e_type); 3695 1.1 christos H_PUT_8 (output_bfd, 0, outsym.e_other); 3696 1.1 christos H_PUT_16 (output_bfd, 0, outsym.e_desc); 3697 1.1 christos indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string, 3698 1.1.1.2 christos false); 3699 1.1.1.10 christos if (indx == - (bfd_size_type) 1) 3700 1.1 christos /* FIXME: No way to handle errors. */ 3701 1.1 christos abort (); 3702 1.1 christos 3703 1.1.1.2 christos PUT_WORD (output_bfd, indx, outsym.e_strx); 3704 1.1 christos PUT_WORD (output_bfd, val, outsym.e_value); 3705 1.1 christos 3706 1.1 christos amt = EXTERNAL_NLIST_SIZE; 3707 1.1.1.9 christos if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0 3708 1.1 christos || bfd_write (&outsym, amt, output_bfd) != amt) 3709 1.1 christos /* FIXME: No way to handle errors. */ 3710 1.1 christos abort (); 3711 1.1 christos 3712 1.1.1.9 christos flaginfo->symoff += EXTERNAL_NLIST_SIZE; 3713 1.1.1.2 christos h->indx = obj_aout_external_sym_count (output_bfd); 3714 1.1 christos ++obj_aout_external_sym_count (output_bfd); 3715 1.1 christos 3716 1.1 christos return true; 3717 1.1 christos } 3718 1.1 christos 3719 1.1 christos /* Handle a link order which is supposed to generate a reloc. */ 3720 1.1 christos 3721 1.1 christos static bool 3722 1.1 christos aout_link_reloc_link_order (struct aout_final_link_info *flaginfo, 3723 1.1 christos asection *o, 3724 1.1 christos struct bfd_link_order *p) 3725 1.1.1.8 christos { 3726 1.1 christos struct bfd_link_order_reloc *pr; 3727 1.1 christos int r_index; 3728 1.1 christos int r_extern; 3729 1.1 christos reloc_howto_type *howto; 3730 1.1 christos file_ptr *reloff_ptr = NULL; 3731 1.1 christos struct reloc_std_external srel; 3732 1.1 christos struct reloc_ext_external erel; 3733 1.1 christos void * rel_ptr; 3734 1.1 christos size_t amt; 3735 1.1 christos 3736 1.1.1.2 christos pr = p->u.reloc.p; 3737 1.1 christos 3738 1.1 christos if (p->type == bfd_section_reloc_link_order) 3739 1.1 christos { 3740 1.1 christos r_extern = 0; 3741 1.1 christos if (bfd_is_abs_section (pr->u.section)) 3742 1.1 christos r_index = N_ABS | N_EXT; 3743 1.1 christos else 3744 1.1 christos { 3745 1.1 christos BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd); 3746 1.1 christos r_index = pr->u.section->target_index; 3747 1.1.1.2 christos } 3748 1.1.1.9 christos } 3749 1.1 christos else 3750 1.1 christos { 3751 1.1 christos struct aout_link_hash_entry *h; 3752 1.1 christos 3753 1.1 christos BFD_ASSERT (p->type == bfd_symbol_reloc_link_order); 3754 1.1 christos r_extern = 1; 3755 1.1 christos h = ((struct aout_link_hash_entry *) 3756 1.1 christos bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info, 3757 1.1 christos pr->u.name, false, false, true)); 3758 1.1 christos if (h != NULL 3759 1.1.1.9 christos && h->indx >= 0) 3760 1.1.1.2 christos r_index = h->indx; 3761 1.1.1.9 christos else if (h != NULL) 3762 1.1 christos { 3763 1.1 christos /* We decided to strip this symbol, but it turns out that we 3764 1.1 christos can't. Note that we lose the other and desc information 3765 1.1 christos here. I don't think that will ever matter for a global 3766 1.1.1.5 christos symbol. */ 3767 1.1.1.5 christos h->indx = -2; 3768 1.1 christos h->written = false; 3769 1.1 christos if (!aout_link_write_other_symbol (&h->root.root, flaginfo)) 3770 1.1 christos return false; 3771 1.1 christos r_index = h->indx; 3772 1.1.1.2 christos } 3773 1.1 christos else 3774 1.1 christos { 3775 1.1 christos (*flaginfo->info->callbacks->unattached_reloc) 3776 1.1.1.9 christos (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0); 3777 1.1 christos r_index = 0; 3778 1.1 christos } 3779 1.1.1.2 christos } 3780 1.1.1.2 christos 3781 1.1.1.2 christos howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc); 3782 1.1.1.2 christos if (howto == 0) 3783 1.1 christos { 3784 1.1 christos bfd_set_error (bfd_error_bad_value); 3785 1.1 christos return false; 3786 1.1.1.2 christos } 3787 1.1 christos 3788 1.1 christos if (o == obj_textsec (flaginfo->output_bfd)) 3789 1.1.1.2 christos reloff_ptr = &flaginfo->treloff; 3790 1.1 christos else if (o == obj_datasec (flaginfo->output_bfd)) 3791 1.1 christos reloff_ptr = &flaginfo->dreloff; 3792 1.1 christos else 3793 1.1 christos abort (); 3794 1.1 christos 3795 1.1 christos if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE) 3796 1.1 christos { 3797 1.1.1.8 christos #ifdef MY_put_reloc 3798 1.1 christos MY_put_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, howto, 3799 1.1 christos &srel); 3800 1.1 christos #else 3801 1.1 christos { 3802 1.1 christos int r_pcrel; 3803 1.1.1.9 christos int r_baserel; 3804 1.1 christos int r_jmptable; 3805 1.1.1.2 christos int r_relative; 3806 1.1.1.2 christos unsigned int r_length; 3807 1.1 christos 3808 1.1 christos r_pcrel = (int) howto->pc_relative; 3809 1.1 christos r_baserel = (howto->type & 8) != 0; 3810 1.1 christos r_jmptable = (howto->type & 16) != 0; 3811 1.1 christos r_relative = (howto->type & 32) != 0; 3812 1.1 christos r_length = bfd_log2 (bfd_get_reloc_size (howto)); 3813 1.1 christos 3814 1.1 christos PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address); 3815 1.1 christos if (bfd_header_big_endian (flaginfo->output_bfd)) 3816 1.1 christos { 3817 1.1 christos srel.r_index[0] = r_index >> 16; 3818 1.1 christos srel.r_index[1] = r_index >> 8; 3819 1.1 christos srel.r_index[2] = r_index; 3820 1.1 christos srel.r_type[0] = 3821 1.1 christos ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 3822 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 3823 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) 3824 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) 3825 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) 3826 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 3827 1.1 christos } 3828 1.1 christos else 3829 1.1 christos { 3830 1.1 christos srel.r_index[2] = r_index >> 16; 3831 1.1 christos srel.r_index[1] = r_index >> 8; 3832 1.1 christos srel.r_index[0] = r_index; 3833 1.1 christos srel.r_type[0] = 3834 1.1 christos ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 3835 1.1 christos | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 3836 1.1 christos | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) 3837 1.1 christos | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) 3838 1.1 christos | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) 3839 1.1 christos | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 3840 1.1 christos } 3841 1.1 christos } 3842 1.1 christos #endif 3843 1.1 christos rel_ptr = (void *) &srel; 3844 1.1 christos 3845 1.1 christos /* We have to write the addend into the object file, since 3846 1.1.1.9 christos standard a.out relocs are in place. It would be more 3847 1.1 christos reliable if we had the current contents of the file here, 3848 1.1 christos rather than assuming zeroes, but we can't read the file since 3849 1.1 christos it was opened using bfd_openw. */ 3850 1.1.1.4 christos if (pr->addend != 0) 3851 1.1.1.9 christos { 3852 1.1.1.2 christos bfd_size_type size; 3853 1.1 christos bfd_reloc_status_type r; 3854 1.1 christos bfd_byte *buf; 3855 1.1 christos bool ok; 3856 1.1 christos 3857 1.1 christos size = bfd_get_reloc_size (howto); 3858 1.1 christos buf = (bfd_byte *) bfd_zmalloc (size); 3859 1.1 christos if (buf == NULL && size != 0) 3860 1.1 christos return false; 3861 1.1 christos r = MY_relocate_contents (howto, flaginfo->output_bfd, 3862 1.1.1.5 christos (bfd_vma) pr->addend, buf); 3863 1.1.1.5 christos switch (r) 3864 1.1.1.5 christos { 3865 1.1.1.8 christos case bfd_reloc_ok: 3866 1.1.1.5 christos break; 3867 1.1.1.5 christos default: 3868 1.1 christos case bfd_reloc_outofrange: 3869 1.1 christos abort (); 3870 1.1.1.2 christos case bfd_reloc_overflow: 3871 1.1 christos (*flaginfo->info->callbacks->reloc_overflow) 3872 1.1 christos (flaginfo->info, NULL, 3873 1.1 christos (p->type == bfd_section_reloc_link_order 3874 1.1.1.9 christos ? bfd_section_name (pr->u.section) 3875 1.1 christos : pr->u.name), 3876 1.1 christos howto->name, pr->addend, NULL, NULL, (bfd_vma) 0); 3877 1.1 christos break; 3878 1.1 christos } 3879 1.1 christos ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf, 3880 1.1.1.2 christos (file_ptr) p->offset, size); 3881 1.1 christos free (buf); 3882 1.1 christos if (! ok) 3883 1.1.1.2 christos return false; 3884 1.1 christos } 3885 1.1.1.2 christos } 3886 1.1 christos else 3887 1.1 christos { 3888 1.1 christos #ifdef MY_put_ext_reloc 3889 1.1 christos MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, 3890 1.1 christos howto, &erel, pr->addend); 3891 1.1 christos #else 3892 1.1 christos PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address); 3893 1.1 christos 3894 1.1 christos if (bfd_header_big_endian (flaginfo->output_bfd)) 3895 1.1 christos { 3896 1.1 christos erel.r_index[0] = r_index >> 16; 3897 1.1 christos erel.r_index[1] = r_index >> 8; 3898 1.1 christos erel.r_index[2] = r_index; 3899 1.1 christos erel.r_type[0] = 3900 1.1 christos ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) 3901 1.1 christos | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG)); 3902 1.1 christos } 3903 1.1 christos else 3904 1.1.1.2 christos { 3905 1.1 christos erel.r_index[2] = r_index >> 16; 3906 1.1 christos erel.r_index[1] = r_index >> 8; 3907 1.1 christos erel.r_index[0] = r_index; 3908 1.1 christos erel.r_type[0] = 3909 1.1 christos (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) 3910 1.1.1.2 christos | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE); 3911 1.1.1.2 christos } 3912 1.1.1.10 christos 3913 1.1.1.9 christos PUT_WORD (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend); 3914 1.1 christos #endif /* MY_put_ext_reloc */ 3915 1.1.1.2 christos 3916 1.1 christos rel_ptr = (void *) &erel; 3917 1.1 christos } 3918 1.1 christos 3919 1.1.1.2 christos amt = obj_reloc_entry_size (flaginfo->output_bfd); 3920 1.1.1.2 christos if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0 3921 1.1 christos || bfd_write (rel_ptr, amt, flaginfo->output_bfd) != amt) 3922 1.1.1.2 christos return false; 3923 1.1 christos 3924 1.1.1.9 christos *reloff_ptr += obj_reloc_entry_size (flaginfo->output_bfd); 3925 1.1 christos 3926 1.1 christos /* Assert that the relocs have not run into the symbols, and that n 3927 1.1 christos the text relocs have not run into the data relocs. */ 3928 1.1 christos BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd) 3929 1.1.1.9 christos && (reloff_ptr != &flaginfo->treloff 3930 1.1 christos || (*reloff_ptr 3931 1.1 christos <= obj_datasec (flaginfo->output_bfd)->rel_filepos))); 3932 1.1 christos 3933 1.1 christos return true; 3934 1.1 christos } 3935 1.1 christos 3936 1.1 christos /* Get the section corresponding to a reloc index. */ 3937 1.1 christos 3938 1.1 christos static inline asection * 3939 1.1 christos aout_reloc_index_to_section (bfd *abfd, int indx) 3940 1.1 christos { 3941 1.1 christos switch (indx & N_TYPE) 3942 1.1 christos { 3943 1.1 christos case N_TEXT: return obj_textsec (abfd); 3944 1.1 christos case N_DATA: return obj_datasec (abfd); 3945 1.1 christos case N_BSS: return obj_bsssec (abfd); 3946 1.1.1.9 christos case N_ABS: 3947 1.1.1.2 christos case N_UNDF: return bfd_abs_section_ptr; 3948 1.1 christos default: abort (); 3949 1.1 christos } 3950 1.1 christos return NULL; 3951 1.1 christos } 3952 1.1 christos 3953 1.1 christos /* Relocate an a.out section using standard a.out relocs. */ 3954 1.1.1.9 christos 3955 1.1 christos static bool 3956 1.1.1.9 christos aout_link_input_section_std (struct aout_final_link_info *flaginfo, 3957 1.1 christos bfd *input_bfd, 3958 1.1.1.9 christos asection *input_section, 3959 1.1 christos struct reloc_std_external *relocs, 3960 1.1 christos bfd_size_type rel_size, 3961 1.1 christos bfd_byte *contents) 3962 1.1 christos { 3963 1.1 christos bool (*check_dynamic_reloc) 3964 1.1 christos (struct bfd_link_info *, bfd *, asection *, 3965 1.1 christos struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *); 3966 1.1 christos bfd *output_bfd; 3967 1.1.1.2 christos bool relocatable; 3968 1.1 christos struct external_nlist *syms; 3969 1.1 christos char *strings; 3970 1.1 christos struct aout_link_hash_entry **sym_hashes; 3971 1.1 christos int *symbol_map; 3972 1.1 christos bfd_size_type reloc_count; 3973 1.1 christos struct reloc_std_external *rel; 3974 1.1.1.5 christos struct reloc_std_external *rel_end; 3975 1.1 christos 3976 1.1 christos output_bfd = flaginfo->output_bfd; 3977 1.1 christos check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; 3978 1.1.1.2 christos 3979 1.1 christos BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE); 3980 1.1 christos BFD_ASSERT (input_bfd->xvec->header_byteorder 3981 1.1 christos == output_bfd->xvec->header_byteorder); 3982 1.1 christos 3983 1.1 christos relocatable = bfd_link_relocatable (flaginfo->info); 3984 1.1 christos syms = obj_aout_external_syms (input_bfd); 3985 1.1 christos strings = obj_aout_external_strings (input_bfd); 3986 1.1.1.9 christos sym_hashes = obj_aout_sym_hashes (input_bfd); 3987 1.1 christos symbol_map = flaginfo->symbol_map; 3988 1.1 christos 3989 1.1 christos reloc_count = rel_size / RELOC_STD_SIZE; 3990 1.1 christos rel = relocs; 3991 1.1 christos rel_end = rel + reloc_count; 3992 1.1 christos for (; rel < rel_end; rel++) 3993 1.1 christos { 3994 1.1 christos bfd_vma r_addr; 3995 1.1 christos unsigned int r_index; 3996 1.1 christos int r_extern; 3997 1.1 christos int r_pcrel; 3998 1.1 christos int r_baserel = 0; 3999 1.1 christos reloc_howto_type *howto; 4000 1.1 christos struct aout_link_hash_entry *h = NULL; 4001 1.1 christos bfd_vma relocation; 4002 1.1 christos bfd_reloc_status_type r; 4003 1.1 christos 4004 1.1 christos r_addr = GET_SWORD (input_bfd, rel->r_address); 4005 1.1 christos 4006 1.1 christos #ifdef MY_reloc_howto 4007 1.1 christos howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel); 4008 1.1 christos #else 4009 1.1 christos { 4010 1.1 christos int r_jmptable; 4011 1.1 christos int r_relative; 4012 1.1 christos int r_length; 4013 1.1 christos unsigned int howto_idx; 4014 1.1 christos 4015 1.1 christos if (bfd_header_big_endian (input_bfd)) 4016 1.1 christos { 4017 1.1 christos r_index = (((unsigned int) rel->r_index[0] << 16) 4018 1.1 christos | ((unsigned int) rel->r_index[1] << 8) 4019 1.1 christos | rel->r_index[2]); 4020 1.1 christos r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); 4021 1.1 christos r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); 4022 1.1 christos r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); 4023 1.1 christos r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); 4024 1.1 christos r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); 4025 1.1 christos r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 4026 1.1 christos >> RELOC_STD_BITS_LENGTH_SH_BIG); 4027 1.1 christos } 4028 1.1 christos else 4029 1.1 christos { 4030 1.1 christos r_index = (((unsigned int) rel->r_index[2] << 16) 4031 1.1 christos | ((unsigned int) rel->r_index[1] << 8) 4032 1.1 christos | rel->r_index[0]); 4033 1.1 christos r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); 4034 1.1 christos r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); 4035 1.1 christos r_baserel = (0 != (rel->r_type[0] 4036 1.1 christos & RELOC_STD_BITS_BASEREL_LITTLE)); 4037 1.1 christos r_jmptable= (0 != (rel->r_type[0] 4038 1.1 christos & RELOC_STD_BITS_JMPTABLE_LITTLE)); 4039 1.1 christos r_relative= (0 != (rel->r_type[0] 4040 1.1 christos & RELOC_STD_BITS_RELATIVE_LITTLE)); 4041 1.1 christos r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 4042 1.1 christos >> RELOC_STD_BITS_LENGTH_SH_LITTLE); 4043 1.1 christos } 4044 1.1 christos 4045 1.1 christos howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel 4046 1.1 christos + 16 * r_jmptable + 32 * r_relative); 4047 1.1.1.7 christos if (howto_idx < TABLE_SIZE (howto_table_std)) 4048 1.1.1.7 christos howto = howto_table_std + howto_idx; 4049 1.1 christos else 4050 1.1.1.9 christos howto = NULL; 4051 1.1 christos } 4052 1.1 christos #endif 4053 1.1 christos 4054 1.1 christos if (howto == NULL) 4055 1.1 christos { 4056 1.1 christos _bfd_error_handler (_("%pB: unsupported relocation type"), 4057 1.1 christos input_bfd); 4058 1.1 christos bfd_set_error (bfd_error_bad_value); 4059 1.1 christos return false; 4060 1.1 christos } 4061 1.1 christos 4062 1.1 christos if (relocatable) 4063 1.1 christos { 4064 1.1 christos /* We are generating a relocatable output file, and must 4065 1.1 christos modify the reloc accordingly. */ 4066 1.1 christos if (r_extern) 4067 1.1 christos { 4068 1.1 christos /* If we know the symbol this relocation is against, 4069 1.1 christos convert it into a relocation against a section. This 4070 1.1 christos is what the native linker does. */ 4071 1.1 christos h = sym_hashes[r_index]; 4072 1.1 christos if (h != NULL 4073 1.1 christos && (h->root.type == bfd_link_hash_defined 4074 1.1 christos || h->root.type == bfd_link_hash_defweak)) 4075 1.1 christos { 4076 1.1 christos asection *output_section; 4077 1.1 christos 4078 1.1 christos /* Change the r_extern value. */ 4079 1.1 christos if (bfd_header_big_endian (output_bfd)) 4080 1.1 christos rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG; 4081 1.1 christos else 4082 1.1 christos rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE; 4083 1.1 christos 4084 1.1 christos /* Compute a new r_index. */ 4085 1.1 christos output_section = h->root.u.def.section->output_section; 4086 1.1 christos if (output_section == obj_textsec (output_bfd)) 4087 1.1 christos r_index = N_TEXT; 4088 1.1 christos else if (output_section == obj_datasec (output_bfd)) 4089 1.1 christos r_index = N_DATA; 4090 1.1 christos else if (output_section == obj_bsssec (output_bfd)) 4091 1.1 christos r_index = N_BSS; 4092 1.1 christos else 4093 1.1 christos r_index = N_ABS; 4094 1.1 christos 4095 1.1 christos /* Add the symbol value and the section VMA to the 4096 1.1 christos addend stored in the contents. */ 4097 1.1 christos relocation = (h->root.u.def.value 4098 1.1.1.9 christos + output_section->vma 4099 1.1 christos + h->root.u.def.section->output_offset); 4100 1.1 christos } 4101 1.1 christos else 4102 1.1 christos { 4103 1.1.1.7 christos /* We must change r_index according to the symbol 4104 1.1.1.7 christos map. */ 4105 1.1.1.7 christos r_index = symbol_map[r_index]; 4106 1.1.1.7 christos 4107 1.1 christos if (r_index == -1u) 4108 1.1 christos { 4109 1.1 christos if (h != NULL) 4110 1.1.1.9 christos { 4111 1.1.1.2 christos /* We decided to strip this symbol, but it 4112 1.1.1.2 christos turns out that we can't. Note that we 4113 1.1.1.9 christos lose the other and desc information here. 4114 1.1 christos I don't think that will ever matter for a 4115 1.1 christos global symbol. */ 4116 1.1 christos if (h->indx < 0) 4117 1.1 christos { 4118 1.1 christos h->indx = -2; 4119 1.1 christos h->written = false; 4120 1.1 christos if (!aout_link_write_other_symbol (&h->root.root, 4121 1.1 christos flaginfo)) 4122 1.1 christos return false; 4123 1.1.1.5 christos } 4124 1.1.1.5 christos r_index = h->indx; 4125 1.1.1.5 christos } 4126 1.1 christos else 4127 1.1 christos { 4128 1.1 christos const char *name; 4129 1.1 christos 4130 1.1 christos name = strings + GET_WORD (input_bfd, 4131 1.1 christos syms[r_index].e_strx); 4132 1.1 christos (*flaginfo->info->callbacks->unattached_reloc) 4133 1.1 christos (flaginfo->info, name, 4134 1.1 christos input_bfd, input_section, r_addr); 4135 1.1 christos r_index = 0; 4136 1.1 christos } 4137 1.1 christos } 4138 1.1 christos 4139 1.1 christos relocation = 0; 4140 1.1 christos } 4141 1.1 christos 4142 1.1 christos /* Write out the new r_index value. */ 4143 1.1 christos if (bfd_header_big_endian (output_bfd)) 4144 1.1 christos { 4145 1.1 christos rel->r_index[0] = r_index >> 16; 4146 1.1 christos rel->r_index[1] = r_index >> 8; 4147 1.1 christos rel->r_index[2] = r_index; 4148 1.1 christos } 4149 1.1 christos else 4150 1.1 christos { 4151 1.1 christos rel->r_index[2] = r_index >> 16; 4152 1.1 christos rel->r_index[1] = r_index >> 8; 4153 1.1 christos rel->r_index[0] = r_index; 4154 1.1 christos } 4155 1.1 christos } 4156 1.1 christos else 4157 1.1 christos { 4158 1.1 christos asection *section; 4159 1.1 christos 4160 1.1 christos /* This is a relocation against a section. We must 4161 1.1 christos adjust by the amount that the section moved. */ 4162 1.1 christos section = aout_reloc_index_to_section (input_bfd, r_index); 4163 1.1 christos relocation = (section->output_section->vma 4164 1.1 christos + section->output_offset 4165 1.1 christos - section->vma); 4166 1.1 christos } 4167 1.1 christos 4168 1.1 christos /* Change the address of the relocation. */ 4169 1.1 christos PUT_WORD (output_bfd, 4170 1.1 christos r_addr + input_section->output_offset, 4171 1.1 christos rel->r_address); 4172 1.1 christos 4173 1.1 christos /* Adjust a PC relative relocation by removing the reference 4174 1.1 christos to the original address in the section and including the 4175 1.1 christos reference to the new address. */ 4176 1.1 christos if (r_pcrel) 4177 1.1 christos relocation -= (input_section->output_section->vma 4178 1.1 christos + input_section->output_offset 4179 1.1 christos - input_section->vma); 4180 1.1 christos 4181 1.1 christos #ifdef MY_relocatable_reloc 4182 1.1 christos MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr); 4183 1.1 christos #endif 4184 1.1 christos 4185 1.1.1.9 christos if (relocation == 0) 4186 1.1 christos r = bfd_reloc_ok; 4187 1.1 christos else 4188 1.1 christos r = MY_relocate_contents (howto, 4189 1.1.1.9 christos input_bfd, relocation, 4190 1.1 christos contents + r_addr); 4191 1.1 christos } 4192 1.1 christos else 4193 1.1 christos { 4194 1.1 christos bool hundef; 4195 1.1 christos 4196 1.1 christos /* We are generating an executable, and must do a full 4197 1.1 christos relocation. */ 4198 1.1 christos hundef = false; 4199 1.1 christos 4200 1.1 christos if (r_extern) 4201 1.1 christos { 4202 1.1 christos h = sym_hashes[r_index]; 4203 1.1 christos 4204 1.1 christos if (h != NULL 4205 1.1 christos && (h->root.type == bfd_link_hash_defined 4206 1.1 christos || h->root.type == bfd_link_hash_defweak)) 4207 1.1 christos { 4208 1.1.1.9 christos relocation = (h->root.u.def.value 4209 1.1 christos + h->root.u.def.section->output_section->vma 4210 1.1 christos + h->root.u.def.section->output_offset); 4211 1.1 christos } 4212 1.1 christos else if (h != NULL 4213 1.1 christos && h->root.type == bfd_link_hash_undefweak) 4214 1.1 christos relocation = 0; 4215 1.1 christos else 4216 1.1 christos { 4217 1.1 christos hundef = true; 4218 1.1 christos relocation = 0; 4219 1.1 christos } 4220 1.1 christos } 4221 1.1 christos else 4222 1.1 christos { 4223 1.1 christos asection *section; 4224 1.1 christos 4225 1.1 christos section = aout_reloc_index_to_section (input_bfd, r_index); 4226 1.1.1.9 christos relocation = (section->output_section->vma 4227 1.1 christos + section->output_offset 4228 1.1 christos - section->vma); 4229 1.1.1.2 christos if (r_pcrel) 4230 1.1 christos relocation += input_section->vma; 4231 1.1.1.9 christos } 4232 1.1 christos 4233 1.1 christos if (check_dynamic_reloc != NULL) 4234 1.1 christos { 4235 1.1 christos bool skip; 4236 1.1 christos 4237 1.1.1.7 christos if (! ((*check_dynamic_reloc) 4238 1.1.1.7 christos (flaginfo->info, input_bfd, input_section, h, 4239 1.1.1.5 christos (void *) rel, contents, &skip, &relocation))) 4240 1.1 christos return false; 4241 1.1 christos if (skip) 4242 1.1 christos continue; 4243 1.1 christos } 4244 1.1 christos 4245 1.1 christos /* Now warn if a global symbol is undefined. We could not 4246 1.1 christos do this earlier, because check_dynamic_reloc might want 4247 1.1.1.5 christos to skip this reloc. */ 4248 1.1.1.9 christos if (hundef && ! bfd_link_pic (flaginfo->info) && ! r_baserel) 4249 1.1 christos { 4250 1.1 christos const char *name; 4251 1.1 christos 4252 1.1 christos if (h != NULL) 4253 1.1 christos name = h->root.root.string; 4254 1.1 christos else 4255 1.1 christos name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); 4256 1.1 christos (*flaginfo->info->callbacks->undefined_symbol) 4257 1.1 christos (flaginfo->info, name, input_bfd, input_section, r_addr, true); 4258 1.1 christos } 4259 1.1 christos 4260 1.1 christos r = MY_final_link_relocate (howto, 4261 1.1 christos input_bfd, input_section, 4262 1.1 christos contents, r_addr, relocation, 4263 1.1 christos (bfd_vma) 0); 4264 1.1 christos } 4265 1.1 christos 4266 1.1 christos if (r != bfd_reloc_ok) 4267 1.1 christos { 4268 1.1 christos switch (r) 4269 1.1 christos { 4270 1.1 christos default: 4271 1.1 christos case bfd_reloc_outofrange: 4272 1.1 christos abort (); 4273 1.1 christos case bfd_reloc_overflow: 4274 1.1 christos { 4275 1.1 christos const char *name; 4276 1.1 christos 4277 1.1 christos if (h != NULL) 4278 1.1.1.8 christos name = NULL; 4279 1.1 christos else if (r_extern) 4280 1.1.1.5 christos name = strings + GET_WORD (input_bfd, 4281 1.1.1.5 christos syms[r_index].e_strx); 4282 1.1.1.5 christos else 4283 1.1 christos { 4284 1.1 christos asection *s; 4285 1.1 christos 4286 1.1 christos s = aout_reloc_index_to_section (input_bfd, r_index); 4287 1.1 christos name = bfd_section_name (s); 4288 1.1 christos } 4289 1.1.1.9 christos (*flaginfo->info->callbacks->reloc_overflow) 4290 1.1 christos (flaginfo->info, (h ? &h->root : NULL), name, howto->name, 4291 1.1 christos (bfd_vma) 0, input_bfd, input_section, r_addr); 4292 1.1 christos } 4293 1.1 christos break; 4294 1.1.1.9 christos } 4295 1.1.1.2 christos } 4296 1.1 christos } 4297 1.1 christos 4298 1.1 christos return true; 4299 1.1 christos } 4300 1.1 christos 4301 1.1 christos /* Relocate an a.out section using extended a.out relocs. */ 4302 1.1.1.9 christos 4303 1.1 christos static bool 4304 1.1.1.9 christos aout_link_input_section_ext (struct aout_final_link_info *flaginfo, 4305 1.1 christos bfd *input_bfd, 4306 1.1.1.9 christos asection *input_section, 4307 1.1 christos struct reloc_ext_external *relocs, 4308 1.1 christos bfd_size_type rel_size, 4309 1.1 christos bfd_byte *contents) 4310 1.1 christos { 4311 1.1 christos bool (*check_dynamic_reloc) 4312 1.1 christos (struct bfd_link_info *, bfd *, asection *, 4313 1.1 christos struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *); 4314 1.1 christos bfd *output_bfd; 4315 1.1.1.2 christos bool relocatable; 4316 1.1 christos struct external_nlist *syms; 4317 1.1 christos char *strings; 4318 1.1 christos struct aout_link_hash_entry **sym_hashes; 4319 1.1 christos int *symbol_map; 4320 1.1 christos bfd_size_type reloc_count; 4321 1.1 christos struct reloc_ext_external *rel; 4322 1.1.1.5 christos struct reloc_ext_external *rel_end; 4323 1.1 christos 4324 1.1 christos output_bfd = flaginfo->output_bfd; 4325 1.1 christos check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; 4326 1.1.1.2 christos 4327 1.1 christos BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE); 4328 1.1 christos BFD_ASSERT (input_bfd->xvec->header_byteorder 4329 1.1 christos == output_bfd->xvec->header_byteorder); 4330 1.1 christos 4331 1.1 christos relocatable = bfd_link_relocatable (flaginfo->info); 4332 1.1 christos syms = obj_aout_external_syms (input_bfd); 4333 1.1 christos strings = obj_aout_external_strings (input_bfd); 4334 1.1.1.9 christos sym_hashes = obj_aout_sym_hashes (input_bfd); 4335 1.1 christos symbol_map = flaginfo->symbol_map; 4336 1.1 christos 4337 1.1 christos reloc_count = rel_size / RELOC_EXT_SIZE; 4338 1.1 christos rel = relocs; 4339 1.1 christos rel_end = rel + reloc_count; 4340 1.1 christos for (; rel < rel_end; rel++) 4341 1.1 christos { 4342 1.1 christos bfd_vma r_addr; 4343 1.1 christos unsigned int r_index; 4344 1.1 christos int r_extern; 4345 1.1 christos unsigned int r_type; 4346 1.1 christos bfd_vma r_addend; 4347 1.1 christos struct aout_link_hash_entry *h = NULL; 4348 1.1 christos asection *r_section = NULL; 4349 1.1 christos bfd_vma relocation; 4350 1.1 christos 4351 1.1 christos r_addr = GET_SWORD (input_bfd, rel->r_address); 4352 1.1 christos 4353 1.1 christos if (bfd_header_big_endian (input_bfd)) 4354 1.1 christos { 4355 1.1 christos r_index = (((unsigned int) rel->r_index[0] << 16) 4356 1.1 christos | ((unsigned int) rel->r_index[1] << 8) 4357 1.1 christos | rel->r_index[2]); 4358 1.1 christos r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); 4359 1.1 christos r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) 4360 1.1 christos >> RELOC_EXT_BITS_TYPE_SH_BIG); 4361 1.1 christos } 4362 1.1 christos else 4363 1.1 christos { 4364 1.1 christos r_index = (((unsigned int) rel->r_index[2] << 16) 4365 1.1 christos | ((unsigned int) rel->r_index[1] << 8) 4366 1.1 christos | rel->r_index[0]); 4367 1.1.1.7 christos r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); 4368 1.1.1.7 christos r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) 4369 1.1 christos >> RELOC_EXT_BITS_TYPE_SH_LITTLE); 4370 1.1.1.9 christos } 4371 1.1 christos 4372 1.1 christos r_addend = GET_SWORD (input_bfd, rel->r_addend); 4373 1.1 christos 4374 1.1 christos if (r_type >= TABLE_SIZE (howto_table_ext)) 4375 1.1 christos { 4376 1.1 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 4377 1.1 christos input_bfd, r_type); 4378 1.1 christos bfd_set_error (bfd_error_bad_value); 4379 1.1 christos return false; 4380 1.1 christos } 4381 1.1 christos 4382 1.1 christos if (relocatable) 4383 1.1 christos { 4384 1.1 christos /* We are generating a relocatable output file, and must 4385 1.1 christos modify the reloc accordingly. */ 4386 1.1 christos if (r_extern 4387 1.1 christos || r_type == (unsigned int) RELOC_BASE10 4388 1.1 christos || r_type == (unsigned int) RELOC_BASE13 4389 1.1 christos || r_type == (unsigned int) RELOC_BASE22) 4390 1.1 christos { 4391 1.1 christos /* If we know the symbol this relocation is against, 4392 1.1 christos convert it into a relocation against a section. This 4393 1.1 christos is what the native linker does. */ 4394 1.1 christos if (r_type == (unsigned int) RELOC_BASE10 4395 1.1 christos || r_type == (unsigned int) RELOC_BASE13 4396 1.1 christos || r_type == (unsigned int) RELOC_BASE22) 4397 1.1 christos h = NULL; 4398 1.1 christos else 4399 1.1 christos h = sym_hashes[r_index]; 4400 1.1 christos if (h != NULL 4401 1.1 christos && (h->root.type == bfd_link_hash_defined 4402 1.1 christos || h->root.type == bfd_link_hash_defweak)) 4403 1.1 christos { 4404 1.1 christos asection *output_section; 4405 1.1 christos 4406 1.1 christos /* Change the r_extern value. */ 4407 1.1 christos if (bfd_header_big_endian (output_bfd)) 4408 1.1 christos rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG; 4409 1.1 christos else 4410 1.1 christos rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE; 4411 1.1 christos 4412 1.1 christos /* Compute a new r_index. */ 4413 1.1 christos output_section = h->root.u.def.section->output_section; 4414 1.1 christos if (output_section == obj_textsec (output_bfd)) 4415 1.1 christos r_index = N_TEXT; 4416 1.1 christos else if (output_section == obj_datasec (output_bfd)) 4417 1.1 christos r_index = N_DATA; 4418 1.1 christos else if (output_section == obj_bsssec (output_bfd)) 4419 1.1 christos r_index = N_BSS; 4420 1.1 christos else 4421 1.1 christos r_index = N_ABS; 4422 1.1 christos 4423 1.1 christos /* Add the symbol value and the section VMA to the 4424 1.1 christos addend. */ 4425 1.1 christos relocation = (h->root.u.def.value 4426 1.1 christos + output_section->vma 4427 1.1 christos + h->root.u.def.section->output_offset); 4428 1.1 christos 4429 1.1 christos /* Now RELOCATION is the VMA of the final 4430 1.1 christos destination. If this is a PC relative reloc, 4431 1.1 christos then ADDEND is the negative of the source VMA. 4432 1.1 christos We want to set ADDEND to the difference between 4433 1.1 christos the destination VMA and the source VMA, which 4434 1.1.1.9 christos means we must adjust RELOCATION by the change in 4435 1.1 christos the source VMA. This is done below. */ 4436 1.1 christos } 4437 1.1 christos else 4438 1.1 christos { 4439 1.1.1.7 christos /* We must change r_index according to the symbol 4440 1.1.1.7 christos map. */ 4441 1.1.1.7 christos r_index = symbol_map[r_index]; 4442 1.1.1.7 christos 4443 1.1 christos if (r_index == -1u) 4444 1.1 christos { 4445 1.1 christos if (h != NULL) 4446 1.1.1.9 christos { 4447 1.1.1.2 christos /* We decided to strip this symbol, but it 4448 1.1.1.2 christos turns out that we can't. Note that we 4449 1.1.1.9 christos lose the other and desc information here. 4450 1.1 christos I don't think that will ever matter for a 4451 1.1 christos global symbol. */ 4452 1.1 christos if (h->indx < 0) 4453 1.1 christos { 4454 1.1 christos h->indx = -2; 4455 1.1 christos h->written = false; 4456 1.1 christos if (!aout_link_write_other_symbol (&h->root.root, 4457 1.1 christos flaginfo)) 4458 1.1 christos return false; 4459 1.1.1.5 christos } 4460 1.1.1.5 christos r_index = h->indx; 4461 1.1.1.5 christos } 4462 1.1 christos else 4463 1.1 christos { 4464 1.1 christos const char *name; 4465 1.1 christos 4466 1.1 christos name = strings + GET_WORD (input_bfd, 4467 1.1 christos syms[r_index].e_strx); 4468 1.1 christos (*flaginfo->info->callbacks->unattached_reloc) 4469 1.1 christos (flaginfo->info, name, 4470 1.1 christos input_bfd, input_section, r_addr); 4471 1.1 christos r_index = 0; 4472 1.1 christos } 4473 1.1 christos } 4474 1.1 christos 4475 1.1 christos relocation = 0; 4476 1.1 christos 4477 1.1 christos /* If this is a PC relative reloc, then the addend 4478 1.1 christos is the negative of the source VMA. We must 4479 1.1 christos adjust it by the change in the source VMA. This 4480 1.1 christos is done below. */ 4481 1.1 christos } 4482 1.1 christos 4483 1.1 christos /* Write out the new r_index value. */ 4484 1.1 christos if (bfd_header_big_endian (output_bfd)) 4485 1.1 christos { 4486 1.1 christos rel->r_index[0] = r_index >> 16; 4487 1.1 christos rel->r_index[1] = r_index >> 8; 4488 1.1 christos rel->r_index[2] = r_index; 4489 1.1 christos } 4490 1.1 christos else 4491 1.1 christos { 4492 1.1 christos rel->r_index[2] = r_index >> 16; 4493 1.1 christos rel->r_index[1] = r_index >> 8; 4494 1.1 christos rel->r_index[0] = r_index; 4495 1.1 christos } 4496 1.1 christos } 4497 1.1 christos else 4498 1.1 christos { 4499 1.1 christos /* This is a relocation against a section. We must 4500 1.1 christos adjust by the amount that the section moved. */ 4501 1.1 christos r_section = aout_reloc_index_to_section (input_bfd, r_index); 4502 1.1 christos relocation = (r_section->output_section->vma 4503 1.1 christos + r_section->output_offset 4504 1.1 christos - r_section->vma); 4505 1.1 christos 4506 1.1 christos /* If this is a PC relative reloc, then the addend is 4507 1.1 christos the difference in VMA between the destination and the 4508 1.1 christos source. We have just adjusted for the change in VMA 4509 1.1 christos of the destination, so we must also adjust by the 4510 1.1 christos change in VMA of the source. This is done below. */ 4511 1.1 christos } 4512 1.1 christos 4513 1.1 christos /* As described above, we must always adjust a PC relative 4514 1.1 christos reloc by the change in VMA of the source. However, if 4515 1.1 christos pcrel_offset is set, then the addend does not include the 4516 1.1 christos location within the section, in which case we don't need 4517 1.1 christos to adjust anything. */ 4518 1.1 christos if (howto_table_ext[r_type].pc_relative 4519 1.1 christos && ! howto_table_ext[r_type].pcrel_offset) 4520 1.1 christos relocation -= (input_section->output_section->vma 4521 1.1 christos + input_section->output_offset 4522 1.1 christos - input_section->vma); 4523 1.1 christos 4524 1.1 christos /* Change the addend if necessary. */ 4525 1.1 christos if (relocation != 0) 4526 1.1.1.9 christos PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend); 4527 1.1 christos 4528 1.1 christos /* Change the address of the relocation. */ 4529 1.1 christos PUT_WORD (output_bfd, 4530 1.1 christos r_addr + input_section->output_offset, 4531 1.1.1.9 christos rel->r_address); 4532 1.1 christos } 4533 1.1 christos else 4534 1.1 christos { 4535 1.1 christos bool hundef; 4536 1.1 christos bfd_reloc_status_type r; 4537 1.1 christos 4538 1.1 christos /* We are generating an executable, and must do a full 4539 1.1 christos relocation. */ 4540 1.1 christos hundef = false; 4541 1.1 christos 4542 1.1 christos if (r_extern) 4543 1.1 christos { 4544 1.1 christos h = sym_hashes[r_index]; 4545 1.1 christos 4546 1.1 christos if (h != NULL 4547 1.1 christos && (h->root.type == bfd_link_hash_defined 4548 1.1 christos || h->root.type == bfd_link_hash_defweak)) 4549 1.1 christos { 4550 1.1.1.9 christos relocation = (h->root.u.def.value 4551 1.1 christos + h->root.u.def.section->output_section->vma 4552 1.1 christos + h->root.u.def.section->output_offset); 4553 1.1 christos } 4554 1.1 christos else if (h != NULL 4555 1.1 christos && h->root.type == bfd_link_hash_undefweak) 4556 1.1 christos relocation = 0; 4557 1.1 christos else 4558 1.1 christos { 4559 1.1 christos hundef = true; 4560 1.1 christos relocation = 0; 4561 1.1 christos } 4562 1.1.1.7 christos } 4563 1.1 christos else if (r_type == (unsigned int) RELOC_BASE10 4564 1.1 christos || r_type == (unsigned int) RELOC_BASE13 4565 1.1 christos || r_type == (unsigned int) RELOC_BASE22) 4566 1.1 christos { 4567 1.1 christos struct external_nlist *sym; 4568 1.1 christos int type; 4569 1.1 christos 4570 1.1 christos /* For base relative relocs, r_index is always an index 4571 1.1 christos into the symbol table, even if r_extern is 0. */ 4572 1.1 christos sym = syms + r_index; 4573 1.1 christos type = H_GET_8 (input_bfd, sym->e_type); 4574 1.1 christos if ((type & N_TYPE) == N_TEXT 4575 1.1 christos || type == N_WEAKT) 4576 1.1 christos r_section = obj_textsec (input_bfd); 4577 1.1 christos else if ((type & N_TYPE) == N_DATA 4578 1.1 christos || type == N_WEAKD) 4579 1.1 christos r_section = obj_datasec (input_bfd); 4580 1.1 christos else if ((type & N_TYPE) == N_BSS 4581 1.1 christos || type == N_WEAKB) 4582 1.1 christos r_section = obj_bsssec (input_bfd); 4583 1.1 christos else if ((type & N_TYPE) == N_ABS 4584 1.1 christos || type == N_WEAKA) 4585 1.1 christos r_section = bfd_abs_section_ptr; 4586 1.1 christos else 4587 1.1 christos abort (); 4588 1.1 christos relocation = (r_section->output_section->vma 4589 1.1 christos + r_section->output_offset 4590 1.1 christos + (GET_WORD (input_bfd, sym->e_value) 4591 1.1 christos - r_section->vma)); 4592 1.1 christos } 4593 1.1 christos else 4594 1.1 christos { 4595 1.1 christos r_section = aout_reloc_index_to_section (input_bfd, r_index); 4596 1.1 christos 4597 1.1 christos /* If this is a PC relative reloc, then R_ADDEND is the 4598 1.1 christos difference between the two vmas, or 4599 1.1 christos old_dest_sec + old_dest_off - (old_src_sec + old_src_off) 4600 1.1 christos where 4601 1.1 christos old_dest_sec == section->vma 4602 1.1 christos and 4603 1.1 christos old_src_sec == input_section->vma 4604 1.1 christos and 4605 1.1 christos old_src_off == r_addr 4606 1.1 christos 4607 1.1 christos _bfd_final_link_relocate expects RELOCATION + 4608 1.1 christos R_ADDEND to be the VMA of the destination minus 4609 1.1 christos r_addr (the minus r_addr is because this relocation 4610 1.1 christos is not pcrel_offset, which is a bit confusing and 4611 1.1 christos should, perhaps, be changed), or 4612 1.1 christos new_dest_sec 4613 1.1 christos where 4614 1.1 christos new_dest_sec == output_section->vma + output_offset 4615 1.1 christos We arrange for this to happen by setting RELOCATION to 4616 1.1 christos new_dest_sec + old_src_sec - old_dest_sec 4617 1.1 christos 4618 1.1 christos If this is not a PC relative reloc, then R_ADDEND is 4619 1.1 christos simply the VMA of the destination, so we set 4620 1.1 christos RELOCATION to the change in the destination VMA, or 4621 1.1 christos new_dest_sec - old_dest_sec 4622 1.1 christos */ 4623 1.1.1.9 christos relocation = (r_section->output_section->vma 4624 1.1 christos + r_section->output_offset 4625 1.1 christos - r_section->vma); 4626 1.1.1.2 christos if (howto_table_ext[r_type].pc_relative) 4627 1.1 christos relocation += input_section->vma; 4628 1.1.1.9 christos } 4629 1.1 christos 4630 1.1 christos if (check_dynamic_reloc != NULL) 4631 1.1 christos { 4632 1.1 christos bool skip; 4633 1.1 christos 4634 1.1.1.7 christos if (! ((*check_dynamic_reloc) 4635 1.1.1.7 christos (flaginfo->info, input_bfd, input_section, h, 4636 1.1 christos (void *) rel, contents, &skip, &relocation))) 4637 1.1.1.5 christos return false; 4638 1.1 christos if (skip) 4639 1.1 christos continue; 4640 1.1 christos } 4641 1.1 christos 4642 1.1 christos /* Now warn if a global symbol is undefined. We could not 4643 1.1 christos do this earlier, because check_dynamic_reloc might want 4644 1.1 christos to skip this reloc. */ 4645 1.1 christos if (hundef 4646 1.1 christos && ! bfd_link_pic (flaginfo->info) 4647 1.1 christos && r_type != (unsigned int) RELOC_BASE10 4648 1.1.1.5 christos && r_type != (unsigned int) RELOC_BASE13 4649 1.1.1.9 christos && r_type != (unsigned int) RELOC_BASE22) 4650 1.1 christos { 4651 1.1 christos const char *name; 4652 1.1 christos 4653 1.1 christos if (h != NULL) 4654 1.1 christos name = h->root.root.string; 4655 1.1 christos else 4656 1.1 christos name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); 4657 1.1 christos (*flaginfo->info->callbacks->undefined_symbol) 4658 1.1 christos (flaginfo->info, name, input_bfd, input_section, r_addr, true); 4659 1.1 christos } 4660 1.1 christos 4661 1.1 christos if (r_type != (unsigned int) RELOC_SPARC_REV32) 4662 1.1 christos r = MY_final_link_relocate (howto_table_ext + r_type, 4663 1.1 christos input_bfd, input_section, 4664 1.1 christos contents, r_addr, relocation, 4665 1.1 christos r_addend); 4666 1.1 christos else 4667 1.1 christos { 4668 1.1 christos bfd_vma x; 4669 1.1 christos 4670 1.1 christos x = bfd_get_32 (input_bfd, contents + r_addr); 4671 1.1 christos x = x + relocation + r_addend; 4672 1.1 christos bfd_putl32 (/*input_bfd,*/ x, contents + r_addr); 4673 1.1 christos r = bfd_reloc_ok; 4674 1.1 christos } 4675 1.1 christos 4676 1.1 christos if (r != bfd_reloc_ok) 4677 1.1 christos { 4678 1.1 christos switch (r) 4679 1.1 christos { 4680 1.1 christos default: 4681 1.1 christos case bfd_reloc_outofrange: 4682 1.1 christos abort (); 4683 1.1 christos case bfd_reloc_overflow: 4684 1.1 christos { 4685 1.1 christos const char *name; 4686 1.1 christos 4687 1.1 christos if (h != NULL) 4688 1.1 christos name = NULL; 4689 1.1 christos else if (r_extern 4690 1.1 christos || r_type == (unsigned int) RELOC_BASE10 4691 1.1.1.8 christos || r_type == (unsigned int) RELOC_BASE13 4692 1.1 christos || r_type == (unsigned int) RELOC_BASE22) 4693 1.1.1.5 christos name = strings + GET_WORD (input_bfd, 4694 1.1.1.5 christos syms[r_index].e_strx); 4695 1.1.1.5 christos else 4696 1.1.1.5 christos { 4697 1.1 christos asection *s; 4698 1.1 christos 4699 1.1 christos s = aout_reloc_index_to_section (input_bfd, r_index); 4700 1.1 christos name = bfd_section_name (s); 4701 1.1 christos } 4702 1.1 christos (*flaginfo->info->callbacks->reloc_overflow) 4703 1.1 christos (flaginfo->info, (h ? &h->root : NULL), name, 4704 1.1.1.9 christos howto_table_ext[r_type].name, 4705 1.1 christos r_addend, input_bfd, input_section, r_addr); 4706 1.1 christos } 4707 1.1 christos break; 4708 1.1 christos } 4709 1.1.1.9 christos } 4710 1.1.1.2 christos } 4711 1.1 christos } 4712 1.1 christos 4713 1.1 christos return true; 4714 1.1 christos } 4715 1.1 christos 4716 1.1 christos /* Link an a.out section into the output file. */ 4717 1.1 christos 4718 1.1 christos static bool 4719 1.1 christos aout_link_input_section (struct aout_final_link_info *flaginfo, 4720 1.1 christos bfd *input_bfd, 4721 1.1 christos asection *input_section, 4722 1.1.1.2 christos file_ptr *reloff_ptr, 4723 1.1 christos bfd_size_type rel_size) 4724 1.1.1.9 christos { 4725 1.1 christos bfd_size_type input_size; 4726 1.1.1.11 christos void * relocs; 4727 1.1.1.11 christos 4728 1.1 christos /* Get the section contents. */ 4729 1.1.1.11 christos input_size = input_section->size; 4730 1.1.1.11 christos if (! bfd_get_section_contents (input_bfd, input_section, 4731 1.1.1.11 christos (void *) flaginfo->contents, 4732 1.1 christos (file_ptr) 0, input_size)) 4733 1.1 christos return false; 4734 1.1 christos 4735 1.1 christos relocs = flaginfo->relocs; 4736 1.1 christos if (rel_size > 0) 4737 1.1.1.2 christos { 4738 1.1 christos if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 4739 1.1.1.2 christos || bfd_read (relocs, rel_size, input_bfd) != rel_size) 4740 1.1.1.9 christos return false; 4741 1.1 christos } 4742 1.1 christos 4743 1.1 christos /* Relocate the section contents. */ 4744 1.1.1.2 christos if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) 4745 1.1 christos { 4746 1.1.1.2 christos if (! aout_link_input_section_std (flaginfo, input_bfd, input_section, 4747 1.1.1.9 christos (struct reloc_std_external *) relocs, 4748 1.1 christos rel_size, flaginfo->contents)) 4749 1.1 christos return false; 4750 1.1 christos } 4751 1.1.1.2 christos else 4752 1.1 christos { 4753 1.1.1.2 christos if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section, 4754 1.1 christos (struct reloc_ext_external *) relocs, 4755 1.1 christos rel_size, flaginfo->contents)) 4756 1.1.1.9 christos return false; 4757 1.1 christos } 4758 1.1 christos 4759 1.1 christos /* Write out the section contents. */ 4760 1.1.1.5 christos if (! bfd_set_section_contents (flaginfo->output_bfd, 4761 1.1 christos input_section->output_section, 4762 1.1.1.2 christos (void *) flaginfo->contents, 4763 1.1.1.9 christos (file_ptr) input_section->output_offset, 4764 1.1.1.10 christos input_size)) 4765 1.1.1.9 christos return false; 4766 1.1 christos 4767 1.1 christos /* If we are producing relocatable output, the relocs were 4768 1.1 christos modified, and we now write them out. */ 4769 1.1 christos if (bfd_link_relocatable (flaginfo->info) && rel_size > 0) 4770 1.1 christos { 4771 1.1.1.2 christos if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0) 4772 1.1.1.2 christos return false; 4773 1.1 christos if (bfd_write (relocs, rel_size, flaginfo->output_bfd) != rel_size) 4774 1.1.1.2 christos return false; 4775 1.1 christos *reloff_ptr += rel_size; 4776 1.1 christos 4777 1.1.1.9 christos /* Assert that the relocs have not run into the symbols, and 4778 1.1 christos that if these are the text relocs they have not run into the 4779 1.1 christos data relocs. */ 4780 1.1 christos BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd) 4781 1.1 christos && (reloff_ptr != &flaginfo->treloff 4782 1.1 christos || (*reloff_ptr 4783 1.1.1.9 christos <= obj_datasec (flaginfo->output_bfd)->rel_filepos))); 4784 1.1.1.2 christos } 4785 1.1 christos 4786 1.1 christos return true; 4787 1.1 christos } 4788 1.1 christos 4789 1.1 christos /* Adjust and write out the symbols for an a.out file. Set the new 4790 1.1 christos symbol indices into a symbol_map. */ 4791 1.1 christos 4792 1.1 christos static bool 4793 1.1 christos aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd) 4794 1.1 christos { 4795 1.1 christos bfd *output_bfd; 4796 1.1 christos bfd_size_type sym_count; 4797 1.1.1.9 christos char *strings; 4798 1.1.1.9 christos enum bfd_link_strip strip; 4799 1.1 christos enum bfd_link_discard discard; 4800 1.1.1.2 christos struct external_nlist *outsym; 4801 1.1 christos bfd_size_type strtab_index; 4802 1.1 christos struct external_nlist *sym; 4803 1.1.1.2 christos struct external_nlist *sym_end; 4804 1.1.1.2 christos struct aout_link_hash_entry **sym_hash; 4805 1.1.1.2 christos int *symbol_map; 4806 1.1 christos bool pass; 4807 1.1 christos bool skip_next; 4808 1.1 christos 4809 1.1 christos output_bfd = flaginfo->output_bfd; 4810 1.1 christos sym_count = obj_aout_external_sym_count (input_bfd); 4811 1.1.1.8 christos strings = obj_aout_external_strings (input_bfd); 4812 1.1.1.8 christos strip = flaginfo->info->strip; 4813 1.1.1.9 christos discard = flaginfo->info->discard; 4814 1.1 christos outsym = flaginfo->output_syms; 4815 1.1 christos 4816 1.1 christos /* First write out a symbol for this object file, unless we are 4817 1.1 christos discarding such symbols. */ 4818 1.1 christos if (strip != strip_all 4819 1.1.1.2 christos && (strip != strip_some 4820 1.1.1.9 christos || bfd_hash_lookup (flaginfo->info->keep_hash, 4821 1.1 christos bfd_get_filename (input_bfd), 4822 1.1.1.9 christos false, false) != NULL) 4823 1.1 christos && discard != discard_all) 4824 1.1 christos { 4825 1.1.1.8 christos H_PUT_8 (output_bfd, N_TEXT, outsym->e_type); 4826 1.1 christos H_PUT_8 (output_bfd, 0, outsym->e_other); 4827 1.1 christos H_PUT_16 (output_bfd, 0, outsym->e_desc); 4828 1.1 christos strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab, 4829 1.1 christos bfd_get_filename (input_bfd), false); 4830 1.1 christos if (strtab_index == (bfd_size_type) -1) 4831 1.1 christos return false; 4832 1.1.1.9 christos PUT_WORD (output_bfd, strtab_index, outsym->e_strx); 4833 1.1.1.9 christos PUT_WORD (output_bfd, 4834 1.1 christos (bfd_section_vma (obj_textsec (input_bfd)->output_section) 4835 1.1 christos + obj_textsec (input_bfd)->output_offset), 4836 1.1 christos outsym->e_value); 4837 1.1.1.2 christos ++obj_aout_external_sym_count (output_bfd); 4838 1.1 christos ++outsym; 4839 1.1 christos } 4840 1.1 christos 4841 1.1 christos pass = false; 4842 1.1 christos skip_next = false; 4843 1.1 christos sym = obj_aout_external_syms (input_bfd); 4844 1.1.1.9 christos sym_end = sym + sym_count; 4845 1.1 christos sym_hash = obj_aout_sym_hashes (input_bfd); 4846 1.1 christos symbol_map = flaginfo->symbol_map; 4847 1.1.1.9 christos memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map); 4848 1.1 christos for (; sym < sym_end; sym++, sym_hash++, symbol_map++) 4849 1.1 christos { 4850 1.1.1.7 christos const char *name; 4851 1.1.1.7 christos int type; 4852 1.1.1.7 christos struct aout_link_hash_entry *h; 4853 1.1 christos bool skip; 4854 1.1 christos asection *symsec; 4855 1.1 christos bfd_vma val = 0; 4856 1.1 christos bool copy; 4857 1.1.1.7 christos 4858 1.1.1.7 christos /* We set *symbol_map to 0 above for all symbols. If it has 4859 1.1 christos already been set to -1 for this symbol, it means that we are 4860 1.1 christos discarding it because it appears in a duplicate header file. 4861 1.1 christos See the N_BINCL code below. */ 4862 1.1 christos if (*symbol_map == -1) 4863 1.1 christos continue; 4864 1.1 christos 4865 1.1 christos /* Initialize *symbol_map to -1, which means that the symbol was 4866 1.1 christos not copied into the output file. We will change it later if 4867 1.1 christos we do copy the symbol over. */ 4868 1.1 christos *symbol_map = -1; 4869 1.1 christos 4870 1.1 christos type = H_GET_8 (input_bfd, sym->e_type); 4871 1.1.1.9 christos name = strings + GET_WORD (input_bfd, sym->e_strx); 4872 1.1 christos 4873 1.1 christos h = NULL; 4874 1.1 christos 4875 1.1 christos if (pass) 4876 1.1 christos { 4877 1.1 christos /* Pass this symbol through. It is the target of an 4878 1.1.1.9 christos indirect or warning symbol. */ 4879 1.1 christos val = GET_WORD (input_bfd, sym->e_value); 4880 1.1 christos pass = false; 4881 1.1 christos } 4882 1.1 christos else if (skip_next) 4883 1.1 christos { 4884 1.1 christos /* Skip this symbol, which is the target of an indirect 4885 1.1 christos symbol that we have changed to no longer be an indirect 4886 1.1 christos symbol. */ 4887 1.1 christos skip_next = false; 4888 1.1 christos continue; 4889 1.1 christos } 4890 1.1 christos else 4891 1.1 christos { 4892 1.1.1.7 christos struct aout_link_hash_entry *hresolve; 4893 1.1 christos 4894 1.1 christos /* We have saved the hash table entry for this symbol, if 4895 1.1 christos there is one. Note that we could just look it up again 4896 1.1 christos in the hash table, provided we first check that it is an 4897 1.1 christos external symbol. */ 4898 1.1 christos h = *sym_hash; 4899 1.1 christos 4900 1.1 christos /* Use the name from the hash table, in case the symbol was 4901 1.1 christos wrapped. */ 4902 1.1 christos if (h != NULL 4903 1.1 christos && h->root.type != bfd_link_hash_warning) 4904 1.1 christos name = h->root.root.string; 4905 1.1 christos 4906 1.1 christos /* If this is an indirect or warning symbol, then change 4907 1.1 christos hresolve to the base symbol. We also change *sym_hash so 4908 1.1 christos that the relocation routines relocate against the real 4909 1.1 christos symbol. */ 4910 1.1 christos hresolve = h; 4911 1.1 christos if (h != (struct aout_link_hash_entry *) NULL 4912 1.1 christos && (h->root.type == bfd_link_hash_indirect 4913 1.1 christos || h->root.type == bfd_link_hash_warning)) 4914 1.1 christos { 4915 1.1 christos hresolve = (struct aout_link_hash_entry *) h->root.u.i.link; 4916 1.1 christos while (hresolve->root.type == bfd_link_hash_indirect 4917 1.1 christos || hresolve->root.type == bfd_link_hash_warning) 4918 1.1 christos hresolve = ((struct aout_link_hash_entry *) 4919 1.1 christos hresolve->root.u.i.link); 4920 1.1.1.9 christos *sym_hash = hresolve; 4921 1.1 christos } 4922 1.1 christos 4923 1.1 christos /* If the symbol has already been written out, skip it. */ 4924 1.1 christos if (h != NULL 4925 1.1 christos && h->written) 4926 1.1.1.9 christos { 4927 1.1 christos if ((type & N_TYPE) == N_INDR 4928 1.1 christos || type == N_WARNING) 4929 1.1 christos skip_next = true; 4930 1.1 christos *symbol_map = h->indx; 4931 1.1 christos continue; 4932 1.1 christos } 4933 1.1.1.9 christos 4934 1.1 christos /* See if we are stripping this symbol. */ 4935 1.1 christos skip = false; 4936 1.1.1.9 christos switch (strip) 4937 1.1 christos { 4938 1.1.1.9 christos case strip_none: 4939 1.1 christos break; 4940 1.1 christos case strip_debugger: 4941 1.1.1.9 christos if ((type & N_STAB) != 0) 4942 1.1 christos skip = true; 4943 1.1 christos break; 4944 1.1 christos case strip_some: 4945 1.1 christos if (bfd_hash_lookup (flaginfo->info->keep_hash, name, false, false) 4946 1.1 christos == NULL) 4947 1.1.1.9 christos skip = true; 4948 1.1 christos break; 4949 1.1 christos case strip_all: 4950 1.1 christos skip = true; 4951 1.1 christos break; 4952 1.1 christos } 4953 1.1 christos if (skip) 4954 1.1 christos { 4955 1.1 christos if (h != NULL) 4956 1.1 christos h->written = true; 4957 1.1 christos continue; 4958 1.1 christos } 4959 1.1 christos 4960 1.1 christos /* Get the value of the symbol. */ 4961 1.1 christos if ((type & N_TYPE) == N_TEXT 4962 1.1 christos || type == N_WEAKT) 4963 1.1 christos symsec = obj_textsec (input_bfd); 4964 1.1 christos else if ((type & N_TYPE) == N_DATA 4965 1.1 christos || type == N_WEAKD) 4966 1.1 christos symsec = obj_datasec (input_bfd); 4967 1.1 christos else if ((type & N_TYPE) == N_BSS 4968 1.1 christos || type == N_WEAKB) 4969 1.1 christos symsec = obj_bsssec (input_bfd); 4970 1.1 christos else if ((type & N_TYPE) == N_ABS 4971 1.1 christos || type == N_WEAKA) 4972 1.1 christos symsec = bfd_abs_section_ptr; 4973 1.1 christos else if (((type & N_TYPE) == N_INDR 4974 1.1 christos && (hresolve == NULL 4975 1.1 christos || (hresolve->root.type != bfd_link_hash_defined 4976 1.1.1.9 christos && hresolve->root.type != bfd_link_hash_defweak 4977 1.1 christos && hresolve->root.type != bfd_link_hash_common))) 4978 1.1 christos || type == N_WARNING) 4979 1.1 christos { 4980 1.1 christos /* Pass the next symbol through unchanged. The 4981 1.1 christos condition above for indirect symbols is so that if 4982 1.1 christos the indirect symbol was defined, we output it with 4983 1.1 christos the correct definition so the debugger will 4984 1.1 christos understand it. */ 4985 1.1 christos pass = true; 4986 1.1 christos val = GET_WORD (input_bfd, sym->e_value); 4987 1.1 christos symsec = NULL; 4988 1.1 christos } 4989 1.1 christos else if ((type & N_STAB) != 0) 4990 1.1 christos { 4991 1.1 christos val = GET_WORD (input_bfd, sym->e_value); 4992 1.1.1.9 christos symsec = NULL; 4993 1.1 christos } 4994 1.1 christos else 4995 1.1 christos { 4996 1.1 christos /* If we get here with an indirect symbol, it means that 4997 1.1 christos we are outputting it with a real definition. In such 4998 1.1 christos a case we do not want to output the next symbol, 4999 1.1 christos which is the target of the indirection. */ 5000 1.1 christos if ((type & N_TYPE) == N_INDR) 5001 1.1 christos skip_next = true; 5002 1.1 christos 5003 1.1 christos symsec = NULL; 5004 1.1 christos 5005 1.1 christos /* We need to get the value from the hash table. We use 5006 1.1 christos hresolve so that if we have defined an indirect 5007 1.1 christos symbol we output the final definition. */ 5008 1.1 christos if (h == NULL) 5009 1.1 christos { 5010 1.1 christos switch (type & N_TYPE) 5011 1.1 christos { 5012 1.1 christos case N_SETT: 5013 1.1 christos symsec = obj_textsec (input_bfd); 5014 1.1 christos break; 5015 1.1 christos case N_SETD: 5016 1.1 christos symsec = obj_datasec (input_bfd); 5017 1.1 christos break; 5018 1.1 christos case N_SETB: 5019 1.1 christos symsec = obj_bsssec (input_bfd); 5020 1.1 christos break; 5021 1.1 christos case N_SETA: 5022 1.1 christos symsec = bfd_abs_section_ptr; 5023 1.1 christos break; 5024 1.1 christos default: 5025 1.1 christos val = 0; 5026 1.1 christos break; 5027 1.1 christos } 5028 1.1 christos } 5029 1.1 christos else if (hresolve->root.type == bfd_link_hash_defined 5030 1.1 christos || hresolve->root.type == bfd_link_hash_defweak) 5031 1.1 christos { 5032 1.1 christos asection *input_section; 5033 1.1.1.8 christos asection *output_section; 5034 1.1 christos 5035 1.1 christos /* This case usually means a common symbol which was 5036 1.1 christos turned into a defined symbol. */ 5037 1.1 christos input_section = hresolve->root.u.def.section; 5038 1.1 christos output_section = input_section->output_section; 5039 1.1 christos BFD_ASSERT (bfd_is_abs_section (output_section) 5040 1.1 christos || output_section->owner == output_bfd); 5041 1.1 christos val = (hresolve->root.u.def.value 5042 1.1 christos + bfd_section_vma (output_section) 5043 1.1 christos + input_section->output_offset); 5044 1.1 christos 5045 1.1 christos /* Get the correct type based on the section. If 5046 1.1 christos this is a constructed set, force it to be 5047 1.1 christos globally visible. */ 5048 1.1 christos if (type == N_SETT 5049 1.1 christos || type == N_SETD 5050 1.1 christos || type == N_SETB 5051 1.1 christos || type == N_SETA) 5052 1.1 christos type |= N_EXT; 5053 1.1 christos 5054 1.1 christos type &=~ N_TYPE; 5055 1.1 christos 5056 1.1 christos if (output_section == obj_textsec (output_bfd)) 5057 1.1 christos type |= (hresolve->root.type == bfd_link_hash_defined 5058 1.1 christos ? N_TEXT 5059 1.1 christos : N_WEAKT); 5060 1.1 christos else if (output_section == obj_datasec (output_bfd)) 5061 1.1 christos type |= (hresolve->root.type == bfd_link_hash_defined 5062 1.1 christos ? N_DATA 5063 1.1 christos : N_WEAKD); 5064 1.1 christos else if (output_section == obj_bsssec (output_bfd)) 5065 1.1 christos type |= (hresolve->root.type == bfd_link_hash_defined 5066 1.1 christos ? N_BSS 5067 1.1 christos : N_WEAKB); 5068 1.1 christos else 5069 1.1 christos type |= (hresolve->root.type == bfd_link_hash_defined 5070 1.1 christos ? N_ABS 5071 1.1 christos : N_WEAKA); 5072 1.1 christos } 5073 1.1 christos else if (hresolve->root.type == bfd_link_hash_common) 5074 1.1 christos val = hresolve->root.u.c.size; 5075 1.1 christos else if (hresolve->root.type == bfd_link_hash_undefweak) 5076 1.1 christos { 5077 1.1 christos val = 0; 5078 1.1 christos type = N_WEAKU; 5079 1.1 christos } 5080 1.1 christos else 5081 1.1 christos val = 0; 5082 1.1 christos } 5083 1.1 christos if (symsec != NULL) 5084 1.1.1.9 christos val = (symsec->output_section->vma 5085 1.1 christos + symsec->output_offset 5086 1.1 christos + (GET_WORD (input_bfd, sym->e_value) 5087 1.1 christos - symsec->vma)); 5088 1.1 christos 5089 1.1 christos /* If this is a global symbol set the written flag, and if 5090 1.1 christos it is a local symbol see if we should discard it. */ 5091 1.1 christos if (h != NULL) 5092 1.1 christos { 5093 1.1 christos h->written = true; 5094 1.1 christos h->indx = obj_aout_external_sym_count (output_bfd); 5095 1.1 christos } 5096 1.1 christos else if ((type & N_TYPE) != N_SETT 5097 1.1 christos && (type & N_TYPE) != N_SETD 5098 1.1 christos && (type & N_TYPE) != N_SETB 5099 1.1 christos && (type & N_TYPE) != N_SETA) 5100 1.1.1.9 christos { 5101 1.1 christos switch (discard) 5102 1.1 christos { 5103 1.1.1.9 christos case discard_none: 5104 1.1 christos case discard_sec_merge: 5105 1.1 christos break; 5106 1.1 christos case discard_l: 5107 1.1 christos if ((type & N_STAB) == 0 5108 1.1.1.9 christos && bfd_is_local_label_name (input_bfd, name)) 5109 1.1 christos skip = true; 5110 1.1 christos break; 5111 1.1 christos case discard_all: 5112 1.1 christos skip = true; 5113 1.1 christos break; 5114 1.1 christos } 5115 1.1 christos if (skip) 5116 1.1 christos { 5117 1.1 christos pass = false; 5118 1.1 christos continue; 5119 1.1 christos } 5120 1.1 christos } 5121 1.1 christos 5122 1.1 christos /* An N_BINCL symbol indicates the start of the stabs 5123 1.1 christos entries for a header file. We need to scan ahead to the 5124 1.1 christos next N_EINCL symbol, ignoring nesting, adding up all the 5125 1.1 christos characters in the symbol names, not including the file 5126 1.1 christos numbers in types (the first number after an open 5127 1.1 christos parenthesis). */ 5128 1.1 christos if (type == (int) N_BINCL) 5129 1.1 christos { 5130 1.1 christos struct external_nlist *incl_sym; 5131 1.1 christos int nest; 5132 1.1 christos struct aout_link_includes_entry *incl_entry; 5133 1.1 christos struct aout_link_includes_totals *t; 5134 1.1 christos 5135 1.1 christos val = 0; 5136 1.1 christos nest = 0; 5137 1.1 christos for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++) 5138 1.1 christos { 5139 1.1 christos int incl_type; 5140 1.1 christos 5141 1.1 christos incl_type = H_GET_8 (input_bfd, incl_sym->e_type); 5142 1.1 christos if (incl_type == (int) N_EINCL) 5143 1.1 christos { 5144 1.1 christos if (nest == 0) 5145 1.1 christos break; 5146 1.1 christos --nest; 5147 1.1 christos } 5148 1.1 christos else if (incl_type == (int) N_BINCL) 5149 1.1 christos ++nest; 5150 1.1 christos else if (nest == 0) 5151 1.1 christos { 5152 1.1 christos const char *s; 5153 1.1 christos 5154 1.1 christos s = strings + GET_WORD (input_bfd, incl_sym->e_strx); 5155 1.1 christos for (; *s != '\0'; s++) 5156 1.1 christos { 5157 1.1 christos val += *s; 5158 1.1 christos if (*s == '(') 5159 1.1 christos { 5160 1.1 christos /* Skip the file number. */ 5161 1.1 christos ++s; 5162 1.1.1.7 christos while (ISDIGIT (*s)) 5163 1.1.1.7 christos ++s; 5164 1.1.1.9 christos --s; 5165 1.1.1.2 christos } 5166 1.1.1.9 christos } 5167 1.1 christos } 5168 1.1.1.9 christos } 5169 1.1 christos 5170 1.1 christos /* If we have already included a header file with the 5171 1.1 christos same value, then replace this one with an N_EXCL 5172 1.1 christos symbol. */ 5173 1.1 christos copy = !flaginfo->info->keep_memory; 5174 1.1 christos incl_entry = aout_link_includes_lookup (&flaginfo->includes, 5175 1.1.1.7 christos name, true, copy); 5176 1.1 christos if (incl_entry == NULL) 5177 1.1.1.7 christos return false; 5178 1.1 christos for (t = incl_entry->totals; t != NULL; t = t->next) 5179 1.1 christos if (t->total == val) 5180 1.1.1.9 christos break; 5181 1.1 christos if (t == NULL) 5182 1.1 christos { 5183 1.1 christos /* This is the first time we have seen this header 5184 1.1 christos file with this set of stabs strings. */ 5185 1.1 christos t = (struct aout_link_includes_totals *) 5186 1.1 christos bfd_hash_allocate (&flaginfo->includes.root, 5187 1.1 christos sizeof *t); 5188 1.1 christos if (t == NULL) 5189 1.1 christos return false; 5190 1.1.1.7 christos t->total = val; 5191 1.1.1.7 christos t->next = incl_entry->totals; 5192 1.1 christos incl_entry->totals = t; 5193 1.1 christos } 5194 1.1 christos else 5195 1.1 christos { 5196 1.1 christos int *incl_map; 5197 1.1 christos 5198 1.1 christos /* This is a duplicate header file. We must change 5199 1.1 christos it to be an N_EXCL entry, and mark all the 5200 1.1 christos included symbols to prevent outputting them. */ 5201 1.1 christos type = (int) N_EXCL; 5202 1.1 christos 5203 1.1 christos nest = 0; 5204 1.1 christos for (incl_sym = sym + 1, incl_map = symbol_map + 1; 5205 1.1 christos incl_sym < sym_end; 5206 1.1 christos incl_sym++, incl_map++) 5207 1.1 christos { 5208 1.1 christos int incl_type; 5209 1.1 christos 5210 1.1 christos incl_type = H_GET_8 (input_bfd, incl_sym->e_type); 5211 1.1 christos if (incl_type == (int) N_EINCL) 5212 1.1 christos { 5213 1.1 christos if (nest == 0) 5214 1.1 christos { 5215 1.1 christos *incl_map = -1; 5216 1.1 christos break; 5217 1.1 christos } 5218 1.1 christos --nest; 5219 1.1 christos } 5220 1.1 christos else if (incl_type == (int) N_BINCL) 5221 1.1 christos ++nest; 5222 1.1 christos else if (nest == 0) 5223 1.1 christos *incl_map = -1; 5224 1.1 christos } 5225 1.1.1.9 christos } 5226 1.1.1.2 christos } 5227 1.1 christos } 5228 1.1 christos 5229 1.1 christos /* Copy this symbol into the list of symbols we are going to 5230 1.1 christos write out. */ 5231 1.1 christos H_PUT_8 (output_bfd, type, outsym->e_type); 5232 1.1 christos H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other); 5233 1.1 christos H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc); 5234 1.1.1.9 christos copy = false; 5235 1.1 christos if (! flaginfo->info->keep_memory) 5236 1.1.1.2 christos { 5237 1.1 christos /* name points into a string table which we are going to 5238 1.1 christos free. If there is a hash table entry, use that string. 5239 1.1.1.9 christos Otherwise, copy name into memory. */ 5240 1.1 christos if (h != NULL) 5241 1.1 christos name = h->root.root.string; 5242 1.1 christos else 5243 1.1 christos copy = true; 5244 1.1 christos } 5245 1.1 christos strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab, 5246 1.1 christos name, copy); 5247 1.1 christos if (strtab_index == (bfd_size_type) -1) 5248 1.1.1.2 christos return false; 5249 1.1 christos PUT_WORD (output_bfd, strtab_index, outsym->e_strx); 5250 1.1 christos PUT_WORD (output_bfd, val, outsym->e_value); 5251 1.1 christos *symbol_map = obj_aout_external_sym_count (output_bfd); 5252 1.1.1.2 christos ++obj_aout_external_sym_count (output_bfd); 5253 1.1.1.9 christos ++outsym; 5254 1.1.1.2 christos } 5255 1.1 christos 5256 1.1.1.10 christos /* Write out the output symbols we have just constructed. */ 5257 1.1 christos if (outsym > flaginfo->output_syms) 5258 1.1.1.9 christos { 5259 1.1.1.2 christos bfd_size_type outsym_size; 5260 1.1 christos 5261 1.1 christos if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0) 5262 1.1.1.9 christos return false; 5263 1.1 christos outsym_size = outsym - flaginfo->output_syms; 5264 1.1 christos outsym_size *= EXTERNAL_NLIST_SIZE; 5265 1.1 christos if (bfd_write (flaginfo->output_syms, outsym_size, output_bfd) 5266 1.1 christos != outsym_size) 5267 1.1.1.9 christos return false; 5268 1.1.1.2 christos flaginfo->symoff += outsym_size; 5269 1.1 christos } 5270 1.1 christos 5271 1.1 christos return true; 5272 1.1 christos } 5273 1.1 christos 5274 1.1 christos /* Link an a.out input BFD into the output file. */ 5275 1.1 christos 5276 1.1.1.2 christos static bool 5277 1.1 christos aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd) 5278 1.1 christos { 5279 1.1.1.2 christos BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object); 5280 1.1 christos 5281 1.1.1.9 christos /* If this is a dynamic object, it may need special handling. */ 5282 1.1 christos if ((input_bfd->flags & DYNAMIC) != 0 5283 1.1 christos && aout_backend_info (input_bfd)->link_dynamic_object != NULL) 5284 1.1.1.2 christos return ((*aout_backend_info (input_bfd)->link_dynamic_object) 5285 1.1.1.2 christos (flaginfo->info, input_bfd)); 5286 1.1.1.9 christos 5287 1.1 christos /* Get the symbols. We probably have them already, unless 5288 1.1 christos flaginfo->info->keep_memory is FALSE. */ 5289 1.1 christos if (! aout_get_external_symbols (input_bfd)) 5290 1.1 christos return false; 5291 1.1 christos 5292 1.1 christos /* Write out the symbols and get a map of the new indices. The map 5293 1.1 christos is placed into flaginfo->symbol_map. */ 5294 1.1.1.2 christos if (! aout_link_write_symbols (flaginfo, input_bfd)) 5295 1.1 christos return false; 5296 1.1.1.2 christos 5297 1.1 christos /* Relocate and write out the sections. These functions use the 5298 1.1.1.9 christos symbol map created by aout_link_write_symbols. The linker_mark 5299 1.1 christos field will be set if these sections are to be included in the 5300 1.1 christos link, which will normally be the case. */ 5301 1.1 christos if (obj_textsec (input_bfd)->linker_mark) 5302 1.1.1.2 christos { 5303 1.1 christos if (! aout_link_input_section (flaginfo, input_bfd, 5304 1.1.1.2 christos obj_textsec (input_bfd), 5305 1.1 christos &flaginfo->treloff, 5306 1.1.1.9 christos exec_hdr (input_bfd)->a_trsize)) 5307 1.1 christos return false; 5308 1.1 christos } 5309 1.1 christos if (obj_datasec (input_bfd)->linker_mark) 5310 1.1 christos { 5311 1.1 christos if (! aout_link_input_section (flaginfo, input_bfd, 5312 1.1.1.2 christos obj_datasec (input_bfd), 5313 1.1 christos &flaginfo->dreloff, 5314 1.1 christos exec_hdr (input_bfd)->a_drsize)) 5315 1.1.1.9 christos return false; 5316 1.1 christos } 5317 1.1 christos 5318 1.1.1.9 christos /* If we are not keeping memory, we don't need the symbols any 5319 1.1 christos longer. We still need them if we are keeping memory, because the 5320 1.1 christos strings in the hash table point into them. */ 5321 1.1 christos if (! flaginfo->info->keep_memory) 5322 1.1 christos { 5323 1.1.1.3 christos if (! aout_link_free_symbols (input_bfd)) 5324 1.1 christos return false; 5325 1.1 christos } 5326 1.1 christos 5327 1.1 christos return true; 5328 1.1.1.9 christos } 5329 1.1 christos 5330 1.1 christos /* Do the final link step. This is called on the output BFD. The 5331 1.1 christos INFO structure should point to a list of BFDs linked through the 5332 1.1 christos link.next field which can be used to find each BFD which takes part 5333 1.1 christos in the output. Also, each section in ABFD should point to a list 5334 1.1.1.9 christos of bfd_link_order structures which list all the input sections for 5335 1.1 christos the output section. */ 5336 1.1 christos 5337 1.1 christos bool 5338 1.1 christos NAME (aout, final_link) (bfd *abfd, 5339 1.1 christos struct bfd_link_info *info, 5340 1.1 christos void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *)) 5341 1.1 christos { 5342 1.1.1.9 christos struct aout_final_link_info aout_info; 5343 1.1 christos bool includes_hash_initialized = false; 5344 1.1.1.5 christos bfd *sub; 5345 1.1 christos bfd_size_type trsize, drsize; 5346 1.1 christos bfd_size_type max_contents_size; 5347 1.1 christos bfd_size_type max_relocs_size; 5348 1.1 christos bfd_size_type max_sym_count; 5349 1.1 christos struct bfd_link_order *p; 5350 1.1 christos asection *o; 5351 1.1 christos bool have_link_order_relocs; 5352 1.1 christos 5353 1.1 christos if (bfd_link_pic (info)) 5354 1.1 christos abfd->flags |= DYNAMIC; 5355 1.1 christos 5356 1.1 christos aout_info.info = info; 5357 1.1 christos aout_info.output_bfd = abfd; 5358 1.1 christos aout_info.contents = NULL; 5359 1.1.1.9 christos aout_info.relocs = NULL; 5360 1.1 christos aout_info.symbol_map = NULL; 5361 1.1 christos aout_info.output_syms = NULL; 5362 1.1 christos 5363 1.1 christos if (!bfd_hash_table_init_n (&aout_info.includes.root, 5364 1.1 christos aout_link_includes_newfunc, 5365 1.1 christos sizeof (struct aout_link_includes_entry), 5366 1.1 christos 251)) 5367 1.1 christos goto error_return; 5368 1.1.1.3 christos includes_hash_initialized = true; 5369 1.1 christos 5370 1.1 christos /* Figure out the largest section size. Also, if generating 5371 1.1 christos relocatable output, count the relocs. */ 5372 1.1.1.5 christos trsize = 0; 5373 1.1 christos drsize = 0; 5374 1.1 christos max_contents_size = 0; 5375 1.1 christos max_relocs_size = 0; 5376 1.1 christos max_sym_count = 0; 5377 1.1 christos for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) 5378 1.1 christos { 5379 1.1 christos bfd_size_type sz; 5380 1.1 christos 5381 1.1 christos if (bfd_link_relocatable (info)) 5382 1.1 christos { 5383 1.1 christos if (bfd_get_flavour (sub) == bfd_target_aout_flavour) 5384 1.1 christos { 5385 1.1.1.6 christos trsize += exec_hdr (sub)->a_trsize; 5386 1.1.1.6 christos drsize += exec_hdr (sub)->a_drsize; 5387 1.1.1.7 christos } 5388 1.1.1.6 christos else 5389 1.1 christos { 5390 1.1 christos /* FIXME: We need to identify the .text and .data sections 5391 1.1 christos and call get_reloc_upper_bound and canonicalize_reloc to 5392 1.1 christos work out the number of relocs needed, and then multiply 5393 1.1 christos by the reloc size. */ 5394 1.1 christos _bfd_error_handler 5395 1.1 christos /* xgettext:c-format */ 5396 1.1 christos (_("%pB: relocatable link from %s to %s not supported"), 5397 1.1 christos abfd, sub->xvec->name, abfd->xvec->name); 5398 1.1 christos bfd_set_error (bfd_error_invalid_operation); 5399 1.1 christos goto error_return; 5400 1.1 christos } 5401 1.1 christos } 5402 1.1 christos 5403 1.1 christos if (bfd_get_flavour (sub) == bfd_target_aout_flavour) 5404 1.1 christos { 5405 1.1 christos sz = obj_textsec (sub)->size; 5406 1.1 christos if (sz > max_contents_size) 5407 1.1 christos max_contents_size = sz; 5408 1.1 christos sz = obj_datasec (sub)->size; 5409 1.1 christos if (sz > max_contents_size) 5410 1.1 christos max_contents_size = sz; 5411 1.1 christos 5412 1.1 christos sz = exec_hdr (sub)->a_trsize; 5413 1.1 christos if (sz > max_relocs_size) 5414 1.1 christos max_relocs_size = sz; 5415 1.1 christos sz = exec_hdr (sub)->a_drsize; 5416 1.1.1.5 christos if (sz > max_relocs_size) 5417 1.1 christos max_relocs_size = sz; 5418 1.1 christos 5419 1.1 christos sz = obj_aout_external_sym_count (sub); 5420 1.1 christos if (sz > max_sym_count) 5421 1.1 christos max_sym_count = sz; 5422 1.1 christos } 5423 1.1 christos } 5424 1.1 christos 5425 1.1 christos if (bfd_link_relocatable (info)) 5426 1.1 christos { 5427 1.1 christos if (obj_textsec (abfd) != NULL) 5428 1.1 christos trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd) 5429 1.1 christos ->map_head.link_order) 5430 1.1 christos * obj_reloc_entry_size (abfd)); 5431 1.1 christos if (obj_datasec (abfd) != NULL) 5432 1.1 christos drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd) 5433 1.1 christos ->map_head.link_order) 5434 1.1 christos * obj_reloc_entry_size (abfd)); 5435 1.1 christos } 5436 1.1.1.5 christos 5437 1.1 christos exec_hdr (abfd)->a_trsize = trsize; 5438 1.1 christos exec_hdr (abfd)->a_drsize = drsize; 5439 1.1 christos 5440 1.1 christos exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); 5441 1.1 christos 5442 1.1 christos /* Adjust the section sizes and vmas according to the magic number. 5443 1.1 christos This sets a_text, a_data and a_bss in the exec_hdr and sets the 5444 1.1 christos filepos for each section. */ 5445 1.1.1.7 christos if (! NAME (aout, adjust_sizes_and_vmas) (abfd)) 5446 1.1 christos goto error_return; 5447 1.1 christos 5448 1.1 christos /* The relocation and symbol file positions differ among a.out 5449 1.1 christos targets. We are passed a callback routine from the backend 5450 1.1 christos specific code to handle this. 5451 1.1 christos FIXME: At this point we do not know how much space the symbol 5452 1.1 christos table will require. This will not work for any (nonstandard) 5453 1.1 christos a.out target that needs to know the symbol table size before it 5454 1.1 christos can compute the relocation file positions. */ 5455 1.1 christos (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff, 5456 1.1 christos &aout_info.symoff); 5457 1.1 christos obj_textsec (abfd)->rel_filepos = aout_info.treloff; 5458 1.1 christos obj_datasec (abfd)->rel_filepos = aout_info.dreloff; 5459 1.1 christos obj_sym_filepos (abfd) = aout_info.symoff; 5460 1.1 christos 5461 1.1 christos /* We keep a count of the symbols as we output them. */ 5462 1.1 christos obj_aout_external_sym_count (abfd) = 0; 5463 1.1 christos 5464 1.1 christos /* We accumulate the string table as we write out the symbols. */ 5465 1.1 christos aout_info.strtab = _bfd_stringtab_init (); 5466 1.1 christos if (aout_info.strtab == NULL) 5467 1.1 christos goto error_return; 5468 1.1 christos 5469 1.1 christos /* Allocate buffers to hold section contents and relocs. */ 5470 1.1 christos aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size); 5471 1.1 christos aout_info.relocs = bfd_malloc (max_relocs_size); 5472 1.1 christos aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int)); 5473 1.1 christos aout_info.output_syms = (struct external_nlist *) 5474 1.1 christos bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist)); 5475 1.1 christos if ((aout_info.contents == NULL && max_contents_size != 0) 5476 1.1 christos || (aout_info.relocs == NULL && max_relocs_size != 0) 5477 1.1 christos || (aout_info.symbol_map == NULL && max_sym_count != 0) 5478 1.1 christos || aout_info.output_syms == NULL) 5479 1.1 christos goto error_return; 5480 1.1.1.9 christos 5481 1.1 christos /* If we have a symbol named __DYNAMIC, force it out now. This is 5482 1.1.1.2 christos required by SunOS. Doing this here rather than in sunos.c is a 5483 1.1 christos hack, but it's easier than exporting everything which would be 5484 1.1 christos needed. */ 5485 1.1 christos { 5486 1.1 christos struct aout_link_hash_entry *h; 5487 1.1 christos 5488 1.1 christos h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC", 5489 1.1 christos false, false, false); 5490 1.1 christos if (h != NULL) 5491 1.1 christos aout_link_write_other_symbol (&h->root.root, &aout_info); 5492 1.1 christos } 5493 1.1 christos 5494 1.1 christos /* The most time efficient way to do the link would be to read all 5495 1.1 christos the input object files into memory and then sort out the 5496 1.1 christos information into the output file. Unfortunately, that will 5497 1.1 christos probably use too much memory. Another method would be to step 5498 1.1 christos through everything that composes the text section and write it 5499 1.1 christos out, and then everything that composes the data section and write 5500 1.1 christos it out, and then write out the relocs, and then write out the 5501 1.1 christos symbols. Unfortunately, that requires reading stuff from each 5502 1.1 christos input file several times, and we will not be able to keep all the 5503 1.1 christos input files open simultaneously, and reopening them will be slow. 5504 1.1 christos 5505 1.1 christos What we do is basically process one input file at a time. We do 5506 1.1.1.3 christos everything we need to do with an input file once--copy over the 5507 1.1.1.9 christos section contents, handle the relocation information, and write 5508 1.1 christos out the symbols--and then we throw away the information we read 5509 1.1 christos from it. This approach requires a lot of lseeks of the output 5510 1.1 christos file, which is unfortunate but still faster than reopening a lot 5511 1.1 christos of files. 5512 1.1 christos 5513 1.1 christos We use the output_has_begun field of the input BFDs to see 5514 1.1 christos whether we have already handled it. */ 5515 1.1 christos for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) 5516 1.1 christos sub->output_has_begun = false; 5517 1.1.1.9 christos 5518 1.1 christos /* Mark all sections which are to be included in the link. This 5519 1.1 christos will normally be every section. We need to do this so that we 5520 1.1.1.9 christos can identify any sections which the linker has decided to not 5521 1.1 christos include. */ 5522 1.1 christos for (o = abfd->sections; o != NULL; o = o->next) 5523 1.1 christos { 5524 1.1 christos for (p = o->map_head.link_order; p != NULL; p = p->next) 5525 1.1 christos if (p->type == bfd_indirect_link_order) 5526 1.1 christos p->u.indirect.section->linker_mark = true; 5527 1.1 christos } 5528 1.1 christos 5529 1.1 christos have_link_order_relocs = false; 5530 1.1 christos for (o = abfd->sections; o != NULL; o = o->next) 5531 1.1 christos { 5532 1.1 christos for (p = o->map_head.link_order; 5533 1.1 christos p != NULL; 5534 1.1 christos p = p->next) 5535 1.1 christos { 5536 1.1 christos if (p->type == bfd_indirect_link_order 5537 1.1 christos && (bfd_get_flavour (p->u.indirect.section->owner) 5538 1.1.1.9 christos == bfd_target_aout_flavour)) 5539 1.1 christos { 5540 1.1 christos bfd *input_bfd; 5541 1.1 christos 5542 1.1 christos input_bfd = p->u.indirect.section->owner; 5543 1.1 christos if (! input_bfd->output_has_begun) 5544 1.1 christos { 5545 1.1.1.9 christos if (! aout_link_input_bfd (&aout_info, input_bfd)) 5546 1.1 christos goto error_return; 5547 1.1 christos input_bfd->output_has_begun = true; 5548 1.1 christos } 5549 1.1 christos } 5550 1.1 christos else if (p->type == bfd_section_reloc_link_order 5551 1.1 christos || p->type == bfd_symbol_reloc_link_order) 5552 1.1 christos { 5553 1.1 christos /* These are handled below. */ 5554 1.1 christos have_link_order_relocs = true; 5555 1.1 christos } 5556 1.1.1.2 christos else 5557 1.1.1.2 christos { 5558 1.1.1.2 christos if (! _bfd_default_link_order (abfd, info, o, p)) 5559 1.1 christos goto error_return; 5560 1.1 christos } 5561 1.1 christos } 5562 1.1 christos } 5563 1.1 christos 5564 1.1 christos /* Write out any symbols that we have not already written out. */ 5565 1.1 christos bfd_hash_traverse (&info->hash->table, 5566 1.1 christos aout_link_write_other_symbol, 5567 1.1 christos &aout_info); 5568 1.1 christos 5569 1.1 christos /* Now handle any relocs we were asked to create by the linker. 5570 1.1 christos These did not come from any input file. We must do these after 5571 1.1 christos we have written out all the symbols, so that we know the symbol 5572 1.1 christos indices to use. */ 5573 1.1 christos if (have_link_order_relocs) 5574 1.1 christos { 5575 1.1 christos for (o = abfd->sections; o != NULL; o = o->next) 5576 1.1 christos { 5577 1.1 christos for (p = o->map_head.link_order; 5578 1.1 christos p != NULL; 5579 1.1 christos p = p->next) 5580 1.1 christos { 5581 1.1 christos if (p->type == bfd_section_reloc_link_order 5582 1.1.1.8 christos || p->type == bfd_symbol_reloc_link_order) 5583 1.1.1.8 christos { 5584 1.1.1.8 christos if (! aout_link_reloc_link_order (&aout_info, o, p)) 5585 1.1.1.8 christos goto error_return; 5586 1.1.1.8 christos } 5587 1.1.1.8 christos } 5588 1.1.1.8 christos } 5589 1.1.1.8 christos } 5590 1.1.1.8 christos 5591 1.1 christos free (aout_info.contents); 5592 1.1 christos aout_info.contents = NULL; 5593 1.1 christos free (aout_info.relocs); 5594 1.1.1.9 christos aout_info.relocs = NULL; 5595 1.1 christos free (aout_info.symbol_map); 5596 1.1 christos aout_info.symbol_map = NULL; 5597 1.1 christos free (aout_info.output_syms); 5598 1.1 christos aout_info.output_syms = NULL; 5599 1.1 christos 5600 1.1 christos if (includes_hash_initialized) 5601 1.1 christos { 5602 1.1 christos bfd_hash_table_free (&aout_info.includes.root); 5603 1.1 christos includes_hash_initialized = false; 5604 1.1 christos } 5605 1.1 christos 5606 1.1 christos /* Finish up any dynamic linking we may be doing. */ 5607 1.1 christos if (aout_backend_info (abfd)->finish_dynamic_link != NULL) 5608 1.1 christos { 5609 1.1 christos if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info)) 5610 1.1 christos goto error_return; 5611 1.1 christos } 5612 1.1 christos 5613 1.1 christos /* Update the header information. */ 5614 1.1 christos abfd->symcount = obj_aout_external_sym_count (abfd); 5615 1.1 christos exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE; 5616 1.1 christos obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms; 5617 1.1 christos obj_textsec (abfd)->reloc_count = 5618 1.1 christos exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd); 5619 1.1 christos obj_datasec (abfd)->reloc_count = 5620 1.1 christos exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd); 5621 1.1 christos 5622 1.1 christos /* Write out the string table, unless there are no symbols. */ 5623 1.1 christos if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0) 5624 1.1 christos goto error_return; 5625 1.1 christos if (abfd->symcount > 0) 5626 1.1.1.10 christos { 5627 1.1 christos if (!emit_stringtab (abfd, aout_info.strtab)) 5628 1.1 christos goto error_return; 5629 1.1 christos } 5630 1.1.1.9 christos else 5631 1.1 christos { 5632 1.1 christos bfd_byte b[BYTES_IN_WORD]; 5633 1.1.1.8 christos 5634 1.1.1.8 christos memset (b, 0, BYTES_IN_WORD); 5635 1.1.1.8 christos if (bfd_write (b, BYTES_IN_WORD, abfd) != BYTES_IN_WORD) 5636 1.1.1.8 christos goto error_return; 5637 1.1 christos } 5638 1.1 christos 5639 1.1.1.9 christos return true; 5640 1.1 christos 5641 error_return: 5642 free (aout_info.contents); 5643 free (aout_info.relocs); 5644 free (aout_info.symbol_map); 5645 free (aout_info.output_syms); 5646 if (includes_hash_initialized) 5647 bfd_hash_table_free (&aout_info.includes.root); 5648 return false; 5649 } 5650