No empty .Rs/.Re
[netbsd-mini2440.git] / libexec / ld.aout_so / arch / i386 / md.c
blob0cbeff0a645cbf594983e301578a30a96e6079c0
1 /* $NetBSD: md.c,v 1.17 1998/12/17 20:14:44 pk Exp $ */
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Paul Kranenburg.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/param.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <err.h>
37 #include <fcntl.h>
38 #include <a.out.h>
39 #include <stab.h>
40 #include <string.h>
42 #include "ld.h"
43 #ifndef RTLD
44 /* Pull in the ld(1) bits as well */
45 #include "ld_i.h"
46 #endif
49 * Get relocation addend corresponding to relocation record RP
50 * from address ADDR
52 long
53 md_get_addend(rp, addr)
54 struct relocation_info *rp;
55 unsigned char *addr;
57 switch (RELOC_TARGET_SIZE(rp)) {
58 case 0:
59 return get_byte(addr);
60 case 1:
61 return get_short(addr);
62 case 2:
63 return get_long(addr);
64 default:
65 errx(1, "Unsupported relocation size: %x",
66 RELOC_TARGET_SIZE(rp));
71 * Put RELOCATION at ADDR according to relocation record RP.
73 void
74 md_relocate(rp, relocation, addr, relocatable_output)
75 struct relocation_info *rp;
76 long relocation;
77 unsigned char *addr;
78 int relocatable_output;
80 switch (RELOC_TARGET_SIZE(rp)) {
81 case 0:
82 put_byte(addr, relocation);
83 break;
84 case 1:
85 put_short(addr, relocation);
86 break;
87 case 2:
88 put_long(addr, relocation);
89 break;
90 default:
91 errx(1, "Unsupported relocation size: %x",
92 RELOC_TARGET_SIZE(rp));
96 void
97 md_set_breakpoint(where, savep)
98 long where;
99 long *savep;
101 *savep = *(long *)where;
102 *(char *)where = TRAP;
106 * Set up a "direct" transfer (ie. not through the run-time binder) from
107 * jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
108 * and by `ld.so' after resolving the symbol.
109 * On the i386, we use the JMP instruction which is PC relative, so no
110 * further RRS relocations will be necessary for such a jmpslot.
112 void
113 md_fix_jmpslot(sp, offset, addr, first)
114 jmpslot_t *sp;
115 long offset;
116 u_long addr;
117 int first;
119 u_long fudge = addr - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
121 sp->opcode = JUMP;
122 #if 0
123 sp->addr = fudge;
124 #else
125 sp->addr[0] = fudge & 0xffff;
126 sp->addr[1] = fudge >> 16;
127 #endif
128 #if 0
129 sp->reloc_index = 0;
130 #endif
133 #ifndef RTLD
135 * Machine dependent part of claim_rrs_reloc().
136 * Set RRS relocation type.
139 md_make_reloc(rp, r, type)
140 struct relocation_info *rp, *r;
141 int type;
143 /* Relocation size */
144 r->r_length = rp->r_length;
146 if (RELOC_PCREL_P(rp))
147 r->r_pcrel = 1;
149 if (type & RELTYPE_RELATIVE)
150 r->r_relative = 1;
152 if (type & RELTYPE_COPY)
153 r->r_copy = 1;
155 return 0;
159 * Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
160 * to the binder slot (which is at offset 0 of the PLT).
162 void
163 md_make_jmpslot(sp, offset, index)
164 jmpslot_t *sp;
165 long offset;
166 long index;
169 * i386 PC-relative "fixed point" is located right after the
170 * instruction it pertains to.
172 u_long fudge = - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
174 sp->opcode = CALL;
175 #if 0
176 sp->addr = fudge;
177 #else
178 sp->addr[0] = fudge & 0xffff;
179 sp->addr[1] = fudge >> 16;
180 #endif
181 sp->reloc_index = index;
185 * Update the relocation record for a RRS jmpslot.
187 void
188 md_make_jmpreloc(rp, r, type)
189 struct relocation_info *rp, *r;
190 int type;
192 jmpslot_t *sp;
195 * Fix relocation address to point to the correct
196 * location within this jmpslot.
198 r->r_address += sizeof(sp->opcode);
200 /* Relocation size */
201 r->r_length = 2;
203 /* Set relocation type */
204 r->r_jmptable = 1;
205 if (type & RELTYPE_RELATIVE)
206 r->r_relative = 1;
211 * Set relocation type for a RRS GOT relocation.
213 void
214 md_make_gotreloc(rp, r, type)
215 struct relocation_info *rp, *r;
216 int type;
218 r->r_baserel = 1;
219 if (type & RELTYPE_RELATIVE)
220 r->r_relative = 1;
222 /* Relocation size */
223 r->r_length = 2;
227 * Set relocation type for a RRS copy operation.
229 void
230 md_make_cpyreloc(rp, r)
231 struct relocation_info *rp, *r;
233 /* Relocation size */
234 r->r_length = 2;
236 r->r_copy = 1;
239 #ifdef __FreeBSD__
240 int netzmagic;
241 #endif
244 * Initialize (output) exec header such that useful values are
245 * obtained from subsequent N_*() macro evaluations.
247 void
248 md_init_header(hp, magic, flags)
249 struct exec *hp;
250 int magic, flags;
252 #ifdef __NetBSD__
253 if (oldmagic || magic == QMAGIC)
254 hp->a_midmag = magic;
255 else
256 N_SETMAGIC((*hp), magic, MID_I386, flags);
257 #endif
258 #ifdef __FreeBSD__
259 if (oldmagic)
260 hp->a_midmag = magic;
261 else if (netzmagic)
262 N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
263 else
264 N_SETMAGIC((*hp), magic, MID_I386, flags);
265 #endif
267 /* TEXT_START depends on the value of outheader.a_entry. */
268 if (!(link_mode & SHAREABLE))
269 hp->a_entry = PAGSIZ;
271 #endif /* RTLD */
274 #ifdef NEED_SWAP
276 * Byte swap routines for cross-linking.
279 void
280 md_swapin_exec_hdr(h)
281 struct exec *h;
283 int skip = 0;
285 if (!N_BADMAG(*h))
286 skip = 1;
288 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
291 void
292 md_swapout_exec_hdr(h)
293 struct exec *h;
295 /* NetBSD: Always leave magic alone */
296 int skip = 1;
297 #if 0
298 if (N_GETMAGIC(*h) == OMAGIC)
299 skip = 0;
300 #endif
302 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
306 void
307 md_swapin_reloc(r, n)
308 struct relocation_info *r;
309 int n;
311 int bits;
313 for (; n; n--, r++) {
314 r->r_address = md_swap_long(r->r_address);
315 bits = ((int *)r)[1];
316 r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
317 r->r_pcrel = (bits & 1);
318 r->r_length = (bits >> 1) & 3;
319 r->r_extern = (bits >> 3) & 1;
320 r->r_baserel = (bits >> 4) & 1;
321 r->r_jmptable = (bits >> 5) & 1;
322 r->r_relative = (bits >> 6) & 1;
323 #ifdef N_SIZE
324 r->r_copy = (bits >> 7) & 1;
325 #endif
329 void
330 md_swapout_reloc(r, n)
331 struct relocation_info *r;
332 int n;
334 int bits;
336 for (; n; n--, r++) {
337 r->r_address = md_swap_long(r->r_address);
338 bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
339 bits |= (r->r_pcrel & 1);
340 bits |= (r->r_length & 3) << 1;
341 bits |= (r->r_extern & 1) << 3;
342 bits |= (r->r_baserel & 1) << 4;
343 bits |= (r->r_jmptable & 1) << 5;
344 bits |= (r->r_relative & 1) << 6;
345 #ifdef N_SIZE
346 bits |= (r->r_copy & 1) << 7;
347 #endif
348 ((int *)r)[1] = bits;
352 void
353 md_swapout_jmpslot(j, n)
354 jmpslot_t *j;
355 int n;
357 for (; n; n--, j++) {
358 j->opcode = md_swap_short(j->opcode);
359 j->addr[0] = md_swap_short(j->addr[0]);
360 j->addr[1] = md_swap_short(j->addr[1]);
361 j->reloc_index = md_swap_short(j->reloc_index);
364 #endif /* NEED_SWAP */