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