source: trunk/src/binutils/bfd/i386aoutemx.c@ 1254

Last change on this file since 1254 was 1248, checked in by bird, 22 years ago

#905: Do relocations more like ELF, ensuring we relocate to a symbol for externals & weaks.

  • Property cvs2svn:cvs-rev set to 1.5
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* BFD back-end for emx a.out binaries, derived from i386aout.c and aout-target.h
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "sysdep.h"
21#ifdef TRAD_HEADER
22#include TRAD_HEADER
23#endif
24#include "bfd.h"
25#include "libbfd.h"
26#ifndef EMX
27#error "EMX TARGET! EMX isn't defined!!!"
28#endif
29
30#include <symcat.h>
31#define MY_object_p MY(object_p)
32#define MY_backend_data &MY(backend_data)
33#define MY_bfd_reloc_type_lookup i386aout_emx_reloc_type_lookup
34
35#include "libaout.h"
36#include "aout/aout64.h"
37
38static bfd_boolean MY(set_sizes) PARAMS ((bfd *));
39const bfd_target * MY(object_p) PARAMS ((bfd *));
40reloc_howto_type * MY(reloc_type_lookup) PARAMS ((bfd *, bfd_reloc_code_real_type));
41bfd_reloc_status_type MY(generic_reloc) PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42/*reloc_howto_type * MY(reloc_howto) PARAMS ((bfd *, struct reloc_std_external *, int *, int *, int *));*/
43
44reloc_howto_type MY(howto_table_std)[] =
45{
46 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone. */
47HOWTO ( 0, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"8", TRUE, 0x000000ff,0x000000ff, FALSE),
48HOWTO ( 1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
49HOWTO ( 2, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"32", TRUE, 0xffffffff,0xffffffff, FALSE),
50HOWTO ( 3, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"64", TRUE, 0xdeaddead,0xdeaddead, FALSE),
51HOWTO ( 4, 0, 0, 8, TRUE, 0, complain_overflow_signed, MY(generic_reloc),"DISP8", TRUE, 0x000000ff,0x000000ff, FALSE),
52HOWTO ( 5, 0, 1, 16, TRUE, 0, complain_overflow_signed, MY(generic_reloc),"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
53HOWTO ( 6, 0, 2, 32, TRUE, 0, complain_overflow_signed, MY(generic_reloc),"DISP32", TRUE, 0xffffffff,0xffffffff, FALSE),
54HOWTO ( 7, 0, 4, 64, TRUE, 0, complain_overflow_signed, MY(generic_reloc),"DISP64", TRUE, 0xfeedface,0xfeedface, FALSE),
55HOWTO ( 8, 0, 2, 0, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"GOT_REL", FALSE, 0,0x00000000, FALSE),
56HOWTO ( 9, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"BASE16", FALSE,0xffffffff,0xffffffff, FALSE),
57HOWTO (10, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"BASE32", FALSE,0xffffffff,0xffffffff, FALSE),
58EMPTY_HOWTO (-1),
59EMPTY_HOWTO (-1),
60EMPTY_HOWTO (-1),
61EMPTY_HOWTO (-1),
62EMPTY_HOWTO (-1),
63 HOWTO (16, 0, 2, 0, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"JMP_TABLE", FALSE, 0,0x00000000, FALSE),
64EMPTY_HOWTO (-1),
65EMPTY_HOWTO (-1),
66EMPTY_HOWTO (-1),
67EMPTY_HOWTO (-1),
68EMPTY_HOWTO (-1),
69EMPTY_HOWTO (-1),
70EMPTY_HOWTO (-1),
71EMPTY_HOWTO (-1),
72EMPTY_HOWTO (-1),
73EMPTY_HOWTO (-1),
74EMPTY_HOWTO (-1),
75EMPTY_HOWTO (-1),
76EMPTY_HOWTO (-1),
77EMPTY_HOWTO (-1),
78EMPTY_HOWTO (-1),
79 HOWTO (32, 0, 2, 0, FALSE, 0, complain_overflow_bitfield, MY(generic_reloc),"RELATIVE", FALSE, 0,0x00000000, FALSE),
80EMPTY_HOWTO (-1),
81EMPTY_HOWTO (-1),
82EMPTY_HOWTO (-1),
83EMPTY_HOWTO (-1),
84EMPTY_HOWTO (-1),
85EMPTY_HOWTO (-1),
86EMPTY_HOWTO (-1),
87 HOWTO (40, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"BASEREL", FALSE, 0,0x00000000, FALSE),
88};
89
90
91CONST struct aout_backend_data MY(backend_data) = {
92 0, /* zmagic contiguous */
93 0, /* text incl header */
94 0, /* entry is text address */
95 0, /* exec_hdr_flags */
96 0, /* text vma? */
97 MY(set_sizes),
98 1, /* exec header not counted */
99 0, /* add_dynamic_symbols */
100 0, /* add_one_symbol */
101 0, /* link_dynamic_object */
102 0, /* write_dynamic_symbol */
103 0, /* check_dynamic_reloc */
104 0 /* finish_dynamic_link */
105};
106
107#include "aout-target.h"
108
109#ifndef __EMX__
110
111/* Cross-compilation support, borrowed from EMX C runtime library */
112int _fseek_hdr PARAMS ((FILE *));
113
114int _fseek_hdr (FILE *stream)
115{
116 struct
117 {
118 char magic[2];
119 char fill1[6];
120 unsigned short hdr_size;
121 } exe_hdr;
122 struct
123 {
124 char sig[16];
125 char bound;
126 char fill1;
127 unsigned short hdr_loc_lo; /* cannot use long, alignment! */
128 unsigned short hdr_loc_hi;
129 } patch;
130 long original_pos;
131 int saved_errno;
132
133 original_pos = ftell (stream);
134 if (fread (&exe_hdr, sizeof (exe_hdr), 1, stream) != 1)
135 goto failure;
136 if (memcmp (exe_hdr.magic, "MZ", 2) != 0)
137 return (fseek (stream, original_pos, SEEK_SET) == -1 ? -1 : 0);
138 if (fseek (stream, original_pos + 16 * exe_hdr.hdr_size, SEEK_SET) == -1)
139 goto failure;
140 if (fread (&patch, sizeof (patch), 1, stream) != 1)
141 goto failure;
142 if (memcmp (patch.sig, "emx", 3) != 0)
143 goto failure;
144 if (fseek (stream, original_pos + patch.hdr_loc_lo
145 + 65536L * patch.hdr_loc_hi, SEEK_SET) == -1)
146 goto failure;
147 return 0;
148
149failure:
150 saved_errno = errno;
151 fseek (stream, original_pos, SEEK_SET);
152 errno = saved_errno;
153 return -1;
154}
155#endif
156
157
158/*
159 * Finish up the reading of an a.out file header
160 */
161const bfd_target *
162MY(object_p) (abfd)
163 bfd *abfd;
164{
165 struct external_exec exec_bytes; /* Raw exec header from file */
166 struct internal_exec exec; /* Cleaned-up exec header */
167 const bfd_target *target;
168 size_t org_pos, add;
169
170 org_pos = bfd_tell (abfd);
171 (void)_fseek_hdr(bfd_cache_lookup(abfd));
172 add = bfd_tell (abfd) - org_pos;
173
174 if (bfd_bread ((PTR) &exec_bytes, EXEC_BYTES_SIZE, abfd)
175 != EXEC_BYTES_SIZE)
176 {
177 if (bfd_get_error () != bfd_error_system_call)
178 bfd_set_error (bfd_error_wrong_format);
179 return 0;
180 }
181
182 exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
183
184 if (N_BADMAG (exec))
185 return 0;
186
187 NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
188 exec.a_hdrofs = add;
189 target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
190 return target;
191}
192
193
194reloc_howto_type *
195MY(reloc_type_lookup) (abfd,code)
196 bfd *abfd;
197 bfd_reloc_code_real_type code;
198{
199#define STD(i, j) case i: return &MY(howto_table_std)[j]
200
201 if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
202 return NAME(aout,reloc_type_lookup) (abfd, code);
203
204
205 if (code == BFD_RELOC_CTOR)
206 switch (bfd_get_arch_info (abfd)->bits_per_address)
207 {
208 case 32:
209 code = BFD_RELOC_32;
210 break;
211 case 64:
212 code = BFD_RELOC_64;
213 break;
214 }
215
216 /* std relocs. */
217 switch (code)
218 {
219 STD (BFD_RELOC_8, 0);
220 STD (BFD_RELOC_16, 1);
221 STD (BFD_RELOC_32, 2);
222 STD (BFD_RELOC_8_PCREL, 4);
223 STD (BFD_RELOC_16_PCREL, 5);
224 STD (BFD_RELOC_32_PCREL, 6);
225 STD (BFD_RELOC_16_BASEREL, 9);
226 STD (BFD_RELOC_32_BASEREL, 10);
227 default: return (reloc_howto_type *) NULL;
228 }
229}
230
231/* ELF relocs are against symbols. If we are producing relocateable
232 output, and the reloc is against an external symbol, and nothing
233 has given us any additional addend, the resulting reloc will also
234 be against the same symbol. In such a case, we don't want to
235 change anything about the way the reloc is handled, since it will
236 all be done at final link time. Rather than put special case code
237 into bfd_perform_relocation, all the reloc types use this howto
238 function. It just short circuits the reloc if producing
239 relocateable output against an external symbol. */
240
241bfd_reloc_status_type
242MY(generic_reloc) (abfd,
243 reloc_entry,
244 symbol,
245 data,
246 input_section,
247 output_bfd,
248 error_message)
249 bfd *abfd ATTRIBUTE_UNUSED;
250 arelent *reloc_entry;
251 asymbol *symbol;
252 PTR data ATTRIBUTE_UNUSED;
253 asection *input_section;
254 bfd *output_bfd;
255 char **error_message ATTRIBUTE_UNUSED;
256{
257 if (output_bfd != (bfd *) NULL
258 && (symbol->flags & BSF_SECTION_SYM) == 0
259 && (! reloc_entry->howto->partial_inplace
260 || reloc_entry->addend == 0))
261 {
262 reloc_entry->address += input_section->output_offset;
263 return bfd_reloc_ok;
264 }
265
266 return bfd_reloc_continue;
267}
268
Note: See TracBrowser for help on using the repository browser.