These files now live in `src/libexec/ld.aout_so/arch'
This commit is contained in:
parent
137577af03
commit
0ea0854e75
@ -1,71 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.1 1997/10/17 21:25:42 mark Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Mark Brinicombe
|
||||
* Copyright (C) 1997 Causality Limited
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Causality Limited.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
|
||||
#define RELOC_32 0x04
|
||||
#define RELOC_JMPSLOT 0x06 /* See note below */
|
||||
#define RELOC_GOT32 0x24
|
||||
|
||||
/*
|
||||
* The value is RELOC_JMPSLOT is special. Really it should be 0x46 i.e.
|
||||
* have the r_jmptable bit set however due to the usage of the
|
||||
* relocation bits outside the linker the r_jmptable is only used
|
||||
* internal to the linker and thus this bit get lost when the
|
||||
* relocations are written out.
|
||||
*/
|
||||
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
int index;
|
||||
|
||||
index = r->r_pcrel | (r->r_length << 1) | (r->r_extern << 3)
|
||||
| (r->r_neg << 4) | (r->r_baserel << 5);
|
||||
|
||||
if (index == RELOC_JMPSLOT)
|
||||
*(long *)addr += relocation;
|
||||
else if (index == RELOC_GOT32)
|
||||
*(long *)addr += relocation;
|
||||
else if (index == RELOC_32)
|
||||
*(long *)addr += relocation;
|
||||
|
||||
/* if (r->r_relative)
|
||||
*(long *)addr += relocation;*/
|
||||
}
|
@ -1,480 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.9 1998/12/03 15:56:51 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Mark Brinicombe
|
||||
* Copyright (C) 1997 Causality Limited
|
||||
* Copyright (C) 1996 Wolfgang Solfrank
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Wolfgang Solfrank.
|
||||
* This product includes software developed by Causality Limited.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Second cut for arm32 (used to be a simple copy of i386 code) */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
#ifdef RTLD
|
||||
#include <machine/sysarch.h>
|
||||
#include <sys/syscall.h>
|
||||
#endif /* RTLD */
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
#ifdef RTLD
|
||||
/*
|
||||
* Flush the instruction cache of the specified address
|
||||
* Some processors have separate instruction caches and
|
||||
* as such may need a flush following a jump slot fixup.
|
||||
*/
|
||||
__inline void
|
||||
iflush(addr, len)
|
||||
void *addr;
|
||||
int len;
|
||||
{
|
||||
struct arm32_sync_icache_args p;
|
||||
|
||||
/*
|
||||
* This is not an efficient way to flush a chunk of memory
|
||||
* if we need to flush lots of small chunks i.e. a jmpslot
|
||||
* per function call.
|
||||
*/
|
||||
p.addr = (u_int)addr;
|
||||
p.len = len;
|
||||
|
||||
__asm __volatile("mov r0, %0; mov r1, %1; swi %2"
|
||||
: : "I" (ARM32_SYNC_ICACHE), "r" (&p), "J" (SYS_sysarch));
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
long rel;
|
||||
|
||||
switch (rp->r_length) {
|
||||
case 0:
|
||||
rel = get_byte(addr);
|
||||
break;
|
||||
case 1:
|
||||
rel = get_short(addr);
|
||||
break;
|
||||
case 2:
|
||||
rel = get_long(addr);
|
||||
break;
|
||||
case 3: /* looks like a special hack for b & bl */
|
||||
rel = (((long)get_long(addr) & 0xffffff) << 8) >> 6;
|
||||
/*
|
||||
* XXX
|
||||
* Address the addend to be relative to the start of the file
|
||||
* The implecation of doing this is that this adjustment is
|
||||
* done every time the reloc goes through ld.
|
||||
* This means that the adjustment can be applied multiple
|
||||
* times if ld -r is used to do a partial link.
|
||||
*
|
||||
* Solution:
|
||||
* 1. Put a hack in md_relocate so that PC relative
|
||||
* relocations are not modified if
|
||||
* relocatable_output == 1
|
||||
* 2. Modify the assembler to apply this adjustment.
|
||||
*/
|
||||
rel -= rp->r_address;
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
rp->r_length);
|
||||
}
|
||||
return rp->r_neg ? -rel : rel; /* Hack to make r_neg work */
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
/*
|
||||
* XXX
|
||||
* See comments above in md_get_addend
|
||||
*/
|
||||
#ifndef RTLD
|
||||
if (RELOC_PCREL_P(rp) && relocatable_output)
|
||||
relocation += (rp->r_address + pc_relocation);
|
||||
if (rp->r_pcrel && rp->r_length == 2 && relocatable_output)
|
||||
relocation -= rp->r_address;
|
||||
#endif
|
||||
|
||||
if (rp->r_neg) /* Not sure, whether this works in all cases XXX */
|
||||
relocation = -relocation;
|
||||
|
||||
switch (rp->r_length) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
case 2:
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
case 3:
|
||||
put_long(addr,
|
||||
(get_long(addr)&0xff000000)
|
||||
| ((relocation>>2)&0xffffff));
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
rp->r_length);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/* Copy most attributes */
|
||||
r->r_pcrel = rp->r_pcrel;
|
||||
r->r_length = rp->r_length;
|
||||
r->r_neg = rp->r_neg;
|
||||
r->r_baserel = rp->r_baserel;
|
||||
r->r_jmptable = rp->r_jmptable;
|
||||
r->r_relative = rp->r_relative;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
/*
|
||||
* Build the jump slot as follows
|
||||
*
|
||||
* ldr ip, [pc]
|
||||
* add pc, pc, ip
|
||||
* .word rel_addr
|
||||
* .word reloc_index
|
||||
*/
|
||||
sp->opcode1 = GETRELADDR;
|
||||
sp->opcode2 = ADDPC;
|
||||
sp->address = - (offset + 12);
|
||||
sp->reloc_index = index;
|
||||
#ifdef RTLD
|
||||
iflush(sp, sizeof(jmpslot_t));
|
||||
#endif /* RTLD */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
*/
|
||||
|
||||
#ifdef RTLD
|
||||
extern void binder_entry __P((void));
|
||||
#endif
|
||||
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
/*
|
||||
* For jmpslot 0 (the binder)
|
||||
* generate
|
||||
* sub ip, pc, ip
|
||||
* ldr pc, [pc, #-4]
|
||||
* .word addr
|
||||
* <unused>
|
||||
*
|
||||
* For jump slots generated by the linker (i.e. -Bsymbolic)
|
||||
* build a direct jump to the absolute address
|
||||
* i.e.
|
||||
* ldr pc, [pc]
|
||||
* <unused>
|
||||
* .word new_addr
|
||||
* <unused>
|
||||
*
|
||||
* For jump slots generated by ld.so at run time,
|
||||
* just modify the address offset since the slot
|
||||
* will have been created with md_make_jmpslot().
|
||||
* i.e.
|
||||
* ldr ip, [pc]
|
||||
* add pc, pc, ip
|
||||
* .word new_rel_addr
|
||||
* <unused>
|
||||
*/
|
||||
if (first) {
|
||||
/* Build binder jump slot */
|
||||
sp->opcode1 = GETSLOTADDR;
|
||||
sp->opcode2 = LDRPCADDR;
|
||||
sp->address = addr;
|
||||
#ifdef RTLD
|
||||
iflush(sp, sizeof(jmpslot_t));
|
||||
#endif /* RTLD */
|
||||
} else {
|
||||
#ifdef RTLD
|
||||
/*
|
||||
* Change the relative offset to the binder
|
||||
* into a relative offset to the function
|
||||
*/
|
||||
sp->address = (addr - (long)sp - 12);
|
||||
#else
|
||||
/*
|
||||
* Build a direct transfer jump slot
|
||||
* as we not doing a run time fixup.
|
||||
*/
|
||||
sp->opcode1 = JUMP;
|
||||
sp->address = addr;
|
||||
#endif /* RTLD */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_address += 8;
|
||||
r->r_pcrel = 0;
|
||||
r->r_length = 2;
|
||||
r->r_neg = 0;
|
||||
r->r_baserel = 0;
|
||||
r->r_jmptable = 1;
|
||||
r->r_relative = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_pcrel = 0;
|
||||
r->r_length = 2;
|
||||
r->r_neg = 0;
|
||||
r->r_baserel = 1;
|
||||
r->r_jmptable = 0;
|
||||
r->r_relative = 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
r->r_pcrel = 0;
|
||||
r->r_length = 2;
|
||||
r->r_neg = 0;
|
||||
r->r_baserel = 0;
|
||||
r->r_jmptable = 0;
|
||||
r->r_relative = 0;
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(long *)where = TRAP;
|
||||
#ifdef RTLD
|
||||
iflush((long *)where, sizeof(long));
|
||||
#endif /* RTLD */
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
N_SETMAGIC((*hp), magic, MID_ARM6, flags);
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
for (; n; n--, j++) {
|
||||
j->opcode1 = md_swap_long(j->opcode1);
|
||||
j->opcode2 = md_swap_long(j->opcode2);
|
||||
j->address = md_swap_long(j->address);
|
||||
j->reloc_index = md_swap_long(j->reloc_index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
/*
|
||||
* md_swapin_reloc()
|
||||
*
|
||||
* As well as provide bit swapping for cross compiling with different
|
||||
* endianness we need to munge some of the reloc bits.
|
||||
* This munging is due to the assemble packing all the PIC related
|
||||
* relocs so that only 1 extra bit in the reloc structure is needed
|
||||
* The result is that jmpslot branches are packed as a baserel branch
|
||||
* Spot this case and internally use a jmptable bit.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
#ifdef NEED_SWAP
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = ((int *)r)[1];
|
||||
r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
|
||||
r->r_pcrel = (bits & 1);
|
||||
r->r_length = (bits >> 1) & 3;
|
||||
r->r_extern = (bits >> 3) & 1;
|
||||
r->r_neg = (bits >> 4) & 1;
|
||||
r->r_baserel = (bits >> 5) & 1;
|
||||
r->r_jmptable = (bits >> 6) & 1;
|
||||
r->r_relative = (bits >> 7) & 1;
|
||||
#endif
|
||||
/* Look for PIC relocation */
|
||||
if (r->r_baserel) {
|
||||
/* Look for baserel branch */
|
||||
if (r->r_length == 3 && r->r_pcrel == 0) {
|
||||
r->r_jmptable = 1;
|
||||
}
|
||||
/* Look for GOTPC reloc */
|
||||
if (r->r_length == 2 && r->r_pcrel == 1)
|
||||
r->r_baserel = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
/* Look for jmptable relocation */
|
||||
if (r->r_jmptable && r->r_pcrel == 0 && r->r_length == 3) {
|
||||
r->r_jmptable = 0;
|
||||
r->r_baserel = 1;
|
||||
}
|
||||
#ifdef NEED_SWAP
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
|
||||
bits |= (r->r_pcrel & 1);
|
||||
bits |= (r->r_length & 3) << 1;
|
||||
bits |= (r->r_extern & 1) << 3;
|
||||
bits |= (r->r_neg & 1) << 4;
|
||||
bits |= (r->r_baserel & 1) << 5;
|
||||
bits |= (r->r_jmptable & 1) << 6;
|
||||
bits |= (r->r_relative & 1) << 7;
|
||||
((int *)r)[1] = bits;
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,262 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.3 1998/10/19 03:09:31 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe
|
||||
* Copyright (c) 1997 Causality Limited
|
||||
* Copyright (c) 1993 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Paul Kranenburg.
|
||||
* This product includes software developed by Causality Limited
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Second cut for arm32 */
|
||||
|
||||
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==sparc
|
||||
#define NEED_SWAP
|
||||
#endif
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (long))
|
||||
|
||||
#ifdef NetBSD
|
||||
#define PAGSIZ __LDPGSZ
|
||||
#else
|
||||
#define PAGSIZ 4096
|
||||
#endif
|
||||
|
||||
#define N_SET_FLAG(ex,f) (N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f)))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) (N_GETMID(ex) != MID_MACHINE)
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#ifdef __notyet__
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
#else
|
||||
#define TEXT_START(ex) ((ex).a_entry < PAGSIZ ? 0 : 0x001000)
|
||||
#define DATA_START(ex) (N_GETMAGIC(ex) == OMAGIC \
|
||||
? TEXT_START(ex) + (ex).a_text \
|
||||
: (TEXT_START(ex) + (ex).a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1))
|
||||
#endif
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
|
||||
#define JMPSLOT_NEEDS_RELOC (1)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (1)
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE (0)
|
||||
|
||||
#define md_got_reloc(r) (-r->r_address)
|
||||
|
||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
#define GOT_ENTRY_SIZE 4
|
||||
typedef long got_t;
|
||||
|
||||
typedef struct jmpslot {
|
||||
u_long opcode1; /* ldr ip, [pc] */
|
||||
u_long opcode2; /* add pc, pc, ip */
|
||||
u_long address; /* binder/function address */
|
||||
u_long reloc_index; /* relocation index */
|
||||
#define JMPSLOT_RELOC_MASK 0xffffffff
|
||||
} jmpslot_t;
|
||||
|
||||
#define SAVEPC 0xe1a0c00e /* MOV ip, lr */
|
||||
#define CALL 0xeb000000 /* CALL opcode */
|
||||
#define JUMP 0xe59ff000 /* LDR pc, [pc] (used as JMP) */
|
||||
#define TRAP 0xe6000011 /* Undefined Instruction (used for bpt) */
|
||||
|
||||
#define GETSLOTADDR 0xe04fc00c /* sub ip, pc, ip */
|
||||
#define ADDPC 0xe08ff00c /* add pc, pc, ip */
|
||||
#define LDRPCADDR 0xe51ff004 /* ldr pc, [pc, #-4] */
|
||||
#define GETRELADDR 0xe59fc000 /* ldr ip, [pc] */
|
||||
|
||||
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
||||
|
||||
/*
|
||||
* Define all the RELOC_ macros
|
||||
*/
|
||||
#define RELOC_ADDRESS(r) ((r)->r_address)
|
||||
#define RELOC_EXTERN_P(r) ((r)->r_extern)
|
||||
#define RELOC_TYPE(r) ((r)->r_symbolnum)
|
||||
#define RELOC_SYMBOL(r) ((r)->r_symbolnum)
|
||||
/* #define RELOC_MEMORY_SUB_P(r) ((r)->r_neg) not used */
|
||||
#define RELOC_MEMORY_ADD_P(r) 1
|
||||
#undef RELOC_ADD_EXTRA
|
||||
#define RELOC_PCREL_P(r) (((r)->r_pcrel == 1) ^ ((r)->r_length == 3))
|
||||
#define RELOC_VALUE_RIGHTSHIFT(r) 0
|
||||
/*#define RELOC_TARGET_SIZE(r) ((r)->r_length) not used */
|
||||
/*#define RELOC_TARGET_BITPOS(r) 0 not used */
|
||||
/*#define RELOC_TARGET_BITSIZE(r) 32 not used */
|
||||
|
||||
#define RELOC_JMPTAB_P(r) ((r)->r_jmptable)
|
||||
#define RELOC_BASEREL_P(r) ((r)->r_baserel)
|
||||
#define RELOC_RELATIVE_P(r) ((r)->r_relative)
|
||||
#define RELOC_COPY_P(r) (0)
|
||||
#define RELOC_LAZY_P(r) ((r)->r_jmptable)
|
||||
|
||||
/*#define CHECK_GOT_RELOC(r) RELOC_PCREL_P(r)*/
|
||||
#define CHECK_GOT_RELOC(r) (((r)->r_pcrel == 1) && ((r)->r_length == 2))
|
||||
|
||||
/*
|
||||
* Define the range of usable Global Offset Table offsets
|
||||
* when using arm LDR instructions with 12 bit offset (-4092 -> 4092);
|
||||
* this is the case if the object files are compiles with -fpic'.
|
||||
* IF a "large" model is used (i.e. -fPIC'), .word instructions
|
||||
* are generated instead providing 32-bit addressability of the GOT table.
|
||||
*/
|
||||
|
||||
#define MAX_GOTOFF(t) ((t) == PIC_TYPE_SMALL ? 4092 : LONG_MAX)
|
||||
#define MIN_GOTOFF(t) ((t) == PIC_TYPE_SMALL ? -4092 : LONG_MIN)
|
||||
|
||||
#define RELOC_PIC_TYPE(r) ((r)->r_baserel ? \
|
||||
((r)->r_length == 1 ? \
|
||||
PIC_TYPE_SMALL : \
|
||||
PIC_TYPE_LARGE) : \
|
||||
PIC_TYPE_NONE)
|
||||
|
||||
#define RELOC_INIT_SEGMENT_RELOC(r)
|
@ -1,92 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.1 1997/10/17 21:25:59 mark Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1996 Wolfgang Solfrank
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Wolfgang Solfrank.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* arm run-time link editor entry points.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* _rtl(int version, struct crt_ldso *crtp)
|
||||
*/
|
||||
|
||||
.align 0
|
||||
.type _rtl,#function
|
||||
_rtl: @ crt0 calls us here
|
||||
mov ip, sp @ Allocate stack frame
|
||||
stmfd sp!, {sl, fp, ip, lr, pc}
|
||||
sub fp, ip, #4
|
||||
|
||||
ldr r3, [r1, #0] @ base address of ld.so (first field)
|
||||
@ setup arguments for rtld()
|
||||
ldr sl, GOTaddr @ get pc-rel offset for GOT
|
||||
add sl, pc, sl @ here is the GOT
|
||||
L1:
|
||||
ldr r2, DYNAMICaddr
|
||||
ldr r2, [sl, r2] @ 1st entry in GOT is our __DYNAMIC
|
||||
add r2, r2, r3 @ add load address
|
||||
ldr lr, rtldaddr @ get GOT offset for function
|
||||
ldr lr, [sl, lr] @ get function address
|
||||
add r3, lr, r3 @ and relocate
|
||||
mov lr, pc
|
||||
mov pc, r3 @ _rtld(version, crtp, DYNAMIC)
|
||||
|
||||
ldmea fp, {sl, fp, ip, pc}
|
||||
|
||||
.align 0
|
||||
GOTaddr:
|
||||
.word __GLOBAL_OFFSET_TABLE_ + (. - (L1+4) )
|
||||
DYNAMICaddr:
|
||||
.word __DYNAMIC
|
||||
rtldaddr:
|
||||
.word _rtld
|
||||
|
||||
@ First call to a procedure generally comes through here for
|
||||
@ binding.
|
||||
|
||||
ENTRY(binder_entry)
|
||||
stmfd sp!, {r0-fp, ip, lr, pc} @ save all regs in standard frame
|
||||
@ (ip and lr to be fixed later)
|
||||
add fp, sp, #(15-1)*4 @ get new fp
|
||||
add r0, fp, #4 @ compute old sp
|
||||
str r0, [fp, #-8] @ fixup saved ip
|
||||
|
||||
sub r0, ip, #(8+12) @ make it point to the jmpslot
|
||||
|
||||
bl _binder
|
||||
str r0, [fp] @ return value from _binder()
|
||||
@ == actual address of function
|
||||
ldmfa fp, {r0-fp, sp, lr, pc} @ restore regs
|
@ -1,17 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.3 1998/01/05 22:00:35 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
if (r->r_relative)
|
||||
*(long *)addr += relocation;
|
||||
}
|
||||
|
@ -1,369 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.16 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
return get_byte(addr);
|
||||
case 1:
|
||||
return get_short(addr);
|
||||
case 2:
|
||||
return get_long(addr);
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
case 2:
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = rp->r_length;
|
||||
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_pcrel = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
if (type & RELTYPE_COPY)
|
||||
r->r_copy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
/*
|
||||
* i386 PC-relative "fixed point" is located right after the
|
||||
* instruction it pertains to.
|
||||
*/
|
||||
u_long fudge = - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
|
||||
|
||||
sp->opcode = CALL;
|
||||
#if 0
|
||||
sp->addr = fudge;
|
||||
#else
|
||||
sp->addr[0] = fudge & 0xffff;
|
||||
sp->addr[1] = fudge >> 16;
|
||||
#endif
|
||||
sp->reloc_index = index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
* On the i386, we use the JMP instruction which is PC relative, so no
|
||||
* further RRS relocations will be necessary for such a jmpslot.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
u_long fudge = addr - (sizeof(sp->opcode) + sizeof(sp->addr) + offset);
|
||||
|
||||
sp->opcode = JUMP;
|
||||
#if 0
|
||||
sp->addr = fudge;
|
||||
#else
|
||||
sp->addr[0] = fudge & 0xffff;
|
||||
sp->addr[1] = fudge >> 16;
|
||||
#endif
|
||||
#if 0
|
||||
sp->reloc_index = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
jmpslot_t *sp;
|
||||
|
||||
/*
|
||||
* Fix relocation address to point to the correct
|
||||
* location within this jmpslot.
|
||||
*/
|
||||
r->r_address += sizeof(sp->opcode);
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
/* Set relocation type */
|
||||
r->r_jmptable = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_baserel = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
r->r_copy = 1;
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(char *)where = TRAP;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
|
||||
#ifdef FreeBSD
|
||||
int netzmagic;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
#ifdef NetBSD
|
||||
if (oldmagic || magic == QMAGIC)
|
||||
hp->a_midmag = magic;
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_I386, flags);
|
||||
#endif
|
||||
#ifdef FreeBSD
|
||||
if (oldmagic)
|
||||
hp->a_midmag = magic;
|
||||
else if (netzmagic)
|
||||
N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_I386, flags);
|
||||
#endif
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (!N_BADMAG(*h))
|
||||
skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
#if 0
|
||||
if (N_GETMAGIC(*h) == OMAGIC)
|
||||
skip = 0;
|
||||
#endif
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = ((int *)r)[1];
|
||||
r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
|
||||
r->r_pcrel = (bits & 1);
|
||||
r->r_length = (bits >> 1) & 3;
|
||||
r->r_extern = (bits >> 3) & 1;
|
||||
r->r_baserel = (bits >> 4) & 1;
|
||||
r->r_jmptable = (bits >> 5) & 1;
|
||||
r->r_relative = (bits >> 6) & 1;
|
||||
#ifdef N_SIZE
|
||||
r->r_copy = (bits >> 7) & 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
|
||||
bits |= (r->r_pcrel & 1);
|
||||
bits |= (r->r_length & 3) << 1;
|
||||
bits |= (r->r_extern & 1) << 3;
|
||||
bits |= (r->r_baserel & 1) << 4;
|
||||
bits |= (r->r_jmptable & 1) << 5;
|
||||
bits |= (r->r_relative & 1) << 6;
|
||||
#ifdef N_SIZE
|
||||
bits |= (r->r_copy & 1) << 7;
|
||||
#endif
|
||||
((int *)r)[1] = bits;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
for (; n; n--, j++) {
|
||||
j->opcode = md_swap_short(j->opcode);
|
||||
j->addr[0] = md_swap_short(j->addr[0]);
|
||||
j->addr[1] = md_swap_short(j->addr[1]);
|
||||
j->reloc_index = md_swap_short(j->reloc_index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
@ -1,233 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.12 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==sparc
|
||||
#define NEED_SWAP
|
||||
#endif
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (long))
|
||||
|
||||
#ifdef NetBSD
|
||||
#define PAGSIZ __LDPGSZ
|
||||
#else
|
||||
#define PAGSIZ 4096
|
||||
#endif
|
||||
|
||||
#if defined(NetBSD) || defined(CROSS_LINKER)
|
||||
|
||||
#define N_SET_FLAG(ex,f) (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
|
||||
N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f)))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) \
|
||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FreeBSD does it differently
|
||||
*/
|
||||
#ifdef FreeBSD
|
||||
#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
|
||||
(netzmagic == 0 ? \
|
||||
N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f)) : \
|
||||
N_SETMAGIC_NET(ex, \
|
||||
N_GETMAGIC_NET(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG_NET(ex)|(f)) ))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
|
||||
((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
|
||||
((N_GETFLAG(ex) & EX_DYNAMIC) ))
|
||||
#define N_BADMID(ex) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (0)
|
||||
#define JMPSLOT_NEEDS_RELOC (0)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (1)
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE (0)
|
||||
|
||||
#define md_got_reloc(r) (0)
|
||||
|
||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
#define GOT_ENTRY_SIZE 4
|
||||
typedef long got_t;
|
||||
|
||||
typedef struct jmpslot {
|
||||
u_short opcode;
|
||||
u_short addr[2];
|
||||
u_short reloc_index;
|
||||
#define JMPSLOT_RELOC_MASK 0xffff
|
||||
} jmpslot_t;
|
||||
|
||||
#define NOP 0x90
|
||||
#define CALL 0xe890 /* NOP + CALL opcode */
|
||||
#define JUMP 0xe990 /* NOP + JMP opcode */
|
||||
#define TRAP 0xcc /* INT 3 */
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin_reloc(r,n)
|
||||
#define md_swapout_reloc(r,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
@ -1,99 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.9 1998/09/05 13:08:38 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* i386 run-time link editor entry points.
|
||||
*/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
.text
|
||||
.globl _binder, _binder_entry
|
||||
|
||||
/*
|
||||
* _rtl(int version, struct crt_ldso *crtp)
|
||||
*/
|
||||
|
||||
_rtl: # crt0 calls us here
|
||||
pushl %ebp # Allocate stack frame
|
||||
movl %esp,%ebp
|
||||
pushl %ebx
|
||||
|
||||
call 1f # PIC function prologue
|
||||
1:
|
||||
popl %ebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
|
||||
|
||||
movl 12(%ebp),%eax # Extract data from interface structure
|
||||
movl (%eax),%eax # base address of ld.so (first field)
|
||||
# setup arguments for rtld()
|
||||
movl (%ebx),%ecx # 1st entry in GOT is our __DYNAMIC
|
||||
addl %eax,%ecx # add load address
|
||||
pushl %ecx # 3rd arg
|
||||
pushl 12(%ebp) # 2nd arg == &crt.
|
||||
pushl 8(%ebp) # 1st arg == version
|
||||
addl _rtld@GOT(%ebx),%eax # relocate address of function
|
||||
call %eax # _rtld(version, crtp, DYNAMIC)
|
||||
addl $12,%esp # pop arguments
|
||||
|
||||
popl %ebx
|
||||
leave # remove stack frame
|
||||
ret
|
||||
|
||||
# First call to a procedure generally comes through here for
|
||||
# binding.
|
||||
|
||||
_binder_entry:
|
||||
pushl %ebp # setup a stack frame
|
||||
movl %esp,%ebp
|
||||
pusha # save all regs
|
||||
|
||||
xorl %eax,%eax # clear
|
||||
movl 4(%ebp),%esi # return address in PLT
|
||||
movw (%esi),%ax # get hold of relocation number
|
||||
subl $6,%esi # make it point to the jmpslot
|
||||
|
||||
pushl %eax # pushd arguments
|
||||
pushl %esi #
|
||||
call _binder@PLT # _binder(rpc, index)
|
||||
addl $8,%esp # pop arguments
|
||||
movl %eax,4(%ebp) # return value from _binder() == actual
|
||||
# address of function
|
||||
popa # restore regs
|
||||
leave # remove our stack frame
|
||||
ret
|
@ -1,18 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.4 1998/01/05 22:00:38 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
if (r->r_relative) {
|
||||
*(long *)addr += relocation;
|
||||
_cachectl (addr, 4); /* maintain cache coherency */
|
||||
}
|
||||
}
|
||||
|
@ -1,375 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.12 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
return get_byte(addr);
|
||||
case 1:
|
||||
return get_short(addr);
|
||||
case 2:
|
||||
return get_long(addr);
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
case 2:
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
#ifdef RTLD
|
||||
_cachectl (addr, RELOC_TARGET_SIZE(rp)); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = rp->r_length;
|
||||
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_pcrel = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
if (type & RELTYPE_COPY)
|
||||
r->r_copy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
/*
|
||||
* On m68k machines, a long branch offset is relative to
|
||||
* the address of the offset.
|
||||
*/
|
||||
u_long fudge = - (sizeof(sp->opcode) + offset);
|
||||
|
||||
sp->opcode = BSRL;
|
||||
sp->addr[0] = fudge >> 16;
|
||||
sp->addr[1] = fudge;
|
||||
sp->reloc_index = index;
|
||||
#ifdef RTLD
|
||||
_cachectl (sp, 6); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
* On the m68k, we use the BRA instruction which is PC relative, so no
|
||||
* further RRS relocations will be necessary for such a jmpslot.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
u_long fudge = addr - (sizeof(sp->opcode) + offset);
|
||||
|
||||
sp->opcode = BRAL;
|
||||
sp->addr[0] = fudge >> 16;
|
||||
sp->addr[1] = fudge;
|
||||
sp->reloc_index = 0;
|
||||
#ifdef RTLD
|
||||
_cachectl (sp, 6); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
jmpslot_t *sp;
|
||||
|
||||
/*
|
||||
* Fix relocation address to point to the correct
|
||||
* location within this jmpslot.
|
||||
*/
|
||||
r->r_address += sizeof(sp->opcode);
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
/* Set relocation type */
|
||||
r->r_jmptable = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_baserel = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
r->r_copy = 1;
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(short *)where = BPT;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
if (oldmagic)
|
||||
hp->a_midmag = oldmagic;
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for acceptable foreign machine Ids
|
||||
*/
|
||||
int
|
||||
md_midcompat(hp)
|
||||
struct exec *hp;
|
||||
{
|
||||
int mid = N_GETMID(*hp);
|
||||
|
||||
if (mid == MID_M68K ||
|
||||
mid == MID_M68K4K ||
|
||||
mid == MID_HP300 ||
|
||||
mid == MID_HPUX ||
|
||||
mid == MID_HPUX800)
|
||||
return 1;
|
||||
#if 0
|
||||
return (((md_swap_long(hp->a_midmag)&0x00ff0000) >> 16) == MID_SUN020);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (!N_BADMAG(*h))
|
||||
skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
#if 0
|
||||
if (N_GETMAGIC(*h) == OMAGIC)
|
||||
skip = 0;
|
||||
#endif
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = ((int *)r)[1];
|
||||
r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
|
||||
bits = ((unsigned char *)r)[7];
|
||||
r->r_pcrel = (bits >> 7) & 1;
|
||||
r->r_length = (bits >> 5) & 3;
|
||||
r->r_extern = (bits >> 4) & 1;
|
||||
r->r_baserel = (bits >> 3) & 1;
|
||||
r->r_jmptable = (bits >> 2) & 1;
|
||||
r->r_relative = (bits >> 1) & 1;
|
||||
#ifdef N_SIZE
|
||||
r->r_copy = (bits & 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
((int *)r)[1] = md_swap_long(r->r_symbolnum) & 0xffffff00;
|
||||
bits = (r->r_pcrel & 1) << 7;
|
||||
bits |= (r->r_length & 3) << 5;
|
||||
bits |= (r->r_extern & 1) << 4;
|
||||
bits |= (r->r_baserel & 1) << 3;
|
||||
bits |= (r->r_jmptable & 1) << 2;
|
||||
bits |= (r->r_relative & 1) << 1;
|
||||
#ifdef N_SIZE
|
||||
bits |= (r->r_copy & 1);
|
||||
#endif
|
||||
((unsigned char *)r)[7] = bits;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
for (; n; n--, j++) {
|
||||
j->opcode = md_swap_short(j->opcode);
|
||||
j->addr[0] = md_swap_short(j->addr[0]);
|
||||
j->addr[1] = md_swap_short(j->addr[1]);
|
||||
j->reloc_index = md_swap_short(j->reloc_index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
@ -1,170 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.6 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*
|
||||
* - m68k dependent definitions
|
||||
*/
|
||||
|
||||
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==i386
|
||||
#define NEED_SWAP
|
||||
#endif
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (long))
|
||||
|
||||
#define PAGSIZ __LDPGSZ
|
||||
|
||||
#define N_SET_FLAG(ex,f) N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) \
|
||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE && \
|
||||
!md_midcompat(&(ex)))
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
|
||||
#define JMPSLOT_NEEDS_RELOC (0)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (1)
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE (0)
|
||||
|
||||
#define md_got_reloc(r) (0)
|
||||
|
||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
#define GOT_ENTRY_SIZE 4
|
||||
typedef long got_t;
|
||||
|
||||
typedef struct jmpslot {
|
||||
u_short opcode;
|
||||
u_short addr[2];
|
||||
u_short reloc_index;
|
||||
#define JMPSLOT_RELOC_MASK 0xffff
|
||||
} jmpslot_t;
|
||||
|
||||
#define NOP 0x4e71
|
||||
#define BSRL 0x61ff /* BSR opcode with long offset */
|
||||
#define BRAL 0x60ff /* BRA opcode with long offset */
|
||||
#define BPT 0x4e42 /* breakpoint trap: trap #2 */
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin_reloc(r,n)
|
||||
#define md_swapout_reloc(r,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_link_object(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_link_object(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
@ -1,81 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.8 1998/01/05 22:00:40 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Paul Mackerras
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Paul Mackerras.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Run-time link editor entry points for m68k architecture.
|
||||
*/
|
||||
|
||||
.globl _rtl
|
||||
_rtl:
|
||||
link a6,#0
|
||||
movel a5,sp@-
|
||||
movel a6@(12),a0 | -> crt_ldso structure
|
||||
movel a0@,a1 | base address
|
||||
movel #__GLOBAL_OFFSET_TABLE_,a5 | PIC function prologue
|
||||
lea pc@(0,a5:l),a5
|
||||
movel a5@,d0 | 1st entry in GOT
|
||||
addl a1,d0 | add ld.so base address
|
||||
movel d0,sp@- | gives address of __DYNAMIC
|
||||
movel a0,sp@- | crt_ldso pointer
|
||||
movel a6@(8),sp@- | version
|
||||
addl a5@(_rtld:w),a1 | relocate _rtld function
|
||||
jsr a1@ | call it
|
||||
| movel #0x80000004,d0 | CC_EXTPURGE | CC_IPURGE
|
||||
| trap #12 | cachectl
|
||||
movel a6@(-4),a5
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
.globl _binder_entry
|
||||
_binder_entry:
|
||||
movml a0-a1/d0-d1,sp@- | preserve scratch registers
|
||||
movl sp@(16),a0 | grab return address (within PLT)
|
||||
moveq #0,d0
|
||||
movw a0@,d0 | get function index
|
||||
movel d0,sp@-
|
||||
subql #6,a0 | point to PLT slot
|
||||
movel a0,sp@-
|
||||
jbsr _binder | relocate function address
|
||||
addql #8,sp
|
||||
movel d0,sp@(16) | put function address on stack
|
||||
| movel #0x80000004,d0 | CC_EXTPURGE | CC_IPURGE
|
||||
| trap #12 | cachectl
|
||||
movml sp@+,a0-a1/d0-d1 | restore scratch registers
|
||||
rts | jump into function (via address on stack)
|
||||
|
||||
.globl __cachectl
|
||||
__cachectl:
|
||||
movel sp@(4),a1 | address
|
||||
movel sp@(8),d1 | length
|
||||
movel #0x80000004,d0 | function = CC_EXTPURGE | CC_IPURGE
|
||||
trap #12 | cachectl "syscall"
|
||||
rts
|
@ -1,38 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.2 1998/01/05 22:00:41 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#define write(fd, s, n) __syscall(SYS_write, (fd), (s), (n))
|
||||
#define _exit(n) __syscall(SYS_exit, (n))
|
||||
|
||||
asm("___syscall:");
|
||||
asm(" movd tos,r1"); /* return address */
|
||||
asm(" movd tos,r0"); /* syscall number */
|
||||
asm(" movd r1,tos");
|
||||
asm(" svc"); /* do system call */
|
||||
asm(" bcc 1f"); /* check error */
|
||||
asm(" movqd -1,r0");
|
||||
asm("1: jump 0(0(sp))"); /* return */
|
||||
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
if (r->r_relative) {
|
||||
if (r->r_disp != 2) {
|
||||
write(2, "Illegal runtime relocation for ld.so",
|
||||
sizeof("Illegal runtime relocation for ld.so") - 1);
|
||||
_exit(1);
|
||||
}
|
||||
*(long *)addr += relocation;
|
||||
}
|
||||
}
|
||||
|
||||
#undef _exit
|
||||
#undef write
|
@ -1,524 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.10 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Put little endian VAL of size N at ADDR
|
||||
*/
|
||||
static void
|
||||
put_num(addr, val, n)
|
||||
unsigned char *addr;
|
||||
long val;
|
||||
char n;
|
||||
{
|
||||
while (n--) {
|
||||
*addr++ = val;
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get little endian of size N at ADDR
|
||||
*/
|
||||
static unsigned long
|
||||
get_num(addr, n)
|
||||
unsigned char *addr;
|
||||
int n;
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
addr += (n - 1);
|
||||
while (n--)
|
||||
val = val * 256 + *addr--;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put big endian VAL of size N at ADDR
|
||||
*/
|
||||
static void
|
||||
put_imm(addr, val, n)
|
||||
unsigned char *addr;
|
||||
unsigned long val;
|
||||
char n;
|
||||
{
|
||||
addr += (n - 1);
|
||||
while (n--) {
|
||||
*addr-- = val;
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get big endian of size N at ADDR
|
||||
*/
|
||||
static unsigned long
|
||||
get_imm(addr, n)
|
||||
unsigned char *addr;
|
||||
int n;
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
while (n--)
|
||||
val = val * 256 + *addr++;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Displacements are big endian with the size
|
||||
* encoded in the two top bits:
|
||||
* Byte: 0xxxxxxx
|
||||
* Word: 10xxxxxx xxxxxxxx
|
||||
* Double word: 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
|
||||
*/
|
||||
|
||||
/*
|
||||
* Signextend VAL from bit N
|
||||
*/
|
||||
static long
|
||||
sign_extend(val, n)
|
||||
int val, n;
|
||||
{
|
||||
val = val & ((1 << n) - 1);
|
||||
return (val & (1 << (n - 1))?
|
||||
val | (~((1 << n) - 1))
|
||||
:
|
||||
val
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put ns32k displacement VAL of size N at ADDR
|
||||
*/
|
||||
static void
|
||||
put_disp(addr, val, n)
|
||||
unsigned char *addr;
|
||||
long val;
|
||||
char n;
|
||||
{
|
||||
switch (n) {
|
||||
case 1:
|
||||
if (val < -64 || val > 63)
|
||||
warnx("Byte displacement %d, out of range.", val);
|
||||
val &= 0x7f;
|
||||
*addr++ = val;
|
||||
break;
|
||||
case 2:
|
||||
if (val < -8192 || val > 8191)
|
||||
warnx("Word displacement %d, out of range.", val);
|
||||
val &= 0x3fff;
|
||||
val |= 0x8000;
|
||||
*addr++ = (val >> 8);
|
||||
*addr++ = val;
|
||||
break;
|
||||
case 4:
|
||||
#if 1
|
||||
if (val < -0x1f000000 || val >= 0x20000000)
|
||||
#else
|
||||
if (val < -0x20000000 || val >= 0x20000000)
|
||||
#endif
|
||||
warnx("Double word displacement %d, out of range", val);
|
||||
val |= 0xc0000000;
|
||||
*addr++ = (val >> 24);
|
||||
*addr++ = (val >> 16);
|
||||
*addr++ = (val >> 8);
|
||||
*addr++ = val;
|
||||
break;
|
||||
default:
|
||||
errx(1, "internal error: putdisp: n = %d", n);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get ns32k displacement size N at ADDR
|
||||
*/
|
||||
static unsigned long
|
||||
get_disp(addr, n)
|
||||
unsigned char *addr;
|
||||
int n;
|
||||
{
|
||||
unsigned long Ivalue;
|
||||
|
||||
Ivalue = *addr++ & 0xff;
|
||||
if (n == 0) {
|
||||
if (Ivalue & 0x80) {
|
||||
if (Ivalue & 0x40)
|
||||
n = 4;
|
||||
else
|
||||
n = 2;
|
||||
} else
|
||||
n = 1;
|
||||
}
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
Ivalue = sign_extend(Ivalue, 7);
|
||||
break;
|
||||
case 2:
|
||||
Ivalue = sign_extend(Ivalue, 6);
|
||||
Ivalue = (Ivalue << 8) | *addr;
|
||||
break;
|
||||
case 4:
|
||||
Ivalue = sign_extend (Ivalue, 6);
|
||||
Ivalue = (Ivalue << 8) | *addr++;
|
||||
Ivalue = (Ivalue << 8) | *addr++;
|
||||
Ivalue = (Ivalue << 8) | *addr;
|
||||
break;
|
||||
default:
|
||||
errx(1, "get_disp: invalid argument %d\n", n);
|
||||
}
|
||||
return Ivalue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
int bytes = 1 << RELOC_TARGET_SIZE(rp);
|
||||
|
||||
switch (rp->r_disp) {
|
||||
case 0:
|
||||
return get_imm(addr, bytes);
|
||||
case 1:
|
||||
return get_disp(addr, bytes);
|
||||
case 2:
|
||||
return get_num(addr, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
{
|
||||
int bytes = 1 << RELOC_TARGET_SIZE(rp);
|
||||
|
||||
switch (rp->r_disp) {
|
||||
case 0:
|
||||
return put_imm(addr, relocation, bytes);
|
||||
case 1:
|
||||
return put_disp(addr, relocation, bytes);
|
||||
case 2:
|
||||
return put_num(addr, relocation, bytes);
|
||||
}
|
||||
#ifdef RTLD
|
||||
_cachectl (addr, bytes); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = rp->r_length;
|
||||
|
||||
/* Data type */
|
||||
r->r_disp = rp->r_disp;
|
||||
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_pcrel = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
if (type & RELTYPE_COPY)
|
||||
r->r_copy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
/*
|
||||
* On ns32k machines, a long branch offset is relative to
|
||||
* the address of the branch instruction.
|
||||
*/
|
||||
|
||||
put_num(sp->code, BSR, 2);
|
||||
put_disp(sp->code + 2, -offset - 1, 4);
|
||||
sp->reloc_index = index;
|
||||
#ifdef RTLD
|
||||
_cachectl (sp->code, 6); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
* On the ns32k, we use the BR instruction which is PC relative, so no
|
||||
* further RRS relocations will be necessary for such a jmpslot.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
put_num(sp->code, BR, 2);
|
||||
put_disp(sp->code + 2, addr - offset - 1, 4);
|
||||
sp->reloc_index = 0;
|
||||
#ifdef RTLD
|
||||
_cachectl (sp->code, 6); /* maintain cache coherency */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
jmpslot_t *sp;
|
||||
|
||||
/*
|
||||
* Fix relocation address to point to the correct
|
||||
* location within this jmpslot.
|
||||
*/
|
||||
r->r_address++;
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
/* Data type */
|
||||
r->r_disp = 1;
|
||||
|
||||
/* Set relocation type */
|
||||
r->r_jmptable = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_baserel = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
/* Data type */
|
||||
r->r_disp = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = 2;
|
||||
|
||||
/* Data type */
|
||||
r->r_disp = 2;
|
||||
|
||||
r->r_copy = 1;
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(short *)where = BPT;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
if (oldmagic)
|
||||
hp->a_midmag = oldmagic;
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (!N_BADMAG(*h))
|
||||
skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
#if 0
|
||||
if (N_GETMAGIC(*h) == OMAGIC)
|
||||
skip = 0;
|
||||
#endif
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = ((int *)r)[1];
|
||||
r->r_symbolnum = md_swap_long(bits) & 0xffffff;
|
||||
bits = ((unsigned char *)r)[7];
|
||||
r->r_pcrel = ((bits >> 7) & 1);
|
||||
r->r_length = ((bits >> 5) & 3);
|
||||
r->r_extern = ((bits >> 4) & 1);
|
||||
r->r_baserel = ((bits >> 3) & 1);
|
||||
r->r_jmptable = ((bits >> 2) & 1);
|
||||
r->r_relative = ((bits >> 1) & 1);
|
||||
#ifdef N_SIZE
|
||||
r->r_copy = (bits & 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
((int *)r)[1] = md_swap_long(r->r_symbolnum & 0xffffff00);
|
||||
bits = ((r->r_pcrel << 7) & 0x80);
|
||||
bits |= ((r->r_length << 5) & 0x60);
|
||||
bits |= ((r->r_extern << 4) & 0x10);
|
||||
bits |= ((r->r_baserel << 3) & 8);
|
||||
bits |= ((r->r_jmptable << 2) & 4);
|
||||
bits |= ((r->r_relative << 1) & 2);
|
||||
#ifdef N_SIZE
|
||||
bits |= (r->r_copy & 1);
|
||||
#endif
|
||||
((unsigned char *)r)[7] = bits;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
for (; n; n--, j++) {
|
||||
j->opcode = md_swap_short(j->opcode);
|
||||
j->addr[0] = md_swap_short(j->addr[0]);
|
||||
j->addr[1] = md_swap_short(j->addr[1]);
|
||||
j->reloc_index = md_swap_short(j->reloc_index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
@ -1,143 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.6 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*
|
||||
* - ns32k dependent definitions
|
||||
*/
|
||||
|
||||
#if defined(CROSS_LINKER) && defined(XHOST) && (XHOST==m68k || XHOST==sparc)
|
||||
#define NEED_SWAP
|
||||
#endif
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (long))
|
||||
|
||||
#define PAGSIZ __LDPGSZ
|
||||
|
||||
#define N_SET_FLAG(ex,f) N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) \
|
||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
|
||||
#define JMPSLOT_NEEDS_RELOC (0)
|
||||
#define RELOC_INIT_SEGMENT_RELOC(r) ((r)->r_disp = 2)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (1)
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE (0)
|
||||
|
||||
#define md_got_reloc(r) (0)
|
||||
|
||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
#define GOT_ENTRY_SIZE 4
|
||||
typedef long got_t;
|
||||
|
||||
typedef struct jmpslot {
|
||||
u_char code[6];
|
||||
u_short reloc_index;
|
||||
#define JMPSLOT_RELOC_MASK 0xffff
|
||||
} jmpslot_t;
|
||||
|
||||
#define NOP 0xa2 /* NOP opcode */
|
||||
#define BSR 0x02a2 /* NOP BSR opcode */
|
||||
#define BR 0xeaa2 /* NOP BR opcode */
|
||||
#define BPT 0xf2 /* BPT opcode */
|
||||
|
||||
static inline void _cachectl __P((void *, unsigned int));
|
||||
|
||||
static inline void
|
||||
_cachectl(addr, bytes)
|
||||
void *addr;
|
||||
unsigned int bytes;
|
||||
{
|
||||
vaddr_t start;
|
||||
for(start = (vaddr_t) addr & 0xfffffff0;
|
||||
start < (vaddr_t) addr + bytes; start += 0x10)
|
||||
cinv(start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
# define md_swapin_exec_hdr(h)
|
||||
# define md_swapout_exec_hdr(h)
|
||||
# define md_swapin_symbols(s,n)
|
||||
# define md_swapout_symbols(s,n)
|
||||
# define md_swapin_zsymbols(s,n)
|
||||
# define md_swapout_zsymbols(s,n)
|
||||
# define md_swapin_reloc(r,n)
|
||||
# define md_swapout_reloc(r,n)
|
||||
# define md_swapin__dynamic(l)
|
||||
# define md_swapout__dynamic(l)
|
||||
# define md_swapin_section_dispatch_table(l)
|
||||
# define md_swapout_section_dispatch_table(l)
|
||||
# define md_swapin_so_debug(d)
|
||||
# define md_swapout_so_debug(d)
|
||||
# define md_swapin_rrs_hash(f,n)
|
||||
# define md_swapout_rrs_hash(f,n)
|
||||
# define md_swapin_sod(l,n)
|
||||
# define md_swapout_sod(l,n)
|
||||
# define md_swapout_jmpslot(j,n)
|
||||
# define md_swapout_got(g,n)
|
||||
# define md_swapin_ranlib_hdr(h,n)
|
||||
# define md_swapout_ranlib_hdr(h,n)
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
# ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
# define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
# define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
# define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
# define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
# define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
# define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
# define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
# define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
# define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
# define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
# define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
# define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
# define md_swapin_sod(l,n) swapin_link_object(l,n)
|
||||
# define md_swapout_sod(l,n) swapout_link_object(l,n)
|
||||
# define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
# define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
# define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
# define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
# define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000) )
|
||||
|
||||
# else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
# define md_swap_short(x) (x)
|
||||
# define md_swap_long(x) (x)
|
||||
|
||||
# endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
# define md_swap_short(x) (x)
|
||||
# define md_swap_long(x) (x)
|
||||
|
||||
#endif /* CROSS_LINKER */
|
@ -1,131 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.7 1998/01/05 22:00:42 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Matthias Pfaller.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Matthias Pfaller.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Run-time link editor entry points for ns32k architecture.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
/*
|
||||
* rtld_entry(int version, struct crt_ldso *crtp)
|
||||
*/
|
||||
|
||||
ENTRY_NOPROFILE(rtl_entry)
|
||||
enter [],0
|
||||
sprd sb,tos
|
||||
addr _C_LABEL(_GLOBAL_OFFSET_TABLE_)(pc),r0
|
||||
lprd sb,r0 /* PIC function prologue */
|
||||
movd 12(fp),r0 /* -> crt_ldso structure */
|
||||
movd 0(r0),r1 /* base address */
|
||||
/* 1st entry in GOT */
|
||||
/* + ld.so base address */
|
||||
addr 0(0(sb))[r1:b],tos /* gives address of __DYNAMIC */
|
||||
movd r0,tos /* crt_ldso pointer */
|
||||
movd 8(fp),tos /* version */
|
||||
jsr 0(_C_LABEL(rtld)(sb))[r1:b] /* call _rtld function */
|
||||
lprd sb,-4(fp)
|
||||
exit []
|
||||
ret 0
|
||||
|
||||
/*
|
||||
* First call to a procedure generally comes through here for
|
||||
* binding.
|
||||
*/
|
||||
|
||||
ENTRY_NOPROFILE(binder_entry)
|
||||
save [r0,r1,r2] /* preserve scratch registers */
|
||||
/* save r0 (for cerror) */
|
||||
/* save r1 (maybe static chain) */
|
||||
/* save r2 (maybe struct addr) */
|
||||
addr -6(12(sp)),tos /* push address of PLT slot */
|
||||
bsr _C_LABEL(binder) /* relocate function address */
|
||||
cmpqd 0,tos
|
||||
movd r0,12(sp) /* prepare for jump */
|
||||
restore [r0,r1,r2] /* restore scratch registers */
|
||||
ret 0 /* jump into function */
|
||||
|
||||
|
||||
/* Force cache line corresponding to address argument to be loaded */
|
||||
|
||||
.text
|
||||
/*
|
||||
* Now we have to 0x200-align the text segment.
|
||||
* We know that the a.out header is 0x20 bytes long.
|
||||
* The code so far is less then 0x1e0 bytes. So we
|
||||
* advance "." to address 0x1e0.
|
||||
*/
|
||||
|
||||
.org 0x1e0
|
||||
|
||||
/*
|
||||
* We are at address 0x200 now.
|
||||
*/
|
||||
|
||||
0: ret 0; /* 0000 */
|
||||
ASGLOBAL(_C_LABEL(cinv))
|
||||
movd S_ARG0,r0 /* 0002 */
|
||||
andd 0x1f0,r0 /* 0005 */
|
||||
jump 0b(pc)[r0:b] /* 000b */
|
||||
/* 000f */
|
||||
|
||||
.align 4,0xa2; ret 0 /* 0010 */
|
||||
.align 4,0xa2; ret 0 /* 0020 */
|
||||
.align 4,0xa2; ret 0 /* 0030 */
|
||||
.align 4,0xa2; ret 0 /* 0040 */
|
||||
.align 4,0xa2; ret 0 /* 0050 */
|
||||
.align 4,0xa2; ret 0 /* 0060 */
|
||||
.align 4,0xa2; ret 0 /* 0070 */
|
||||
.align 4,0xa2; ret 0 /* 0080 */
|
||||
.align 4,0xa2; ret 0 /* 0090 */
|
||||
.align 4,0xa2; ret 0 /* 00a0 */
|
||||
.align 4,0xa2; ret 0 /* 00b0 */
|
||||
.align 4,0xa2; ret 0 /* 00c0 */
|
||||
.align 4,0xa2; ret 0 /* 00d0 */
|
||||
.align 4,0xa2; ret 0 /* 00e0 */
|
||||
.align 4,0xa2; ret 0 /* 00f0 */
|
||||
.align 4,0xa2; ret 0 /* 0100 */
|
||||
.align 4,0xa2; ret 0 /* 0110 */
|
||||
.align 4,0xa2; ret 0 /* 0120 */
|
||||
.align 4,0xa2; ret 0 /* 0130 */
|
||||
.align 4,0xa2; ret 0 /* 0140 */
|
||||
.align 4,0xa2; ret 0 /* 0150 */
|
||||
.align 4,0xa2; ret 0 /* 0160 */
|
||||
.align 4,0xa2; ret 0 /* 0170 */
|
||||
.align 4,0xa2; ret 0 /* 0180 */
|
||||
.align 4,0xa2; ret 0 /* 0190 */
|
||||
.align 4,0xa2; ret 0 /* 01a0 */
|
||||
.align 4,0xa2; ret 0 /* 01b0 */
|
||||
.align 4,0xa2; ret 0 /* 01c0 */
|
||||
.align 4,0xa2; ret 0 /* 01d0 */
|
||||
.align 4,0xa2; ret 0 /* 01e0 */
|
||||
.align 4,0xa2; ret 0 /* 01f0 */
|
@ -1,17 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.2 1998/01/05 22:00:43 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
if (r->r_relative)
|
||||
*(long *)addr += relocation;
|
||||
}
|
||||
|
@ -1,294 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.4 1998/10/19 03:09:32 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
static int reloc_target_rightshift[] = {
|
||||
-1, 0, 2, 0, 0, 16, 16, 2,
|
||||
-1, -1, 2, 2, -1, -1, 0, 0,
|
||||
16, 16, 2, -1, -1, -1, -1, -1,
|
||||
-1, -1, 0, 0, 0, 0, 16, 16
|
||||
};
|
||||
|
||||
static int reloc_target_bitpos[] = {
|
||||
-1, 0, 2, 0, 0, 0, 0, 2,
|
||||
-1, -1, 2, 2, -1, -1, 0, 0,
|
||||
0, 0, 2, -1, -1, -1, -1, -1,
|
||||
-1, -1, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static int reloc_target_size[] = {
|
||||
-1, 4, 4, 2, 2, 2, 2, 4,
|
||||
-1, -1, 4, 4, -1, -1, 2, 2,
|
||||
2, 2, 4, -1, -1, -1, -1, -1,
|
||||
-1, -1, 4, 4, 4, 2, 2, 2
|
||||
};
|
||||
|
||||
static int reloc_target_bitsize[] = {
|
||||
-1, 32, 24, 16, 16, 16, 16, 14,
|
||||
-1, -1, 24, 14, -1, -1, 16, 16,
|
||||
16, 16, 24, -1, -1, -1, -1, -1,
|
||||
-1, -1, 32, 32, 32, 16, 16, 16
|
||||
};
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
return rp->r_addend;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
register unsigned long mask;
|
||||
int ha_adj = 0;
|
||||
|
||||
if (relocatable_output) {
|
||||
/*
|
||||
* Store relocation where the next link-edit run
|
||||
* will look for it.
|
||||
*/
|
||||
rp->r_addend = relocation;
|
||||
return;
|
||||
}
|
||||
if (rp->r_type == RELOC_16_HA
|
||||
|| rp->r_type == RELOC_GOT16_HA
|
||||
|| rp->r_type == RELOC_PLT16_HA)
|
||||
relocation += (relocation & 0x8000) << 1;
|
||||
|
||||
relocation >>= RELOC_VALUE_RIGHTSHIFT(rp);
|
||||
|
||||
/* Unshifted mask for relocation */
|
||||
mask = 1 << RELOC_TARGET_BITSIZE(rp) - 1;
|
||||
mask |= mask - 1;
|
||||
relocation &= mask;
|
||||
|
||||
/* Shift everything up to where it's going to be used */
|
||||
relocation <<= RELOC_TARGET_BITPOS(rp);
|
||||
mask <<= RELOC_TARGET_BITPOS(rp);
|
||||
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 4:
|
||||
*(u_long *)addr &= ~mask;
|
||||
*(u_long *)addr |= relocation;
|
||||
break;
|
||||
case 2:
|
||||
*(u_short *)addr &= ~mask;
|
||||
*(u_short *)addr |= relocation;
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unknown relocation type %d", rp->r_type);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_type = rp->r_type;
|
||||
r->r_addend = rp->r_addend;
|
||||
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_addend -= pc_relocation;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
errx(1, "md_make_jmpslot unimplemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
errx(1, "md_fix_jmpslot unimplemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
errx(1, "md_make_jmpreloc unimplemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
errx(1, "md_make_gotreloc unimplemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
errx(1, "md_make_cpyreloc unimplemented");
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(char *)where = TRAP;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
swap_longs((long *)h + 1, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
swap_longs((long *)h + 1, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
errx(1, "md_swapin_reloc unimplemented");
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
errx(1, "md_swapout_reloc unimplemented");
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
errx(1, "md_swapout_jmpslot unimplemented");
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
@ -1,225 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.2 1998/10/19 03:09:33 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Wolfgang Solfrank
|
||||
* Copyright (c) 1995 TooLs GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (double)) /* 32??? */
|
||||
|
||||
#define PAGSIZ __LDPGSZ
|
||||
|
||||
#define N_SET_FLAG(ex,f) N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) (N_GETMID(ex) != MID_MACHINE)
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#define RELOC_ADDRESS(r) ((r)->r_address)
|
||||
#define RELOC_EXTERN_P(r) ((r)->r_extern)
|
||||
#define RELOC_TYPE(r) ((r)->r_symbolnum)
|
||||
#define RELOC_SYMBOL(r) ((r)->r_symbolnum)
|
||||
#define RELOC_MEMORY_SUB_P(r) 0
|
||||
#define RELOC_MEMORY_ADD_P(r) 0
|
||||
#define RELOC_ADD_EXTRA(r) ((r)->r_addend)
|
||||
#define RELOC_PCREL_P(r) \
|
||||
(((r)->r_type >= RELOC_REL24 && (r)->r_type <= RELOC_REL14_NTAKEN) \
|
||||
|| (r)->r_type == RELOC_PLT24 \
|
||||
|| (r)->r_type == RELOC_REL32 \
|
||||
|| (r)->r_type == RELOC_PLTREL32)
|
||||
#define RELOC_VALUE_RIGHTSHIFT(r) (reloc_target_rightshift[(r)->r_type])
|
||||
#define RELOC_TARGET_SIZE(r) (reloc_target_size[(r)->r_type])
|
||||
#define RELOC_TARGET_BITPOS(r) (reloc_target_bitpos[(r)->r_type])
|
||||
#define RELOC_TARGET_BITSIZE(r) (reloc_target_bitsize[(r)->r_type])
|
||||
#define RELOC_JMPTAB_P(r) \
|
||||
((r)->r_type == RELOC_PLT24 \
|
||||
|| ((r)->r_type >= RELOC_PLT32 \
|
||||
&& (r)->r_type <= RELOC_PLT16_HA))
|
||||
#define RELOC_BASEREL_P(r) 0
|
||||
#define RELOC_RELATIVE_P(r) ((r)->r_type == RELOC_RELATIVE)
|
||||
#define RELOC_COPY_P(r) ((r)->r_type == RELOC_COPY)
|
||||
#define RELOC_LAZY_P(r) ((r)->r_type == RELOC_JMP_SLOT)
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) 1
|
||||
#define JMPSLOT_NEEDS_RELOC 1
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT 1
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE 0
|
||||
|
||||
#define CHECK_GOT_RELOC(r) \
|
||||
((r)->r_type >= RELOC_16_LO \
|
||||
&& (r)->r_type <= RELOC_16_HA)
|
||||
|
||||
#define md_got_reloc(r) (-(r)->r_address)
|
||||
|
||||
#define RELOC_INIT_SEGMENT_RELOC(r) ((r)->r_type = RELOC_32)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
typedef long got_t;
|
||||
|
||||
/*
|
||||
* TO BE DONE!!!
|
||||
*/
|
||||
typedef struct jmpslot {
|
||||
u_long opcode;
|
||||
u_long addr;
|
||||
u_long reloc_index;
|
||||
#define JMPSLOT_RELOC_MASK 0xffffffff
|
||||
} jmpslot_t;
|
||||
|
||||
#define NOP 0
|
||||
#define CALL 0
|
||||
#define JUMP 0
|
||||
#define TRAP 0
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin_reloc(r,n)
|
||||
#define md_swapout_reloc(r,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
@ -1,21 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.2 1998/01/05 22:00:44 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* PowerPC run-time link editor entry points.
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl _binder, _binder_entry
|
||||
|
||||
/*
|
||||
* _rtl(int version, struct crt_ldso *crtp)
|
||||
*/
|
||||
_rtl: /* crt0 calls us here */
|
||||
ret
|
||||
|
||||
/*
|
||||
* First call to a procedure generally comes through here for
|
||||
* binding.
|
||||
*/
|
||||
_binder_entry:
|
||||
ret
|
@ -1,38 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.4 1998/12/15 21:23:57 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Simple SPARC relocations for the benefit of self-relocation of ld.so
|
||||
* avoiding the use of global variables (ie. reloc_bitshift[] et. al.).
|
||||
* Only types supported are RELOC_32 and RELOC_RELATIVE.
|
||||
*
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
unsigned long mask;
|
||||
unsigned long shift;
|
||||
|
||||
switch (r->r_type) {
|
||||
case RELOC_32:
|
||||
mask = 0xffffffff;
|
||||
shift = 0;
|
||||
break;
|
||||
case RELOC_RELATIVE:
|
||||
mask = 0x003fffff;
|
||||
shift = 10;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
relocation += (*(long *)addr & mask) << shift;
|
||||
relocation >>= shift;
|
||||
relocation &= mask;
|
||||
|
||||
*(long *) (addr) &= ~mask;
|
||||
*(long *) (addr) |= relocation;
|
||||
}
|
||||
|
@ -1,356 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.17 1998/10/19 03:09:33 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <a.out.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Relocation masks and sizes for the Sparc architecture.
|
||||
*
|
||||
* Note that these are very dependent on the order of the enums in
|
||||
* enum reloc_type (in a.out.h); if they change the following must be
|
||||
* changed.
|
||||
* Also, note that RELOC_RELATIVE is handled as if it were a RELOC_HI22.
|
||||
* This should work provided that relocations values have zeroes in their
|
||||
* least significant 10 bits. As RELOC_RELATIVE is used only to relocate
|
||||
* with load address values - which are page aligned - this condition is
|
||||
* fulfilled as long as the system's page size is > 1024 (and a power of 2).
|
||||
*/
|
||||
static int reloc_target_rightshift[] = {
|
||||
0, 0, 0, /* RELOC_8, _16, _32 */
|
||||
0, 0, 0, 2, 2, /* DISP8, DISP16, DISP32, WDISP30, WDISP22 */
|
||||
10, 0, /* HI22, _22 */
|
||||
0, 0, /* RELOC_13, _LO10 */
|
||||
0, 0, /* _SFA_BASE, _SFA_OFF13 */
|
||||
0, 0, 10, /* _BASE10, _BASE13, _BASE22 */
|
||||
0, 10, /* _PC10, _PC22 */
|
||||
2, 0, /* _JMP_TBL, _SEGOFF16 */
|
||||
0, 0, 0 /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
|
||||
};
|
||||
static int reloc_target_size[] = {
|
||||
0, 1, 2, /* RELOC_8, _16, _32 */
|
||||
0, 1, 2, 2, 2, /* DISP8, DISP16, DISP32, WDISP30, WDISP22 */
|
||||
2, 2, /* HI22, _22 */
|
||||
2, 2, /* RELOC_13, _LO10 */
|
||||
2, 2, /* _SFA_BASE, _SFA_OFF13 */
|
||||
2, 2, 2, /* _BASE10, _BASE13, _BASE22 */
|
||||
2, 2, /* _PC10, _PC22 */
|
||||
2, 0, /* _JMP_TBL, _SEGOFF16 */
|
||||
2, 0, 2 /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
|
||||
};
|
||||
static int reloc_target_bitsize[] = {
|
||||
8, 16, 32, /* RELOC_8, _16, _32 */
|
||||
8, 16, 32, 30, 22, /* DISP8, DISP16, DISP32, WDISP30, WDISP22 */
|
||||
22, 22, /* HI22, _22 */
|
||||
13, 10, /* RELOC_13, _LO10 */
|
||||
32, 32, /* _SFA_BASE, _SFA_OFF13 */
|
||||
10, 13, 22, /* _BASE10, _BASE13, _BASE22 */
|
||||
10, 22, /* _PC10, _PC22 */
|
||||
30, 0, /* _JMP_TBL, _SEGOFF16 */
|
||||
32, 0, 22 /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
|
||||
};
|
||||
|
||||
static __inline void
|
||||
iflush(sp)
|
||||
jmpslot_t *sp;
|
||||
{
|
||||
__asm __volatile("iflush %0+0" : : "r" (sp));
|
||||
__asm __volatile("iflush %0+4" : : "r" (sp));
|
||||
__asm __volatile("iflush %0+8" : : "r" (sp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* ADDR unused by SPARC impl.
|
||||
*/
|
||||
long
|
||||
md_get_addend(r, addr)
|
||||
struct relocation_info *r;
|
||||
unsigned char *addr;
|
||||
{
|
||||
return r->r_addend;
|
||||
}
|
||||
|
||||
void
|
||||
md_relocate(r, relocation, addr, relocatable_output)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
register unsigned long mask;
|
||||
|
||||
if (relocatable_output) {
|
||||
/*
|
||||
* Store relocation where the next link-edit run
|
||||
* will look for it.
|
||||
*/
|
||||
r->r_addend = relocation;
|
||||
return;
|
||||
}
|
||||
|
||||
relocation >>= RELOC_VALUE_RIGHTSHIFT(r);
|
||||
|
||||
/* Unshifted mask for relocation */
|
||||
mask = 1 << RELOC_TARGET_BITSIZE(r) - 1;
|
||||
mask |= mask - 1;
|
||||
relocation &= mask;
|
||||
|
||||
/* Shift everything up to where it's going to be used */
|
||||
relocation <<= RELOC_TARGET_BITPOS(r);
|
||||
mask <<= RELOC_TARGET_BITPOS(r);
|
||||
|
||||
#define RELOCATE(type) \
|
||||
{ \
|
||||
type ad; \
|
||||
(void)memcpy(&ad, addr, sizeof(ad)); \
|
||||
if (RELOC_MEMORY_ADD_P(r)) \
|
||||
relocation += (mask & ad); \
|
||||
ad &= ~mask; \
|
||||
ad |= relocation; \
|
||||
(void)memcpy(addr, &ad, sizeof(ad)); \
|
||||
}
|
||||
|
||||
switch (RELOC_TARGET_SIZE(r)) {
|
||||
case 0:
|
||||
RELOCATE(u_char)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
RELOCATE(u_short)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
RELOCATE(u_long)
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unimplemented relocation field length: %d",
|
||||
RELOC_TARGET_SIZE(r));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* On the Sparc the relocation offsets are stored in the r_addend member.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_type = rp->r_type;
|
||||
r->r_addend = rp->r_addend;
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* This wouldn't be strictly necessary - we could record the
|
||||
* relocation value "in situ" in stead of in the r_addend field -
|
||||
* but we are being Sun compatible here. Besides, Sun's ld.so
|
||||
* has a bug that prevents it from handling this alternate method.
|
||||
*
|
||||
* IT WOULD BE REALLY NICE TO HAVE CONSISTENCY THROUGHOUT THE ENTIRE
|
||||
* RELOCATION PROCESS, ie. using `r_addend' for storing all partially
|
||||
* completed relocations, in stead of mixing them in both relocation
|
||||
* records and in the segment data.
|
||||
*/
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_addend -= pc_relocation;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
u_long fudge = (u_long) -(sizeof(sp->opcode1) + offset);
|
||||
sp->opcode1 = SAVE;
|
||||
/* The following is a RELOC_WDISP30 relocation */
|
||||
sp->opcode2 = CALL | ((fudge >> 2) & 0x3fffffff);
|
||||
sp->reloc_index = NOP | index;
|
||||
iflush(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
* On the i386, we use the JMP instruction which is PC relative, so no
|
||||
* further RRS relocations will be necessary for such a jmpslot.
|
||||
*
|
||||
* OFFSET unused on Sparc.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
/*
|
||||
* Here comes a RELOC_{LO10,HI22} relocation pair
|
||||
* The resulting code is:
|
||||
* sethi %hi(addr), %g1
|
||||
* jmp %g1+%lo(addr)
|
||||
* nop ! delay slot
|
||||
*/
|
||||
sp->opcode1 = SETHI | ((addr >> 10) & 0x003fffff);
|
||||
sp->opcode2 = JMP | (addr & 0x000003ff);
|
||||
sp->reloc_index = NOP;
|
||||
iflush(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_type = RELOC_RELATIVE;
|
||||
else
|
||||
r->r_type = RELOC_JMP_SLOT;
|
||||
|
||||
r->r_addend = rp->r_addend;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a GOT RRS relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/*
|
||||
* GOT value resolved (symbolic or entry point): R_32
|
||||
* GOT not resolved: GLOB_DAT
|
||||
*
|
||||
* NOTE: I don't think it makes a difference.
|
||||
*/
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_type = RELOC_32;
|
||||
else
|
||||
r->r_type = RELOC_GLOB_DAT;
|
||||
|
||||
r->r_addend = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
r->r_type = RELOC_COPY_DAT;
|
||||
r->r_addend = 0;
|
||||
}
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(long *)where = TRAP;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
#ifdef __NetBSD__
|
||||
N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
|
||||
hp->a_entry = PAGSIZ;
|
||||
#else
|
||||
hp->a_magic = magic;
|
||||
hp->a_machtype = M_SPARC;
|
||||
hp->a_toolversion = 1;
|
||||
hp->a_dynamic = ((flags) & EX_DYNAMIC);
|
||||
|
||||
/* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
|
||||
hp->a_entry = N_PAGSIZ(*hp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for acceptable foreign machine Ids
|
||||
*/
|
||||
int
|
||||
md_midcompat(hp)
|
||||
struct exec *hp;
|
||||
{
|
||||
#ifdef __NetBSD__
|
||||
#define SUN_M_SPARC 3
|
||||
return (((md_swap_long(hp->a_midmag)&0x00ff0000) >> 16) == SUN_M_SPARC);
|
||||
#else
|
||||
return hp->a_machtype == M_SPARC;
|
||||
#endif
|
||||
}
|
||||
#endif /* RTLD */
|
@ -1,309 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.16 1998/12/15 21:22:52 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPARC machine dependent definitions
|
||||
*/
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (double))
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#define PAGSIZ __LDPGSZ
|
||||
|
||||
#define N_SET_FLAG(ex,f) N_SETMAGIC(ex,N_GETMAGIC(ex), \
|
||||
MID_MACHINE, N_GETFLAG(ex)|(f))
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#else /* __NetBSD__ */
|
||||
|
||||
/* Get the SunOS a.out and relocation nomenclature */
|
||||
#define EX_DYNAMIC 1
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((ex).a_dynamic)
|
||||
|
||||
#define N_SET_FLAG(ex, f) { \
|
||||
(ex).a_dynamic = ((f) & EX_DYNAMIC); \
|
||||
}
|
||||
|
||||
#undef relocation_info
|
||||
#define relocation_info reloc_info_sparc
|
||||
#define r_symbolnum r_index
|
||||
#endif /* __NetBSD__ */
|
||||
|
||||
#define N_BADMID(ex) \
|
||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE && \
|
||||
!md_midcompat(&(ex)))
|
||||
|
||||
/* Sparc (Sun 4) macros */
|
||||
#define RELOC_ADDRESS(r) ((r)->r_address)
|
||||
#define RELOC_EXTERN_P(r) ((r)->r_extern)
|
||||
#define RELOC_TYPE(r) ((r)->r_symbolnum)
|
||||
#define RELOC_SYMBOL(r) ((r)->r_symbolnum)
|
||||
#define RELOC_MEMORY_SUB_P(r) 0
|
||||
#ifdef RTLD
|
||||
/* XXX - consider this making SUN_COMPAT --> repercussions on rrs.c */
|
||||
#define RELOC_MEMORY_ADD_P(r) 1
|
||||
#else
|
||||
#define RELOC_MEMORY_ADD_P(r) 0
|
||||
#endif
|
||||
#define RELOC_ADD_EXTRA(r) ((r)->r_addend)
|
||||
#define RELOC_PCREL_P(r) \
|
||||
(((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22) \
|
||||
|| ((r)->r_type == RELOC_PC10 || (r)->r_type == RELOC_PC22) \
|
||||
|| (r)->r_type == RELOC_JMP_TBL)
|
||||
#define RELOC_VALUE_RIGHTSHIFT(r) (reloc_target_rightshift[(r)->r_type])
|
||||
#define RELOC_TARGET_SIZE(r) (reloc_target_size[(r)->r_type])
|
||||
#define RELOC_TARGET_BITPOS(r) 0
|
||||
#define RELOC_TARGET_BITSIZE(r) (reloc_target_bitsize[(r)->r_type])
|
||||
|
||||
#define RELOC_JMPTAB_P(r) ((r)->r_type == RELOC_JMP_TBL)
|
||||
|
||||
#define RELOC_BASEREL_P(r) \
|
||||
((r)->r_type >= RELOC_BASE10 && (r)->r_type <= RELOC_BASE22)
|
||||
|
||||
#define RELOC_RELATIVE_P(r) ((r)->r_type == RELOC_RELATIVE)
|
||||
#define RELOC_COPY_DAT (RELOC_RELATIVE+1) /*XXX*/
|
||||
#define RELOC_COPY_P(r) ((r)->r_type == RELOC_COPY_DAT)
|
||||
#define RELOC_LAZY_P(r) ((r)->r_type == RELOC_JMP_SLOT)
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
|
||||
#define JMPSLOT_NEEDS_RELOC (1)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (1)
|
||||
#define JMPSLOT_NONEXTERN_IS_INTERMODULE (0)
|
||||
|
||||
/*
|
||||
* Define the range of usable Global Offset Table offsets
|
||||
* when using sparc 13 bit relocation types (-4096 - 4092);
|
||||
* this is the case if the object files are compiles with `-fpic'.
|
||||
* IF a "large" model is used (i.e. `-fPIC'), pairs of
|
||||
* <RELOC_BASE10,RELOC_BASE22> relocations are used which establish
|
||||
* 32-bit addressability of the GOT table.
|
||||
*/
|
||||
#define MAX_GOTOFF(t) ((t)==PIC_TYPE_SMALL?4092:LONG_MAX)
|
||||
#define MIN_GOTOFF(t) ((t)==PIC_TYPE_SMALL?-4096:LONG_MIN)
|
||||
|
||||
#define RELOC_PIC_TYPE(r) ( \
|
||||
((r)->r_type == RELOC_BASE10 || (r)->r_type == RELOC_BASE22) \
|
||||
? PIC_TYPE_LARGE \
|
||||
: ((r)->r_type==RELOC_BASE13 ? \
|
||||
PIC_TYPE_SMALL : \
|
||||
PIC_TYPE_NONE) )
|
||||
|
||||
#define CHECK_GOT_RELOC(r) \
|
||||
((r)->r_type == RELOC_PC10 || (r)->r_type == RELOC_PC22)
|
||||
|
||||
#define md_got_reloc(r) (-(r)->r_address)
|
||||
|
||||
#define RELOC_INIT_SEGMENT_RELOC(r) ((r)->r_type = RELOC_32)
|
||||
|
||||
#ifdef SUN_COMPAT
|
||||
/*
|
||||
* Sun plays games with `r_addend'
|
||||
*/
|
||||
#define md_get_rt_segment_addend(r,a) (0)
|
||||
#endif
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
typedef long got_t;
|
||||
|
||||
typedef struct jmpslot {
|
||||
u_long opcode1;
|
||||
u_long opcode2;
|
||||
u_long reloc_index;
|
||||
#define JMPSLOT_RELOC_MASK (0x003fffff) /* 22 bits */
|
||||
} jmpslot_t;
|
||||
|
||||
#define SAVE 0x9de3bfa0 /* Build stack frame (opcode1) */
|
||||
#define SETHI 0x03000000 /* %hi(addr) -> %g1 (opcode1) */
|
||||
#define CALL 0x40000000 /* Call instruction (opcode2) */
|
||||
#define JMP 0x81c06000 /* Jump %g1 instruction (opcode2) */
|
||||
#define NOP 0x01000000 /* Delay slot NOP for (reloc_index) */
|
||||
#define TRAP 0x91d02001 /* ta 0x1 */
|
||||
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin_reloc(r,n)
|
||||
#define md_swapout_reloc(r,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[1] << 8) | \
|
||||
( ((unsigned char *)(p))[0] ) \
|
||||
)
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[3] << 24) | \
|
||||
( ((unsigned char *)(p))[2] << 16) | \
|
||||
( ((unsigned char *)(p))[1] << 8 ) | \
|
||||
( ((unsigned char *)(p))[0] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
||||
|
@ -1,108 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.7 1998/09/05 13:08:39 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPARC run-time link editor entry points.
|
||||
*/
|
||||
|
||||
#define CRT_VERSION_SUN 1
|
||||
|
||||
.seg "text" ! [internal]
|
||||
.proc 16
|
||||
.global _rtld_entry
|
||||
_rtld_entry:
|
||||
!#PROLOGUE# 0
|
||||
save %sp,-96,%sp
|
||||
L.1B:
|
||||
call L.2B
|
||||
sethi %hi((__GLOBAL_OFFSET_TABLE_-(L.1B-.))),%l7
|
||||
L.2B:
|
||||
!#PROLOGUE# 1
|
||||
or %l7,%lo((__GLOBAL_OFFSET_TABLE_-(L.1B-.))),%l7
|
||||
add %l7,%o7,%l7
|
||||
|
||||
cmp %i0, CRT_VERSION_SUN ! is crtp passed in Sun style,
|
||||
bne 1f ! ie. relative to stack frame ?
|
||||
nop
|
||||
add %i1, %fp, %i1 ! if so, adjust to absolute address
|
||||
1:
|
||||
ld [%i1], %o3 ! load base address (crtp->crt_ba)
|
||||
ld [%l7], %o2 ! get __DYNAMIC address
|
||||
! from 1st GOT entry
|
||||
add %o2, %o3, %o2 ! relocate and make it 3rd arg.
|
||||
|
||||
ld [%l7 + _rtld], %g1 ! get address of rtld()
|
||||
add %g1, %o3, %g1 ! relocate
|
||||
|
||||
mov %i1, %o1 ! set up args, #2: crtp
|
||||
call %g1 ! rtld(version, crtp, dp)
|
||||
mov %i0, %o0 ! arg #1: version
|
||||
|
||||
mov %o0, %i0 ! pass on rtld() return value
|
||||
ret
|
||||
restore
|
||||
.seg "data" ! [internal]
|
||||
|
||||
.seg "text"
|
||||
.global _binder_entry
|
||||
_binder_entry:
|
||||
!#PROLOGUE# 0
|
||||
save %sp,-96,%sp
|
||||
!L.1C:
|
||||
! call L.2C
|
||||
! sethi %hi((__GLOBAL_OFFSET_TABLE_-(L.1C-.))),%l7
|
||||
!L.2C:
|
||||
! or %l7,%lo((__GLOBAL_OFFSET_TABLE_-(L.1C-.))),%l7
|
||||
!#PROLOGUE# 1
|
||||
|
||||
sub %i7, 4, %o0 ! get to jmpslot through pc
|
||||
ld [%i7+4], %o1 ! get relocation index
|
||||
sethi %hi(0x3fffff), %o2 ! -> reloc_index & 0x003fffff
|
||||
or %o2, %lo(0x3fffff), %o2 ! [internal]
|
||||
call _binder ! and call binder(jsp, reloc_index)
|
||||
and %o1, %o2, %o1
|
||||
|
||||
mov %o0, %g1 ! return value == function address
|
||||
|
||||
restore ! get rid of our context
|
||||
jmp %g1 ! and go.
|
||||
restore ! and the jmpslot context
|
||||
nop
|
||||
|
||||
.seg "data" ! [internal]
|
||||
|
@ -1,17 +0,0 @@
|
||||
/* $NetBSD: md-static-funcs.c,v 1.3 1998/10/19 03:09:33 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Called by ld.so when onanating.
|
||||
* This *must* be a static function, so it is not called through a jmpslot.
|
||||
*/
|
||||
|
||||
static void
|
||||
md_relocate_simple(r, relocation, addr)
|
||||
struct relocation_info *r;
|
||||
long relocation;
|
||||
char *addr;
|
||||
{
|
||||
if (r->r_relative)
|
||||
*(long *)addr += relocation;
|
||||
}
|
||||
|
@ -1,411 +0,0 @@
|
||||
/* $NetBSD: md.c,v 1.12 1998/10/31 09:04:29 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Get relocation addend corresponding to relocation record RP
|
||||
* from address ADDR
|
||||
*/
|
||||
long
|
||||
md_get_addend(rp, addr)
|
||||
struct relocation_info *rp;
|
||||
unsigned char *addr;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
return get_byte(addr);
|
||||
case 1:
|
||||
return get_short(addr);
|
||||
case 2:
|
||||
if (rp->r_baserel) {
|
||||
long addend = get_long(addr);
|
||||
if (rp->r_pcrel) {
|
||||
addend += rp->r_address + 4;
|
||||
if (addend)
|
||||
put_long(addr, -(rp->r_address+4));
|
||||
}
|
||||
return addend;
|
||||
}
|
||||
return get_long(addr);
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put RELOCATION at ADDR according to relocation record RP.
|
||||
*/
|
||||
void
|
||||
md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
case 2:
|
||||
#ifndef RTLD
|
||||
if (rp->r_baserel) {
|
||||
relocation += got_symbol->value + get_long(addr);
|
||||
if (rp->r_copy)
|
||||
put_byte(addr-1, 0x10 | get_byte(addr-1));
|
||||
}
|
||||
#endif
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
default:
|
||||
errx(1, "Unsupported relocation size: %x",
|
||||
RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine dependent part of claim_rrs_reloc().
|
||||
* Set RRS relocation type.
|
||||
*/
|
||||
int
|
||||
md_make_reloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = rp->r_length;
|
||||
|
||||
if (RELOC_PCREL_P(rp))
|
||||
r->r_pcrel = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
if (type & RELTYPE_COPY)
|
||||
r->r_copy = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
|
||||
* to the binder slot (which is at offset 0 of the PLT).
|
||||
*/
|
||||
void
|
||||
md_make_jmpslot(sp, offset, index)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
long index;
|
||||
{
|
||||
/*
|
||||
* On VAX a branch offset given in immediate mode is relative to
|
||||
* the end of the address itself.
|
||||
*/
|
||||
u_long fudge = - (offset + 9);
|
||||
|
||||
sp->mask = 0x0000; /* no registers */
|
||||
sp->insn[0] = 0x01; /* nop */
|
||||
sp->insn[1] = 0x16; /* jsb */
|
||||
sp->insn[2] = 0xef; /* L^(pc) */
|
||||
sp->insn[3] = (fudge >> 0) & 0xff;
|
||||
sp->insn[4] = (fudge >> 8) & 0xff;
|
||||
sp->insn[5] = (fudge >> 16) & 0xff;
|
||||
sp->insn[6] = (fudge >> 24) & 0xff;
|
||||
sp->insn[7] = 0x00; /* halt */
|
||||
sp->reloc_index = index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a "direct" transfer (ie. not through the run-time binder) from
|
||||
* jmpslot at OFFSET to ADDR. Used by `ld' when the SYMBOLIC flag is on,
|
||||
* and by `ld.so' after resolving the symbol.
|
||||
* On the VAX, we use a PC relative JMP instruction, so no
|
||||
* further RRS relocations will be necessary for such a jmpslot.
|
||||
*/
|
||||
void
|
||||
md_fix_jmpslot(sp, offset, addr, first)
|
||||
jmpslot_t *sp;
|
||||
long offset;
|
||||
u_long addr;
|
||||
int first;
|
||||
{
|
||||
u_long fudge = addr - (offset + 9);
|
||||
|
||||
if (first) {
|
||||
sp->mask = 0x0101; /* NOP NOP */
|
||||
sp->insn[0] = 0x01; /* nop */
|
||||
sp->insn[1] = 0x17; /* jmp */
|
||||
} else {
|
||||
#ifdef RTLD
|
||||
sp->mask = *(u_int16_t *) addr;
|
||||
sp->insn[0] = 0x01; /* nop */
|
||||
sp->insn[1] = 0x17; /* jmp */
|
||||
fudge += 2; /* skip entry mask */
|
||||
#else
|
||||
sp->mask = 0x0000;
|
||||
sp->insn[0] = 0xfa; /* callg */
|
||||
sp->insn[1] = 0x6c; /* (ap) */
|
||||
#endif
|
||||
}
|
||||
sp->insn[2] = 0xef; /* L^(pc) */
|
||||
sp->insn[3] = (fudge >> 0) & 0xff;
|
||||
sp->insn[4] = (fudge >> 8) & 0xff;
|
||||
sp->insn[5] = (fudge >> 16) & 0xff;
|
||||
sp->insn[6] = (fudge >> 24) & 0xff;
|
||||
sp->insn[7] = 0x04; /* ret */
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the relocation record for a RRS jmpslot.
|
||||
*/
|
||||
void
|
||||
md_make_jmpreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
jmpslot_t *sp;
|
||||
|
||||
/*
|
||||
* Fix relocation address to point to the correct
|
||||
* location within this jmpslot.
|
||||
*/
|
||||
r->r_address += sizeof(sp->mask);
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2; /* 4 bytes */
|
||||
|
||||
/* Set relocation type */
|
||||
r->r_jmptable = 1;
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS GOT relocation.
|
||||
*/
|
||||
void
|
||||
md_make_gotreloc(rp, r, type)
|
||||
struct relocation_info *rp, *r;
|
||||
int type;
|
||||
{
|
||||
r->r_baserel = 1;
|
||||
|
||||
if (type & RELTYPE_RELATIVE)
|
||||
r->r_relative = 1;
|
||||
|
||||
/* Relocation size */
|
||||
r->r_length = 2; /* 4 bytes */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set relocation type for a RRS copy operation.
|
||||
*/
|
||||
void
|
||||
md_make_cpyreloc(rp, r)
|
||||
struct relocation_info *rp, *r;
|
||||
{
|
||||
/* Relocation size */
|
||||
r->r_length = 2; /* 4 bytes */
|
||||
|
||||
r->r_copy = 1;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
int
|
||||
md_convert_textreloc(r)
|
||||
struct relocation_info *r;
|
||||
{
|
||||
if (r->r_length != 2 || !r->r_pcrel || !r->r_copy)
|
||||
return 0;
|
||||
|
||||
r->r_baserel = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
md_set_breakpoint(where, savep)
|
||||
long where;
|
||||
long *savep;
|
||||
{
|
||||
*savep = *(long *)where;
|
||||
*(char *)where = BPT;
|
||||
}
|
||||
|
||||
#ifndef RTLD
|
||||
|
||||
#ifdef FreeBSD
|
||||
int netzmagic;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize (output) exec header such that useful values are
|
||||
* obtained from subsequent N_*() macro evaluations.
|
||||
*/
|
||||
void
|
||||
md_init_header(hp, magic, flags)
|
||||
struct exec *hp;
|
||||
int magic, flags;
|
||||
{
|
||||
#ifdef NetBSD
|
||||
if (oldmagic || magic == QMAGIC)
|
||||
hp->a_midmag = magic;
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_VAX, flags);
|
||||
#endif
|
||||
#ifdef FreeBSD
|
||||
if (oldmagic)
|
||||
hp->a_midmag = magic;
|
||||
else if (netzmagic)
|
||||
N_SETMAGIC_NET((*hp), magic, MID_VAX, flags);
|
||||
else
|
||||
N_SETMAGIC((*hp), magic, MID_VAX, flags);
|
||||
#endif
|
||||
|
||||
/* TEXT_START depends on the value of outheader.a_entry. */
|
||||
if (!(link_mode & SHAREABLE))
|
||||
hp->a_entry = PAGSIZ;
|
||||
}
|
||||
#endif /* RTLD */
|
||||
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
/*
|
||||
* Byte swap routines for cross-linking.
|
||||
*/
|
||||
|
||||
void
|
||||
md_swapin_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (!N_BADMAG(*h))
|
||||
skip = 1;
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_exec_hdr(h)
|
||||
struct exec *h;
|
||||
{
|
||||
/* NetBSD: Always leave magic alone */
|
||||
int skip = 1;
|
||||
#if 0
|
||||
if (N_GETMAGIC(*h) == OMAGIC)
|
||||
skip = 0;
|
||||
#endif
|
||||
|
||||
swap_longs((long *)h + skip, sizeof(*h)/sizeof(long) - skip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_swapin_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = ((int *)r)[1];
|
||||
r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
|
||||
r->r_pcrel = (bits & 1);
|
||||
r->r_length = (bits >> 1) & 3;
|
||||
r->r_extern = (bits >> 3) & 1;
|
||||
r->r_baserel = (bits >> 4) & 1;
|
||||
r->r_jmptable = (bits >> 5) & 1;
|
||||
r->r_relative = (bits >> 6) & 1;
|
||||
#ifdef N_SIZE
|
||||
r->r_copy = (bits >> 7) & 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_reloc(r, n)
|
||||
struct relocation_info *r;
|
||||
int n;
|
||||
{
|
||||
int bits;
|
||||
|
||||
for (; n; n--, r++) {
|
||||
r->r_address = md_swap_long(r->r_address);
|
||||
bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
|
||||
bits |= (r->r_pcrel & 1);
|
||||
bits |= (r->r_length & 3) << 1;
|
||||
bits |= (r->r_extern & 1) << 3;
|
||||
bits |= (r->r_baserel & 1) << 4;
|
||||
bits |= (r->r_jmptable & 1) << 5;
|
||||
bits |= (r->r_relative & 1) << 6;
|
||||
#ifdef N_SIZE
|
||||
bits |= (r->r_copy & 1) << 7;
|
||||
#endif
|
||||
((int *)r)[1] = bits;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_swapout_jmpslot(j, n)
|
||||
jmpslot_t *j;
|
||||
int n;
|
||||
{
|
||||
for (; n; n--, j++) {
|
||||
j->mask = md_swap_short(j->mask);
|
||||
j->reloc_index = md_swap_short(j->reloc_index);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NEED_SWAP */
|
@ -1,237 +0,0 @@
|
||||
/* $NetBSD: md.h,v 1.9 1998/10/31 09:04:29 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==sparc
|
||||
#define NEED_SWAP
|
||||
#endif
|
||||
|
||||
#define MAX_ALIGNMENT (sizeof (long))
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#define PAGSIZ __LDPGSZ
|
||||
#else
|
||||
#define PAGSIZ 1024
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) || defined(CROSS_LINKER)
|
||||
|
||||
#define N_SET_FLAG(ex,f) (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
|
||||
N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f)))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
|
||||
|
||||
#define N_BADMID(ex) \
|
||||
(N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE \
|
||||
&& N_GETMID(ex) != MID_VAX1K)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FreeBSD does it differently
|
||||
*/
|
||||
#ifdef FreeBSD
|
||||
#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
|
||||
(netzmagic == 0 ? \
|
||||
N_SETMAGIC(ex, \
|
||||
N_GETMAGIC(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG(ex)|(f)) : \
|
||||
N_SETMAGIC_NET(ex, \
|
||||
N_GETMAGIC_NET(ex), \
|
||||
MID_MACHINE, \
|
||||
N_GETFLAG_NET(ex)|(f)) ))
|
||||
|
||||
#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
|
||||
((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
|
||||
((N_GETFLAG(ex) & EX_DYNAMIC) ))
|
||||
#define N_BADMID(ex) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Should be handled by a.out.h ?
|
||||
*/
|
||||
#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
|
||||
#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
|
||||
#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
|
||||
|
||||
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
|
||||
#define RELOC_SYMBOLICS_THROUGH_JMPSLOT (0)
|
||||
#define RELOC_EXTERNAL_DATA_THROUGH_GOT_P(r) (md_convert_textreloc(r))
|
||||
#define JMPSLOT_NONEXTERN_ARE_INTERMODULE (1)
|
||||
#define JMPSLOT_NEEDS_RELOC (0)
|
||||
|
||||
#define md_got_reloc(r) (0)
|
||||
|
||||
#define md_get_rt_segment_addend(r,a) md_get_addend(r,a)
|
||||
|
||||
/* Width of a Global Offset Table entry */
|
||||
#define GOT_ENTRY_SIZE 4
|
||||
typedef int32_t got_t;
|
||||
|
||||
/*
|
||||
* .word ^M<reg-mask>
|
||||
* jsb L^addr
|
||||
* callg (ap), L^addr
|
||||
*/
|
||||
typedef struct jmpslot {
|
||||
u_short mask;
|
||||
u_char insn[8];
|
||||
u_short reloc_index;
|
||||
} jmpslot_t;
|
||||
|
||||
#define JMPSLOT_RELOC_MASK 0xffff
|
||||
#define BPT 0x0003 /* Set a breakpoint */
|
||||
|
||||
/*
|
||||
* Byte swap defs for cross linking
|
||||
*/
|
||||
|
||||
#if !defined(NEED_SWAP)
|
||||
|
||||
#define md_swapin_exec_hdr(h)
|
||||
#define md_swapout_exec_hdr(h)
|
||||
#define md_swapin_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n)
|
||||
#define md_swapin_reloc(r,n)
|
||||
#define md_swapout_reloc(r,n)
|
||||
#define md_swapin__dynamic(l)
|
||||
#define md_swapout__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d)
|
||||
#define md_swapout_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n)
|
||||
#define md_swapout_jmpslot(j,n)
|
||||
#define md_swapout_got(g,n)
|
||||
#define md_swapin_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#ifdef CROSS_LINKER
|
||||
|
||||
#define get_byte(p) ( ((unsigned char *)(p))[0] )
|
||||
|
||||
#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
|
||||
( ((unsigned char *)(p))[1] ) \
|
||||
)
|
||||
|
||||
#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
|
||||
( ((unsigned char *)(p))[1] << 16) | \
|
||||
( ((unsigned char *)(p))[2] << 8 ) | \
|
||||
( ((unsigned char *)(p))[3] ) \
|
||||
)
|
||||
|
||||
#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
|
||||
|
||||
#define put_short(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#define put_long(p, v) { ((unsigned char *)(p))[0] = \
|
||||
((((unsigned long)(v)) >> 24) & 0xff); \
|
||||
((unsigned char *)(p))[1] = \
|
||||
((((unsigned long)(v)) >> 16) & 0xff); \
|
||||
((unsigned char *)(p))[2] = \
|
||||
((((unsigned long)(v)) >> 8) & 0xff); \
|
||||
((unsigned char *)(p))[3] = \
|
||||
((((unsigned long)(v)) ) & 0xff); }
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
|
||||
/* Define IO byte swapping routines */
|
||||
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
void md_swapout_exec_hdr __P((struct exec *));
|
||||
void md_swapin_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_reloc __P((struct relocation_info *, int));
|
||||
void md_swapout_jmpslot __P((jmpslot_t *, int));
|
||||
|
||||
#define md_swapin_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapout_symbols(s,n) swap_symbols(s,n)
|
||||
#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
|
||||
#define md_swapin__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapout__dynamic(l) swap__dynamic(l)
|
||||
#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
|
||||
#define md_swapin_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapout_so_debug(d) swap_so_debug(d)
|
||||
#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
|
||||
#define md_swapin_sod(l,n) swapin_sod(l,n)
|
||||
#define md_swapout_sod(l,n) swapout_sod(l,n)
|
||||
#define md_swapout_got(g,n) swap_longs((long*)(g),n)
|
||||
#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
|
||||
|
||||
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
|
||||
|
||||
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
|
||||
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
|
||||
#else /* We need not swap, but must pay attention to alignment: */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#endif /* NEED_SWAP */
|
||||
|
||||
#else /* Not a cross linker: use native */
|
||||
|
||||
#define md_swap_short(x) (x)
|
||||
#define md_swap_long(x) (x)
|
||||
|
||||
#define get_byte(where) (*(char *)(where))
|
||||
#define get_short(where) (*(short *)(where))
|
||||
#define get_long(where) (*(long *)(where))
|
||||
|
||||
#define put_byte(where,what) (*(char *)(where) = (what))
|
||||
#define put_short(where,what) (*(short *)(where) = (what))
|
||||
#define put_long(where,what) (*(long *)(where) = (what))
|
||||
|
||||
#endif /* CROSS_LINKER */
|
@ -1,104 +0,0 @@
|
||||
/* $NetBSD: mdprologue.S,v 1.9 1998/10/31 08:59:58 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Matt Thomas <matt@3am-software.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* i386 run-time link editor entry points.
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl _binder, _binder_entry
|
||||
.globl _rtl
|
||||
.type _rtl,@function
|
||||
|
||||
/*
|
||||
* _rtl(int version, struct crt_ldso *crtp)
|
||||
*/
|
||||
|
||||
.align 2
|
||||
_rtl: /* crt0 calls us here */
|
||||
.word 0 /* no registers to save */
|
||||
movl 8(ap),r0 /* load crtp into r0 */
|
||||
/* setup arguments for rtld() */
|
||||
/*
|
||||
* Add the 1st entry in the GOT (e.g. __DYNAMIC) to the base
|
||||
* address of ld.so and pushd that onto the stack.
|
||||
*/
|
||||
addl3 __GLOBAL_OFFSET_TABLE_,(r0),-(sp)
|
||||
pushl r0 /* 2nd arg == crtp */
|
||||
pushl 4(ap) /* 1st arg == version */
|
||||
calls $3,_rtld /* _rtld(version, crtp, DYNAMIC) */
|
||||
movpsl -(sp) /* flush the instruction cache */
|
||||
pushab 1f /* by issuing an */
|
||||
rei /* rei. */
|
||||
1: ret
|
||||
|
||||
/*
|
||||
* First call to a procedure generally comes through here for binding.
|
||||
* We got here via JSB so now (sp) is inside our jmpslot_t. So we
|
||||
* simply preserve our registers, push the address of jmpslot_t for
|
||||
* _binder. Save the address we are supported to call (which was
|
||||
* returned in R0) in the stack location that the JSB used to store
|
||||
* its return address (which we don't care about anymore).
|
||||
*
|
||||
* Check to see the function has a zero entry mask. Since we
|
||||
* were called with a zero entry, if the function we need to call
|
||||
* also has a zero entry mask, we can let it use our call frame
|
||||
* and jump inside of it to its first instruction. Otherwise we'll
|
||||
* call the actual function the slow way and return.
|
||||
*
|
||||
* The above optimization is required in order for vfork(2) to
|
||||
* work properly in shared libraries. DO NOT REMOVE IT.
|
||||
*/
|
||||
.align 1
|
||||
.type _binder_entry,@label
|
||||
_binder_entry:
|
||||
pushr $0x3f /* save r0 to r5 */
|
||||
#ifdef DEBUG
|
||||
pushl $29
|
||||
pushab LC1
|
||||
pushl $2
|
||||
calls $3,_write
|
||||
#endif
|
||||
subl3 $8, 24(sp), -(sp) /* point to beginning of jmpslot */
|
||||
bicl2 $3, (sp)
|
||||
calls $1, _binder /* _binder(jsp) */
|
||||
movpsl -(sp) /* flush the instruction cache */
|
||||
pushab 1f /* by issuing an */
|
||||
rei /* rei. */
|
||||
1: movl r0, 24(sp) /* save return address onto stack */
|
||||
popr $0x3f /* restore r0 to r5 */
|
||||
tstw *(sp) /* does the entry mask save any regs */
|
||||
bneq 2f /* yes? do it the hard way */
|
||||
addl2 $2,(sp) /* no? skip past the mask */
|
||||
rsb /* and jump to it */
|
||||
2: callg (ap), *(sp)+ /* return value from _binder() == actual */
|
||||
ret
|
||||
#ifdef DEBUG
|
||||
LC1: .asciz "ld.so: entered _binder_entry\n"
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user