No empty .Rs/.Re
[netbsd-mini2440.git] / libexec / ld.aout_so / arch / vax / md.c
blob9337c3b6870df4708955a0bdf756f24bb700cb00
1 /* $NetBSD: md.c,v 1.15 1999/06/28 17:28:56 ragge 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 <stddef.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <err.h>
38 #include <fcntl.h>
39 #include <a.out.h>
40 #include <stab.h>
41 #include <string.h>
43 #include "ld.h"
44 #ifndef RTLD
45 /* Pull in the ld(1) bits as well */
46 #include "ld_i.h"
47 #endif
50 * Get relocation addend corresponding to relocation record RP
51 * from address ADDR
53 long
54 md_get_addend(rp, addr)
55 struct relocation_info *rp;
56 unsigned char *addr;
58 switch (RELOC_TARGET_SIZE(rp)) {
59 case 0:
60 return get_byte(addr);
61 case 1:
62 return get_short(addr);
63 case 2:
64 if (rp->r_baserel) {
65 long addend = get_long(addr);
66 if (rp->r_pcrel) {
67 addend += rp->r_address + 4;
68 if (addend)
69 put_long(addr, -(rp->r_address+4));
71 return addend;
73 return get_long(addr);
74 default:
75 errx(1, "Unsupported relocation size: %x",
76 RELOC_TARGET_SIZE(rp));
81 * Put RELOCATION at ADDR according to relocation record RP.
83 void
84 md_relocate(rp, relocation, addr, relocatable_output)
85 struct relocation_info *rp;
86 long relocation;
87 unsigned char *addr;
88 int relocatable_output;
90 switch (RELOC_TARGET_SIZE(rp)) {
91 case 0:
92 put_byte(addr, relocation);
93 break;
94 case 1:
95 put_short(addr, relocation);
96 break;
97 case 2:
98 #ifndef RTLD
99 if (rp->r_baserel) {
100 relocation += got_symbol->value + get_long(addr);
101 if (rp->r_copy)
102 put_byte(addr-1, 0x10 | get_byte(addr-1));
104 #endif
105 put_long(addr, relocation);
106 break;
107 default:
108 errx(1, "Unsupported relocation size: %x",
109 RELOC_TARGET_SIZE(rp));
114 * Set up a "direct" transfer (ie. not through the run-time binder) from
115 * jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
116 * and by `ld.so' after resolving the symbol.
117 * On the VAX, we use a PC relative JMP instruction, so no
118 * further RRS relocations will be necessary for such a jmpslot.
120 void
121 md_fix_jmpslot(sp, offset, addr, first)
122 jmpslot_t *sp;
123 long offset;
124 u_long addr;
125 int first;
127 u_long fudge = addr - (offset + 9);
129 if (first) {
130 sp->mask = 0x0101; /* NOP NOP */
131 sp->insn[0] = 0x01; /* nop */
132 sp->insn[1] = 0x17; /* jmp */
133 } else {
134 #ifdef RTLD
135 sp->mask = *(u_int16_t *) addr;
136 sp->insn[0] = 0x01; /* nop */
137 sp->insn[1] = 0x17; /* jmp */
138 fudge += 2; /* skip entry mask */
139 #else
140 sp->mask = 0x0000;
141 sp->insn[0] = 0xfa; /* callg */
142 sp->insn[1] = 0x6c; /* (ap) */
143 #endif
145 sp->insn[2] = 0xef; /* L^(pc) */
146 sp->insn[3] = (fudge >> 0) & 0xff;
147 sp->insn[4] = (fudge >> 8) & 0xff;
148 sp->insn[5] = (fudge >> 16) & 0xff;
149 sp->insn[6] = (fudge >> 24) & 0xff;
150 sp->insn[7] = 0x04; /* ret */
153 void
154 md_set_breakpoint(where, savep)
155 long where;
156 long *savep;
158 *savep = *(long *)where;
159 *(char *)where = BPT;
164 #ifndef RTLD
166 * Machine dependent part of claim_rrs_reloc().
167 * Set RRS relocation type.
170 md_make_reloc(rp, r, type)
171 struct relocation_info *rp, *r;
172 int type;
174 /* Relocation size */
175 r->r_length = rp->r_length;
177 if (RELOC_PCREL_P(rp))
178 r->r_pcrel = 1;
180 if (type & RELTYPE_RELATIVE)
181 r->r_relative = 1;
183 if (type & RELTYPE_COPY)
184 r->r_copy = 1;
186 return 0;
190 * Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
191 * to the binder slot (which is at offset 0 of the PLT).
193 void
194 md_make_jmpslot(sp, offset, index)
195 jmpslot_t *sp;
196 long offset;
197 long index;
200 * On VAX a branch offset given in immediate mode is relative to
201 * the end of the address itself.
203 u_long fudge = - (offset + 9);
205 sp->mask = (1 << 6); /* Just R6 (for setjmp) */
206 sp->insn[0] = 0x01; /* nop */
207 sp->insn[1] = 0x16; /* jsb */
208 sp->insn[2] = 0xef; /* L^(pc) */
209 sp->insn[3] = (fudge >> 0) & 0xff;
210 sp->insn[4] = (fudge >> 8) & 0xff;
211 sp->insn[5] = (fudge >> 16) & 0xff;
212 sp->insn[6] = (fudge >> 24) & 0xff;
213 sp->insn[7] = 0x00; /* halt */
214 sp->reloc_index = index;
218 * Update the relocation record for a RRS jmpslot.
220 void
221 md_make_jmpreloc(rp, r, type)
222 struct relocation_info *rp, *r;
223 int type;
225 jmpslot_t *sp;
228 * Fix relocation address to point to the correct
229 * location within this jmpslot.
231 r->r_address += sizeof(sp->mask);
233 /* Relocation size */
234 r->r_length = 2; /* 4 bytes */
236 /* Set relocation type */
237 r->r_jmptable = 1;
238 if (type & RELTYPE_RELATIVE)
239 r->r_relative = 1;
243 * Set relocation type for a RRS GOT relocation.
245 void
246 md_make_gotreloc(rp, r, type)
247 struct relocation_info *rp, *r;
248 int type;
250 r->r_baserel = 1;
252 if (type & RELTYPE_RELATIVE)
253 r->r_relative = 1;
255 /* Relocation size */
256 r->r_length = 2; /* 4 bytes */
260 * Set relocation type for a RRS copy operation.
262 void
263 md_make_cpyreloc(rp, r)
264 struct relocation_info *rp, *r;
266 /* Relocation size */
267 r->r_length = 2; /* 4 bytes */
269 r->r_copy = 1;
273 md_convert_textreloc(r)
274 struct relocation_info *r;
276 if (r->r_length != 2 || !r->r_pcrel || !r->r_copy)
277 return 0;
279 r->r_baserel = 1;
280 return 1;
283 #ifdef __FreeBSD__
284 int netzmagic;
285 #endif
288 * Initialize (output) exec header such that useful values are
289 * obtained from subsequent N_*() macro evaluations.
291 void
292 md_init_header(hp, magic, flags)
293 struct exec *hp;
294 int magic, flags;
296 #ifdef __NetBSD__
297 if (oldmagic || magic == QMAGIC)
298 hp->a_midmag = magic;
299 else
300 N_SETMAGIC((*hp), magic, MID_VAX, flags);
301 #endif
302 #ifdef __FreeBSD__
303 if (oldmagic)
304 hp->a_midmag = magic;
305 else if (netzmagic)
306 N_SETMAGIC_NET((*hp), magic, MID_VAX, flags);
307 else
308 N_SETMAGIC((*hp), magic, MID_VAX, flags);
309 #endif
311 /* TEXT_START depends on the value of outheader.a_entry. */
312 if (!(link_mode & SHAREABLE))
313 hp->a_entry = PAGSIZ;
315 #endif /* RTLD */
318 #ifdef NEED_SWAP
320 * Byte swap routines for cross-linking.
323 void
324 md_swapin_exec_hdr(h)
325 struct exec *h;
327 int skip = 0;
329 if (!N_BADMAG(*h))
330 skip = 1;
332 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
335 void
336 md_swapout_exec_hdr(h)
337 struct exec *h;
339 /* NetBSD: Always leave magic alone */
340 int skip = 1;
341 #if 0
342 if (N_GETMAGIC(*h) == OMAGIC)
343 skip = 0;
344 #endif
346 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
350 void
351 md_swapin_reloc(r, n)
352 struct relocation_info *r;
353 int n;
355 int bits;
357 for (; n; n--, r++) {
358 r->r_address = md_swap_long(r->r_address);
359 bits = ((int *)r)[1];
360 r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
361 r->r_pcrel = (bits & 1);
362 r->r_length = (bits >> 1) & 3;
363 r->r_extern = (bits >> 3) & 1;
364 r->r_baserel = (bits >> 4) & 1;
365 r->r_jmptable = (bits >> 5) & 1;
366 r->r_relative = (bits >> 6) & 1;
367 #ifdef N_SIZE
368 r->r_copy = (bits >> 7) & 1;
369 #endif
373 void
374 md_swapout_reloc(r, n)
375 struct relocation_info *r;
376 int n;
378 int bits;
380 for (; n; n--, r++) {
381 r->r_address = md_swap_long(r->r_address);
382 bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
383 bits |= (r->r_pcrel & 1);
384 bits |= (r->r_length & 3) << 1;
385 bits |= (r->r_extern & 1) << 3;
386 bits |= (r->r_baserel & 1) << 4;
387 bits |= (r->r_jmptable & 1) << 5;
388 bits |= (r->r_relative & 1) << 6;
389 #ifdef N_SIZE
390 bits |= (r->r_copy & 1) << 7;
391 #endif
392 ((int *)r)[1] = bits;
396 void
397 md_swapout_jmpslot(j, n)
398 jmpslot_t *j;
399 int n;
401 for (; n; n--, j++) {
402 j->mask = md_swap_short(j->mask);
403 j->reloc_index = md_swap_short(j->reloc_index);
406 #endif /* NEED_SWAP */