Add support for mips.

This commit is contained in:
mhitch 1998-03-25 04:12:32 +00:00
parent 0fb478e609
commit 082edecc20
17 changed files with 875 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: link_elf.h,v 1.1 1996/12/16 20:37:59 cgd Exp $ */
/* $NetBSD: link_elf.h,v 1.2 1998/03/25 04:13:01 mhitch Exp $ */
/*
* This only exists for GDB.
@ -10,6 +10,9 @@
struct link_map {
caddr_t l_addr; /* Base Address of library */
#ifdef __mips__
caddr_t l_offs; /* Load Offset of library */
#endif
const char *l_name; /* Absolute Path to Library */
void *l_ld; /* Pointer to .dynamic in memory */
struct link_map *l_next, *l_prev; /* linked list of of mapped libs */

View File

@ -1,9 +1,8 @@
# $NetBSD: Makefile,v 1.11 1998/02/23 10:09:32 jonathan Exp $
# $NetBSD: Makefile,v 1.12 1998/03/25 04:13:01 mhitch Exp $
.include <bsd.own.mk> # for OBJECT_FMT definition
.if ((${OBJECT_FMT} == "ELF") && !defined(NOSHLIB)) && \
(${MACHINE_ARCH} != "mips") # mips uses non-native ld.so
.if ((${OBJECT_FMT} == "ELF") && !defined(NOSHLIB))
PROG= ld.elf_so
.endif

View File

@ -1,4 +1,4 @@
$NetBSD: README,v 1.1 1996/12/16 20:37:56 cgd Exp $
$NetBSD: README,v 1.2 1998/03/25 04:13:01 mhitch Exp $
BUGS/PROBLEMS:
@ -38,7 +38,7 @@ BUGS/PROBLEMS:
TO DO:
* Support for other platforms (e.g. mips)
* Support for other platforms
* Support for coexistance of 32-bit and 64-bit ELF on platforms that can
do that.
@ -47,3 +47,5 @@ TO DO:
* Possible support for ldd (standalone operation) and program loading
a la the glibc shared loader.
* Support for relocating ld.elf_so on mips

View File

@ -0,0 +1,15 @@
# $NetBSD: Makefile.inc,v 1.1 1998/03/25 04:12:32 mhitch Exp $
SRCS+= rtld_start.S mips_reloc.c
CPPFLAGS+= -mabicalls -G0 -fPIC -DELFSIZE=32 -I${.CURDIR}
.if (${MACHINE} == "newsmips")
# UGH! ld.so.script specifies little-endian; need to override that here
LDFLAGS+= -EB
.endif
LDFLAGS+= -Bshareable -Bsymbolic -e .rtld_start --script mips/ld.so.script
# Link ld.so for backward compatibility with old binaries
LINKS+= ${DESTDIR}/usr/libexec/${PROG} ${DESTDIR}/usr/libexec/ld.so

View File

@ -0,0 +1,152 @@
/* $NetBSD: ld.so.script,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/* ldscript for MIPS ld.elf_so */
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/mips-dec-netbsd/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x5ffe0000 + SIZEOF_HEADERS;
.reginfo : { *(.reginfo) }
.dynamic : { *(.dynamic) }
.dynstr : { *(.dynstr) }
.dynsym : { *(.dynsym) }
.hash : { *(.hash) }
.rel.text :
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text :
{ *(.rela.text) *(.rela.gnu.linkonce.t*) }
.rel.data :
{ *(.rel.data) *(.rel.gnu.linkonce.d*) }
.rela.data :
{ *(.rela.data) *(.rela.gnu.linkonce.d*) }
.rel.rodata :
{ *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
.rela.rodata :
{ *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
.init : { *(.init) } =0
.text :
{
_ftext = . ;
*(.text)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
} =0
_etext = .;
PROVIDE (etext = .);
.fini : { *(.fini) } =0
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = 0x10000000;
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
/* "Fix" for ld.so on NetBSD:
The binutils 2.8.1 ld aligns the data segment at 1MB (0x40000), but
the alignment specified in the ELF program headers specifies 4K
(0x1000). The NetBSD kernel forces the data section to be loaded
by the alignment in the program header, which thus does not match
the alignment done by ld. This line is the only difference from
the script built in to ld: force the data section alignment to
match what bfd puts into the program headers. */
. = ALIGN(0x1000) + (ALIGN(8) & (0x1000 - 1));
.data :
{
_fdata = . ;
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
.data1 : { *(.data1) }
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
_gp = ALIGN(16) + 0x7ff0;
.got :
{
*(.got.plt) *(.got)
}
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata : { *(.sdata) }
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
_fbss = .;
.sbss : { *(.sbss) *(.scommon) }
.bss :
{
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
}

View File

@ -0,0 +1,123 @@
/* $NetBSD: mips_reloc.c,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
* 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.
*/
#include <stdarg.h>
#include <sys/types.h>
#include "debug.h"
#include "rtld.h"
/*
* Relocate a MIPS GOT
*/
void
_rtld_relocate_mips_got(obj)
Obj_Entry *obj;
{
Elf_Addr *got = obj->pltgot;
const Elf_Sym *sym = obj->symtab;
const Elf_Sym *def;
const Obj_Entry *defobj;
int i;
i = (got[1] & 0x80000000) ? 2 : 1;
/* Relocate the local GOT entries */
while (i < obj->local_gotno)
got[i++] += (Elf_Word)obj->relocbase;
got += obj->local_gotno;
i = obj->symtabno - obj->gotsym;
sym += obj->gotsym;
/* Now do the global GOT entries */
while (i--) {
def = _rtld_find_symdef(_rtld_objlist, 0,
sym->st_name + obj->strtab, obj, &defobj, true);
if (def != NULL) {
if (sym->st_shndx == Elf_eshn_undefined) {
#if 0 /* These don't seem to work? */
if (ELF_SYM_TYPE(sym->st_info) ==
Elf_estt_func) {
if (sym->st_value)
*got = sym->st_value +
(Elf_Word)obj->relocbase;
else
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else
#endif
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else if (sym->st_shndx == Elf_eshn_common) {
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else if (ELF_SYM_TYPE(sym->st_info) == Elf_estt_func
&& *got != sym->st_value) {
*got += (Elf_Word)obj->relocbase;
} else if (ELF_SYM_TYPE(sym->st_info) ==
Elf_estt_section && ELF_SYM_BIND(sym->st_info) ==
Elf_estb_global) {
if (sym->st_shndx == Elf_eshn_absolute)
*got = sym->st_value +
(Elf_Word)obj->relocbase;
/* else SGI stuff ignored */
} else
*got = def->st_value +
(Elf_Word)defobj->relocbase;
}
++sym;
++got;
}
}
/*
* _rtld_bind_mips(symbol_index, return_address, old_gp, stub_return_addr)
*/
caddr_t
_rtld_bind_mips(a0, a1, a2, a3)
Elf_Word a0;
Elf_Addr a1, a2, a3;
{
Elf_Addr *u = (Elf_Addr *)(a2 - 0x7ff0);
Obj_Entry *obj = (Obj_Entry *)(u[1] & 0x7fffffff);
const Elf_Sym *def;
const Obj_Entry *defobj;
def = _rtld_find_symdef(_rtld_objlist, a0 << 8, NULL, obj, &defobj,
true);
if (def) {
u[obj->local_gotno + a0 - obj->gotsym] = (Elf_Addr)
(def->st_value + defobj->relocbase);
return((caddr_t)(def->st_value + defobj->relocbase));
}
return(NULL); /* XXX */
}

View File

@ -0,0 +1,88 @@
/* $NetBSD: rtld_start.S,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
* 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.
*/
#include <machine/regdef.h>
#include <mips/asm.h>
LEAF(rtld_start)
.set noreorder
.cpload t9
addu sp, sp, -12 # adjust stack pointer
.cprestore 0 # 0(sp) for gp
# 4(sp) for atexit
# 8(sp) for obj_main
move s0,a0 # save stack pointer from a0
addu a0, sp, 4 # _rtld argument
jal _C_LABEL(_rtld) # v0 = _rtld(sp)
move s1,a3 # save ps_strings pointer
lw a1, 4(sp) # our atexit function
lw a2, 8(sp) # obj_main entry
addu sp, sp,12 # readjust stack
move a0,s0 # stack pointer
move t9,v0
jr t9 # _start(sp, cleanup, obj);
move a3,s1 # restore ps_strings
END(rtld_start)
.globl _rtld_bind_start
.ent _rtld_bind_start
_rtld_bind_start:
move v1,gp # save old GP
add t9,8 # modify T9 to point at .cpload
.cpload t9
subu sp,40 # save arguments and sp value in stack
.cprestore 32
sw t7,36(sp)
sw a0,12(sp)
sw a1,16(sp)
sw a2,20(sp)
sw a3,24(sp)
sw s0,28(sp)
move s0,sp
move a0,t8 # symbol index
move a1,t7 # old RA
move a2,v1 # old GP
move a3,ra # current RA
jal _C_LABEL(_rtld_bind_mips)
nop
move sp,s0
lw ra,36(sp)
lw a0,12(sp)
lw a1,16(sp)
lw a2,20(sp)
lw a3,24(sp)
lw s0,28(sp)
addu sp,40
move t9,v0
jr t9
nop
.end _rtld_bind_start

View File

@ -1,4 +1,4 @@
/* $NetBSD: headers.c,v 1.1 1996/12/16 20:37:58 cgd Exp $ */
/* $NetBSD: headers.c,v 1.2 1998/03/25 04:13:01 mhitch Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -200,6 +200,26 @@ _rtld_digest_dynamic(
dynp->d_un.d_ptr = (Elf_Addr) &_rtld_debug;
#endif
break;
#if defined(__mips__)
case DT_MIPS_LOCAL_GOTNO:
obj->local_gotno = dynp->d_un.d_val;
break;
case DT_MIPS_SYMTABNO:
obj->symtabno = dynp->d_un.d_val;
break;
case DT_MIPS_GOTSYM:
obj->gotsym = dynp->d_un.d_val;
break;
case DT_MIPS_RLD_MAP:
#ifdef RTLD_LOADER
*((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) &_rtld_debug;
#endif
break;
#endif
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: link.h,v 1.1 1996/12/16 20:37:59 cgd Exp $ */
/* $NetBSD: link.h,v 1.2 1998/03/25 04:13:01 mhitch Exp $ */
/*
* This only exists for GDB.
@ -10,6 +10,9 @@
struct link_map {
caddr_t l_addr; /* Base Address of library */
#ifdef __mips__
caddr_t l_offs; /* Load Offset of library */
#endif
const char *l_name; /* Absolute Path to Library */
void *l_ld; /* Pointer to .dynamic in memory */
struct link_map *l_next, *l_prev; /* linked list of of mapped libs */

View File

@ -0,0 +1,15 @@
# $NetBSD: Makefile.inc,v 1.1 1998/03/25 04:12:32 mhitch Exp $
SRCS+= rtld_start.S mips_reloc.c
CPPFLAGS+= -mabicalls -G0 -fPIC -DELFSIZE=32 -I${.CURDIR}
.if (${MACHINE} == "newsmips")
# UGH! ld.so.script specifies little-endian; need to override that here
LDFLAGS+= -EB
.endif
LDFLAGS+= -Bshareable -Bsymbolic -e .rtld_start --script mips/ld.so.script
# Link ld.so for backward compatibility with old binaries
LINKS+= ${DESTDIR}/usr/libexec/${PROG} ${DESTDIR}/usr/libexec/ld.so

View File

@ -0,0 +1,152 @@
/* $NetBSD: ld.so.script,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/* ldscript for MIPS ld.elf_so */
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/mips-dec-netbsd/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x5ffe0000 + SIZEOF_HEADERS;
.reginfo : { *(.reginfo) }
.dynamic : { *(.dynamic) }
.dynstr : { *(.dynstr) }
.dynsym : { *(.dynsym) }
.hash : { *(.hash) }
.rel.text :
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text :
{ *(.rela.text) *(.rela.gnu.linkonce.t*) }
.rel.data :
{ *(.rel.data) *(.rel.gnu.linkonce.d*) }
.rela.data :
{ *(.rela.data) *(.rela.gnu.linkonce.d*) }
.rel.rodata :
{ *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
.rela.rodata :
{ *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
.init : { *(.init) } =0
.text :
{
_ftext = . ;
*(.text)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.mips16.fn.*)
*(.mips16.call.*)
} =0
_etext = .;
PROVIDE (etext = .);
.fini : { *(.fini) } =0
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = 0x10000000;
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
/* "Fix" for ld.so on NetBSD:
The binutils 2.8.1 ld aligns the data segment at 1MB (0x40000), but
the alignment specified in the ELF program headers specifies 4K
(0x1000). The NetBSD kernel forces the data section to be loaded
by the alignment in the program header, which thus does not match
the alignment done by ld. This line is the only difference from
the script built in to ld: force the data section alignment to
match what bfd puts into the program headers. */
. = ALIGN(0x1000) + (ALIGN(8) & (0x1000 - 1));
.data :
{
_fdata = . ;
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
}
.data1 : { *(.data1) }
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
_gp = ALIGN(16) + 0x7ff0;
.got :
{
*(.got.plt) *(.got)
}
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata : { *(.sdata) }
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
_fbss = .;
.sbss : { *(.sbss) *(.scommon) }
.bss :
{
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
}

View File

@ -0,0 +1,123 @@
/* $NetBSD: mips_reloc.c,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
* 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.
*/
#include <stdarg.h>
#include <sys/types.h>
#include "debug.h"
#include "rtld.h"
/*
* Relocate a MIPS GOT
*/
void
_rtld_relocate_mips_got(obj)
Obj_Entry *obj;
{
Elf_Addr *got = obj->pltgot;
const Elf_Sym *sym = obj->symtab;
const Elf_Sym *def;
const Obj_Entry *defobj;
int i;
i = (got[1] & 0x80000000) ? 2 : 1;
/* Relocate the local GOT entries */
while (i < obj->local_gotno)
got[i++] += (Elf_Word)obj->relocbase;
got += obj->local_gotno;
i = obj->symtabno - obj->gotsym;
sym += obj->gotsym;
/* Now do the global GOT entries */
while (i--) {
def = _rtld_find_symdef(_rtld_objlist, 0,
sym->st_name + obj->strtab, obj, &defobj, true);
if (def != NULL) {
if (sym->st_shndx == Elf_eshn_undefined) {
#if 0 /* These don't seem to work? */
if (ELF_SYM_TYPE(sym->st_info) ==
Elf_estt_func) {
if (sym->st_value)
*got = sym->st_value +
(Elf_Word)obj->relocbase;
else
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else
#endif
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else if (sym->st_shndx == Elf_eshn_common) {
*got = def->st_value +
(Elf_Word)defobj->relocbase;
} else if (ELF_SYM_TYPE(sym->st_info) == Elf_estt_func
&& *got != sym->st_value) {
*got += (Elf_Word)obj->relocbase;
} else if (ELF_SYM_TYPE(sym->st_info) ==
Elf_estt_section && ELF_SYM_BIND(sym->st_info) ==
Elf_estb_global) {
if (sym->st_shndx == Elf_eshn_absolute)
*got = sym->st_value +
(Elf_Word)obj->relocbase;
/* else SGI stuff ignored */
} else
*got = def->st_value +
(Elf_Word)defobj->relocbase;
}
++sym;
++got;
}
}
/*
* _rtld_bind_mips(symbol_index, return_address, old_gp, stub_return_addr)
*/
caddr_t
_rtld_bind_mips(a0, a1, a2, a3)
Elf_Word a0;
Elf_Addr a1, a2, a3;
{
Elf_Addr *u = (Elf_Addr *)(a2 - 0x7ff0);
Obj_Entry *obj = (Obj_Entry *)(u[1] & 0x7fffffff);
const Elf_Sym *def;
const Obj_Entry *defobj;
def = _rtld_find_symdef(_rtld_objlist, a0 << 8, NULL, obj, &defobj,
true);
if (def) {
u[obj->local_gotno + a0 - obj->gotsym] = (Elf_Addr)
(def->st_value + defobj->relocbase);
return((caddr_t)(def->st_value + defobj->relocbase));
}
return(NULL); /* XXX */
}

View File

@ -0,0 +1,88 @@
/* $NetBSD: rtld_start.S,v 1.1 1998/03/25 04:12:32 mhitch Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
* 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.
*/
#include <machine/regdef.h>
#include <mips/asm.h>
LEAF(rtld_start)
.set noreorder
.cpload t9
addu sp, sp, -12 # adjust stack pointer
.cprestore 0 # 0(sp) for gp
# 4(sp) for atexit
# 8(sp) for obj_main
move s0,a0 # save stack pointer from a0
addu a0, sp, 4 # _rtld argument
jal _C_LABEL(_rtld) # v0 = _rtld(sp)
move s1,a3 # save ps_strings pointer
lw a1, 4(sp) # our atexit function
lw a2, 8(sp) # obj_main entry
addu sp, sp,12 # readjust stack
move a0,s0 # stack pointer
move t9,v0
jr t9 # _start(sp, cleanup, obj);
move a3,s1 # restore ps_strings
END(rtld_start)
.globl _rtld_bind_start
.ent _rtld_bind_start
_rtld_bind_start:
move v1,gp # save old GP
add t9,8 # modify T9 to point at .cpload
.cpload t9
subu sp,40 # save arguments and sp value in stack
.cprestore 32
sw t7,36(sp)
sw a0,12(sp)
sw a1,16(sp)
sw a2,20(sp)
sw a3,24(sp)
sw s0,28(sp)
move s0,sp
move a0,t8 # symbol index
move a1,t7 # old RA
move a2,v1 # old GP
move a3,ra # current RA
jal _C_LABEL(_rtld_bind_mips)
nop
move sp,s0
lw ra,36(sp)
lw a0,12(sp)
lw a1,16(sp)
lw a2,20(sp)
lw a3,24(sp)
lw s0,28(sp)
addu sp,40
move t9,v0
jr t9
nop
.end _rtld_bind_start

View File

@ -1,4 +1,4 @@
/* $NetBSD: reloc.c,v 1.1 1996/12/16 20:38:02 cgd Exp $ */
/* $NetBSD: reloc.c,v 1.2 1998/03/25 04:13:01 mhitch Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -52,6 +52,7 @@
#include "debug.h"
#include "rtld.h"
#ifdef __alpha__
static int
_rtld_do_copy_relocation(
const Obj_Entry *dstobj,
@ -80,6 +81,7 @@ _rtld_do_copy_relocation(
memcpy(dstaddr, srcaddr, size);
return 0;
}
#endif /* __alpha__ */
/*
* Process the special R_xxx_COPY relocations in the main program. These
@ -94,6 +96,7 @@ _rtld_do_copy_relocations(
{
assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
#ifdef __alpha__ /* jrs */
if (dstobj->rel != NULL) {
const Elf_Rel *rel;
for (rel = dstobj->rel; rel < dstobj->rellim; ++rel) {
@ -117,6 +120,7 @@ _rtld_do_copy_relocations(
}
}
}
#endif /* jrs */
return 0;
}
@ -182,7 +186,7 @@ _rtld_relocate_nonplt_object(
*where = tmp_value;
break;
}
#endif
/*#endif*/
case R_TYPE(GLOB_DAT):
{
@ -209,7 +213,6 @@ _rtld_relocate_nonplt_object(
break;
}
case R_TYPE(COPY): {
/*
* These are deferred until all other relocations have
@ -224,6 +227,33 @@ _rtld_relocate_nonplt_object(
}
break;
}
#endif /* __alpha__ */
#ifdef __mips__
case R_TYPE(REL32): {
/* 32-bit PC-relative reference */
const Elf_Sym *def;
const Obj_Entry *defobj;
def = obj->symtab + ELF_R_SYM(rela->r_info);
if (ELF_SYM_BIND(def->st_info) == Elf_estb_local &&
(ELF_SYM_TYPE(def->st_info) == Elf_estt_section ||
ELF_SYM_TYPE(def->st_info) == Elf_estt_notype)) {
*where += (Elf_Addr) obj->relocbase;
} else {
/* XXX maybe do something re: bootstrapping? */
def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
&defobj, false);
if (def == NULL)
return -1;
*where += (Elf_Addr)(defobj->relocbase + def->st_value);
}
break;
}
#endif /* mips */
default: {
const Elf_Sym *def;
@ -252,6 +282,8 @@ _rtld_relocate_plt_object(
Elf_Addr new_value;
/* Fully resolve procedure addresses now */
#if defined(__alpha__) /* (jrs) */
if (bind_now || obj->pltgot == NULL) {
const Elf_Sym *def;
const Obj_Entry *defobj;
@ -268,7 +300,9 @@ _rtld_relocate_plt_object(
defobj->strtab + def->st_name, obj->path,
new_value, defobj->path);
#endif
} else if (!obj->mainprog) {
} else
#endif /* __alpha__ (jrs) */
if (!obj->mainprog) {
/* Just relocate the GOT slots pointing into the PLT */
new_value = *where + (Elf_Addr) (obj->relocbase);
} else {
@ -352,6 +386,12 @@ _rtld_relocate_objects(
Elf_RelA ourrela;
ourrela.r_info = rel->r_info;
ourrela.r_offset = rel->r_offset;
#if defined(__mips__)
/* rel->r_offset is not valid on mips? */
if (ELF_R_TYPE(ourrela.r_info) == R_TYPE(NONE))
ourrela.r_addend = 0;
else
#endif
ourrela.r_addend = *(Elf_Word *) (obj->relocbase + rel->r_offset);
if (_rtld_relocate_nonplt_object(obj, &ourrela) < 0)
@ -423,6 +463,13 @@ _rtld_relocate_objects(
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
/* Identify this shared object */
obj->pltgot[3] = (Elf_Addr) obj;
#endif
#if defined(__mips__)
_rtld_relocate_mips_got(obj);
obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
/* XXX only if obj->pltgot[1] & 0x80000000 ?? */
obj->pltgot[1] |= (Elf_Addr) obj;
#endif
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.c,v 1.5 1997/10/08 08:55:37 mrg Exp $ */
/* $NetBSD: rtld.c,v 1.6 1998/03/25 04:13:02 mhitch Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -138,7 +138,12 @@ _rtld_init(
_rtld_objself.path = _rtld_path;
_rtld_objself.rtld = true;
_rtld_objself.mapbase = mapbase;
#ifdef __mips__
/* mips ld.so currently linked at load address, so no relocation needed */
_rtld_objself.relocbase = 0;
#else
_rtld_objself.relocbase = mapbase;
#endif
_rtld_objself.pltgot = NULL;
#ifdef OLD_GOT
_rtld_objself.dynamic = (Elf_Dyn *) _GLOBAL_OFFSET_TABLE_[0];
@ -152,7 +157,9 @@ _rtld_init(
_rtld_objself.pltgot = NULL;
#endif
assert(_rtld_objself.needed == NULL);
#ifndef __mips__ /* no relocation for mips */
assert(!_rtld_objself.textrel);
#endif
/* Set up the _rtld_objlist pointer, so that rtld symbols can be found. */
_rtld_objlist = &_rtld_objself;
@ -252,8 +259,10 @@ _rtld(
#ifdef RTLD_DEBUG
xprintf("_ctype_ is %p\n", _ctype_);
#endif
#ifdef DEBUG
if (aux_info[AUX_debug] != NULL) /* Set debugging level */
debug = aux_info[AUX_debug]->au_v;
#endif
__progname = _rtld_objself.path;
environ = env;
@ -264,9 +273,11 @@ _rtld(
if (ld_bind_now != NULL && *ld_bind_now != '\0')
bind_now = true;
if (_rtld_trust) {
#ifdef DEBUG
const char *ld_debug = getenv("LD_DEBUG");
if (ld_debug != NULL && *ld_debug != '\0')
debug = 1;
#endif
_rtld_add_paths(&_rtld_paths, getenv("LD_LIBRARY_PATH"));
}
@ -543,6 +554,10 @@ _rtld_linkmap_add(
obj->linkmap.l_name = obj->path;
obj->linkmap.l_addr = obj->mapbase;
obj->linkmap.l_ld = obj->dynamic;
#ifdef __mips__
/* GDB needs load offset on MIPS to use the symbols */
obj->linkmap.l_offs = obj->relocbase;
#endif
if (_rtld_debug.r_map == NULL) {
_rtld_debug.r_map = l;
@ -571,4 +586,3 @@ _rtld_linkmap_delete(
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.h,v 1.3 1997/02/14 22:30:25 cgd Exp $ */
/* $NetBSD: rtld.h,v 1.4 1998/03/25 04:13:02 mhitch Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -122,6 +122,11 @@ typedef struct Struct_Obj_Entry {
const Elf_Sym *symtab; /* Symbol table */
const char *strtab; /* String table */
unsigned long strsize; /* Size in bytes of string table */
#if defined(__mips__)
Elf_Word local_gotno; /* Number of local GOT entries */
Elf_Word symtabno; /* Number of dynamic symbols */
Elf_Word gotsym; /* First dynamic symbol in GOT */
#endif
const Elf_Word *buckets; /* Hash table buckets array */
unsigned long nbuckets; /* Number of buckets */
@ -208,4 +213,10 @@ extern const Elf_Sym *_rtld_find_symdef(const Obj_Entry *, Elf_Word,
/* map_object.c */
extern Obj_Entry *_rtld_map_object(const char *, int);
#if defined(__mips__)
/* mips_reloc.c */
extern void _rtld_relocate_mips_got(Obj_Entry *);
extern caddr_t _rtld_bind_mips (Elf_Word, Elf_Addr, Elf_Addr, Elf_Addr);
#endif
#endif /* } */

View File

@ -1,4 +1,4 @@
/* $NetBSD: symbol.c,v 1.1 1996/12/16 20:38:06 cgd Exp $ */
/* $NetBSD: symbol.c,v 1.2 1998/03/25 04:13:02 mhitch Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -102,8 +102,12 @@ _rtld_symlook_obj(
#endif
if (strcmp(name, strp) == 0) {
if (symp->st_shndx != Elf_eshn_undefined
#if !defined(__mips__) /* Following doesn't work on MIPS? mhitch */
|| (!in_plt && symp->st_value != 0 &&
ELF_SYM_TYPE(symp->st_info) == Elf_estt_func)) {
#else
) {
#endif
return symp;
}
}