Sync usage with man page.
[netbsd-mini2440.git] / libexec / ld.aout_so / arch / m68k / md.c
blob77718b0eb6c1e688e82cf6af18894ede874b0a06
1 /* $NetBSD: md.c,v 1.16 1999/04/12 00:52:44 gwr 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));
94 #ifdef RTLD
95 _cachectl (addr, RELOC_TARGET_SIZE(rp)); /* maintain cache coherency */
96 #endif
100 * Set up a "direct" transfer (ie. not through the run-time binder) from
101 * jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
102 * and by `ld.so' after resolving the symbol.
103 * On the m68k, we use the BRA instruction which is PC relative, so no
104 * further RRS relocations will be necessary for such a jmpslot.
106 void
107 md_fix_jmpslot(sp, offset, addr, first)
108 jmpslot_t *sp;
109 long offset;
110 u_long addr;
111 int first;
113 u_long fudge = addr - (sizeof(sp->opcode) + offset);
115 sp->opcode = BRAL;
116 sp->addr[0] = fudge >> 16;
117 sp->addr[1] = fudge;
118 sp->reloc_index = 0;
119 #ifdef RTLD
120 _cachectl (sp, 6); /* maintain cache coherency */
121 #endif
124 void
125 md_set_breakpoint(where, savep)
126 long where;
127 long *savep;
129 *savep = *(long *)where;
130 *(short *)where = BPT;
135 #ifndef RTLD
137 * Machine dependent part of claim_rrs_reloc().
138 * Set RRS relocation type.
141 md_make_reloc(rp, r, type)
142 struct relocation_info *rp, *r;
143 int type;
145 /* Relocation size */
146 r->r_length = rp->r_length;
148 if (RELOC_PCREL_P(rp))
149 r->r_pcrel = 1;
151 if (type & RELTYPE_RELATIVE)
152 r->r_relative = 1;
154 if (type & RELTYPE_COPY)
155 r->r_copy = 1;
157 return 0;
161 * Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
162 * to the binder slot (which is at offset 0 of the PLT).
164 void
165 md_make_jmpslot(sp, offset, index)
166 jmpslot_t *sp;
167 long offset;
168 long index;
171 * On m68k machines, a long branch offset is relative to
172 * the address of the offset.
174 u_long fudge = - (sizeof(sp->opcode) + offset);
176 sp->opcode = BSRL;
177 sp->addr[0] = fudge >> 16;
178 sp->addr[1] = fudge;
179 sp->reloc_index = index;
180 #ifdef RTLD
181 _cachectl (sp, 6); /* maintain cache coherency */
182 #endif
186 * Update the relocation record for a RRS jmpslot.
188 void
189 md_make_jmpreloc(rp, r, type)
190 struct relocation_info *rp, *r;
191 int type;
193 jmpslot_t *sp;
196 * Fix relocation address to point to the correct
197 * location within this jmpslot.
199 r->r_address += sizeof(sp->opcode);
201 /* Relocation size */
202 r->r_length = 2;
204 /* Set relocation type */
205 r->r_jmptable = 1;
206 if (type & RELTYPE_RELATIVE)
207 r->r_relative = 1;
212 * Set relocation type for a RRS GOT relocation.
214 void
215 md_make_gotreloc(rp, r, type)
216 struct relocation_info *rp, *r;
217 int type;
219 r->r_baserel = 1;
220 if (type & RELTYPE_RELATIVE)
221 r->r_relative = 1;
223 /* Relocation size */
224 r->r_length = 2;
228 * Set relocation type for a RRS copy operation.
230 void
231 md_make_cpyreloc(rp, r)
232 struct relocation_info *rp, *r;
234 /* Relocation size */
235 r->r_length = 2;
237 r->r_copy = 1;
241 * Initialize (output) exec header such that useful values are
242 * obtained from subsequent N_*() macro evaluations.
244 void
245 md_init_header(hp, magic, flags)
246 struct exec *hp;
247 int magic, flags;
249 if (oldmagic)
250 hp->a_midmag = oldmagic;
251 else
252 N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
254 /* TEXT_START depends on the value of outheader.a_entry. */
255 if (!(link_mode & SHAREABLE))
256 hp->a_entry = PAGSIZ;
260 * Check for acceptable foreign machine Ids
263 md_midcompat(hp)
264 struct exec *hp;
266 int mid = N_GETMID(*hp);
268 if (mid == MID_M68K ||
269 mid == MID_M68K4K ||
270 mid == MID_HP300 ||
271 mid == MID_HPUX ||
272 mid == MID_HPUX800)
273 return 1;
275 #ifdef MID_SUN020
276 mid = (md_swap_long(hp->a_midmag) & 0x00ff0000) >> 16;
277 if (mid == MID_SUN020)
278 return 1;
279 #endif
280 return 0;
282 #endif /* RTLD */
285 #ifdef NEED_SWAP
287 * Byte swap routines for cross-linking.
290 void
291 md_swapin_exec_hdr(h)
292 struct exec *h;
294 int skip = 0;
296 if (!N_BADMAG(*h))
297 skip = 1;
299 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
302 void
303 md_swapout_exec_hdr(h)
304 struct exec *h;
306 /* NetBSD: Always leave magic alone */
307 int skip = 1;
308 #if 0
309 if (N_GETMAGIC(*h) == OMAGIC)
310 skip = 0;
311 #endif
313 swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
317 void
318 md_swapin_reloc(r, n)
319 struct relocation_info *r;
320 int n;
322 int bits;
324 for (; n; n--, r++) {
325 r->r_address = md_swap_long(r->r_address);
326 bits = ((int *)r)[1];
327 r->r_symbolnum = md_swap_long(bits) >> 8;
328 bits >>= 24;
329 r->r_pcrel = (bits >> 7) & 1;
330 r->r_length = (bits >> 5) & 3;
331 r->r_extern = (bits >> 4) & 1;
332 r->r_baserel = (bits >> 3) & 1;
333 r->r_jmptable = (bits >> 2) & 1;
334 r->r_relative = (bits >> 1) & 1;
335 #ifdef N_SIZE
336 r->r_copy = (bits & 1);
337 #endif
341 void
342 md_swapout_reloc(r, n)
343 struct relocation_info *r;
344 int n;
346 int bits;
348 for (; n; n--, r++) {
349 r->r_address = md_swap_long(r->r_address);
350 bits = (r->r_pcrel & 1) << 7;
351 bits |= (r->r_length & 3) << 5;
352 bits |= (r->r_extern & 1) << 4;
353 bits |= (r->r_baserel & 1) << 3;
354 bits |= (r->r_jmptable & 1) << 2;
355 bits |= (r->r_relative & 1) << 1;
356 #ifdef N_SIZE
357 bits |= (r->r_copy & 1);
358 #endif
359 ((int *)r)[1] = md_swap_long(r->r_symbolnum) >> 8;
360 ((unsigned char *)r)[7] = bits;
364 void
365 md_swapout_jmpslot(j, n)
366 jmpslot_t *j;
367 int n;
369 for (; n; n--, j++) {
370 j->opcode = md_swap_short(j->opcode);
371 j->addr[0] = md_swap_short(j->addr[0]);
372 j->addr[1] = md_swap_short(j->addr[1]);
373 j->reloc_index = md_swap_short(j->reloc_index);
377 #endif /* NEED_SWAP */