Sat Feb 10 13:09:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/unix/sysv/linux/sys/mman.h: Define MAP_ANON and
	MAP_FILE if not already defined.

	* elf/elf.h: Add m68k reloc definitions.
	* sysdeps/m68k/dl-machine.h, sysdeps/m68k/elf/start.S: New files.
Sat Feb 10 13:09:03 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/sys/mman.h: Define MAP_ANON and
	MAP_FILE if not already defined.

	* elf/elf.h: Add m68k reloc definitions.
	* sysdeps/m68k/dl-machine.h, sysdeps/m68k/elf/start.S: New files.
This commit is contained in:
Roland McGrath 1996-02-13 09:26:53 +00:00
parent 38334018ff
commit 01f3e03bcd
8 changed files with 375 additions and 1 deletions

View File

@ -1,3 +1,11 @@
Sat Feb 10 13:09:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/sys/mman.h: Define MAP_ANON and
MAP_FILE if not already defined.
* elf/elf.h: Add m68k reloc definitions.
* sysdeps/m68k/dl-machine.h, sysdeps/m68k/elf/start.S: New files.
Tue Feb 13 00:12:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> Tue Feb 13 00:12:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/i386/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE, * sysdeps/i386/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE,

View File

@ -69,7 +69,11 @@ endif
# The name of the symbol table archive member. The default is suitable for # The name of the symbol table archive member. The default is suitable for
# BSD style archives. It can be overridden in sysdep Makefiles when SYSV # BSD style archives. It can be overridden in sysdep Makefiles when SYSV
# style archive are used. # style archive are used.
ifeq (no,$(elf))
ar-symtab-name = __.SYMDEF ar-symtab-name = __.SYMDEF
else
ar-symtab-name = # The null name is used in ELF archives.
endif
# Include any system-specific makefiles. # Include any system-specific makefiles.

View File

@ -48,7 +48,11 @@ static Elf32_Addr fixup (struct link_map *l, Elf32_Word reloc_offset)
function. */ function. */
static Elf32_Addr static Elf32_Addr
fixup (struct link_map *l, Elf32_Word reloc_offset) fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
struct link_map *l, Elf32_Word reloc_offset)
{ {
const Elf32_Sym *const symtab const Elf32_Sym *const symtab
= (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr); = (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);

View File

@ -439,6 +439,34 @@ typedef struct
#define AT_GID 13 /* Real gid */ #define AT_GID 13 /* Real gid */
#define AT_EGID 14 /* Effective gid */ #define AT_EGID 14 /* Effective gid */
/* Motorola 68k specific definitions. */
/* m68k relocs. */
#define R_68K_NONE 0 /* No reloc */
#define R_68K_32 1 /* Direct 32 bit */
#define R_68K_16 2 /* Direct 16 bit */
#define R_68K_8 3 /* Direct 8 bit */
#define R_68K_PC32 4 /* PC relative 32 bit */
#define R_68K_PC16 5 /* PC relative 16 bit */
#define R_68K_PC8 6 /* PC relative 8 bit */
#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
#define R_68K_GOT32O 10 /* 32 bit GOT offset */
#define R_68K_GOT16O 11 /* 16 bit GOT offset */
#define R_68K_GOT8O 12 /* 8 bit GOT offset */
#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
#define R_68K_PLT32O 16 /* 32 bit PLT offset */
#define R_68K_PLT16O 17 /* 16 bit PLT offset */
#define R_68K_PLT8O 18 /* 8 bit PLT offset */
#define R_68K_COPY 19 /* Copy symbol at runtime */
#define R_68K_GLOB_DAT 20 /* Create GOT entry */
#define R_68K_JMP_SLOT 21 /* Create PLT entry */
#define R_68K_RELATIVE 22 /* Adjust by program base */
/* Intel 80386 specific definitions. */ /* Intel 80386 specific definitions. */
/* i386 relocs. */ /* i386 relocs. */

230
sysdeps/m68k/dl-machine.h Normal file
View File

@ -0,0 +1,230 @@
/* Machine-dependent ELF dynamic relocation inline functions. m68k version.
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#define ELF_MACHINE_NAME "m68k"
#include <assert.h>
#include <string.h>
#include <link.h>
/* Return nonzero iff E_MACHINE is compatible with the running host. */
static inline int
elf_machine_matches_host (Elf32_Half e_machine)
{
switch (e_machine)
{
case EM_68K:
return 1;
default:
return 0;
}
}
/* Return the run-time address of the _GLOBAL_OFFSET_TABLE_.
Must be inlined in a function which uses global data. */
static inline Elf32_Addr *
elf_machine_got (void)
{
register Elf32_Addr *got asm ("%a5");
return got;
}
/* Return the run-time load address of the shared object. */
static inline Elf32_Addr
elf_machine_load_address (void)
{
...
}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
static inline void
elf_machine_rela (struct link_map *map,
const Elf32_Rela *reloc,
Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
{
Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
const Elf32_Addr sym_value = sym ? sym_loadaddr + sym->st_value : 0;
switch (ELF32_R_TYPE (reloc->r_info))
{
case R_68K_COPY:
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
break;
case R_68K_GLOB_DAT:
case R_68K_JMP_SLOT:
*reloc_addr = sym_value;
break;
case R_68K_8:
*(char *) reloc_addr = sym_value + reloc->r_addend;
break;
case R_68K_16:
*(short *) reloc_addr = sym_value + reloc->r_addend;
break;
case R_68K_32:
*reloc_addr = sym_value + reloc->r_addend;
break;
case R_68K_RELATIVE:
*reloc_addr = map->l_addr + reloc->r_addend;
break;
case R_68K_PC8:
*(char *) reloc_addr = (sym_value + reloc->r_addend
- (Elf32_Addr) reloc_addr);
break;
case R_68K_PC16:
*(short *) reloc_addr = (sym_value + reloc->r_addend
- (Elf32_Addr) reloc_addr);
break;
case R_68K_PC32:
*reloc_addr = sym_value + reloc->r_addend - (Elf32_Addr) reloc_addr;
break;
case R_68K_NONE: /* Alright, Wilbur. */
break;
default:
assert (! "unexpected dynamic reloc type");
break;
}
}
static inline void
elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
{
Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
switch (ELF32_R_TYPE (reloc->r_info))
{
case R_68K_NONE:
break;
case R_68K_JMP_SLOT:
*reloc_addr += map->l_addr;
break;
default:
assert (! "unexpected PLT reloc type");
break;
}
}
/* The m68k never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
/* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */
static inline void
elf_machine_runtime_setup (struct link_map *l, int lazy)
{
Elf32_Addr *got;
extern void _dl_runtime_resolve (Elf32_Word);
if (l->l_info[DT_JMPREL] && lazy)
{
/* The GOT entries for functions in the PLT have not yet been
filled in. Their initial contents will arrange when called
to push an offset into the .rela.plt section, push
_GLOBAL_OFFSET_TABLE_[1], and then jump to
_GLOBAL_OFFSET_TABLE_[2]. */
got = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
got[1] = (Elf32_Addr) l; /* Identify this shared object. */
/* This function will get called to fix up the GOT entry
indicated by the offset on the stack, and then jump to the
resolved address. */
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
}
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
| Trampoline for _dl_runtime_resolver
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
_dl_runtime_resolve:
| Save %a0 (struct return address).
move.l %a0, -(%sp)
| Call the real address resolver.
bsr.l fixup
| Restore register %a0.
move.l (%sp)+, %a0
| Pop parameters
addq.l #8, %sp
| Call real function.
jmp (%d0)
.size _dl_runtime_resolve, . - _dl_runtime_resolve
");
#define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0
}
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
#define ELF_MACHINE_USER_ADDRESS_MASK 0x80000000UL
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
#define RTLD_START asm ("\
.text
.globl _start
.globl _dl_start_user
_start:
jbsr _dl_start
_dl_start_user:
| Save the user entry point address in %a4.
move.l %d0, %a4
| Point %a5 at the GOT.
lea _GLOBAL_OFFSET_TABLE_@GOTPC(%pc), %a5
| See if we were run as a command with the executable file
| name as an extra leading argument.
move.l ([_dl_skip_args@GOT, %a5]), %d0
jeq 0f
| Pop the original argument count
move.l (%sp)+, %d1
| Subtract _dl_skip_args from it.
sub.l %d0, %d1
| Adjust the stack pointer to skip _dl_skip_args words.
lea (%sp, %d0*4), %sp
| Push back the modified argument count.
move.l %d1, -(%sp)
| Call _dl_init_next to return the address of an initializer
| function to run.
0: bsr.l _dl_init_next@PLTPC
| Check for zero return, when out of initializers.
tst.l %d0
jeq 1f
| Call the shared object initializer function.
| NOTE: We depend only on the registers (%a4 and %a5)
| and the return address pushed by this call;
| the initializer is called with the stack just
| as it appears on entry, and it is free to move
| the stack around, as long as it winds up jumping to
| the return address on the top of the stack.
move.l %d0, %a0
jsr (%a0)
| Loop to call _dl_init_next for the next initializer.
jra 0b
1: | Pass our finalizer function to the user in %a1.
move.l _dl_fini@GOT(%a5), %a1
| Initialize %fp with the stack pointer.
move.l %sp, %fp
| Jump to the user's entry point.
jmp (%a4)");

90
sysdeps/m68k/elf/start.S Normal file
View File

@ -0,0 +1,90 @@
/* Startup code compliant to the ELF m68k ABI.
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/m68k ABI says that when the entry point runs,
most registers' values are unspecified, except for:
%a1 Contains a function pointer to be registered with `atexit'.
This is how the dynamic linker arranges to have DT_FINI
functions called for shared libraries that have been loaded
before this code runs.
%sp The stack contains the arguments and environment:
0(%sp) argc
4(%sp) argv[0]
...
(4*argc)(%sp) NULL
(4*(argc+1))(%sp) envp[0]
...
NULL
*/
.text
.globl _start
_start:
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
sub.l %fp, %fp
/* %a1 contains the address of the shared library termination
function, which we will register with `atexit' to be called by
`exit'. */
tstl %a1
jbeq 1f
move.l %a1, -(%sp)
jbsr atexit
addql #4, %sp
1:
/* Do essential libc initialization. In statically linked
programs under the GNU Hurd, this is what sets up the
arguments on the stack for the code below. */
jbsr __libc_init_first
/* Extract the arguments and environment as encoded on the stack
and set up the arguments for `main': argc, argv, envp. */
move.l (%sp)+, %d0 /* Pop the argument count. */
lea (4,%sp,%d0*4), %a0 /* envp = &argv[argc + 1] */
move.l %a0, _environ /* Store it in the global variable. */
pea (%a0) /* Push third argument: envp. */
pea 4(%sp) /* Push second argument: argv. */
move.l %d0, -(%sp) /* Push first argument: argc. */
/* Call `_init', which is the entry point to our own `.init'
section; and register with `atexit' to have `exit' call
`_fini', which is the entry point to our own `.fini' section. */
jbsr _init
move.l #_fini, -(%sp)
jbsr atexit
addq.l #4, %sp
/* Call the user's main function, and exit with its value. */
jbsr main
move.l %d0, (%sp)
1: jbsr exit /* This should never return. */
jbra 1b /* Try again if somehow it does return. */
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.long 0
.weak data_start
data_start = __data_start

View File

@ -40,3 +40,6 @@ ifeq ($(subdir),dirent)
sysdep_routines := $(sysdep_routines) s_getdents sysdep_routines := $(sysdep_routines) s_getdents
endif endif
# In SYSV style archives the symbol table member has an empty name.
ar-symtab-name =

View File

@ -31,6 +31,13 @@ Cambridge, MA 02139, USA. */
/* Get the bit values from the kernel header file. */ /* Get the bit values from the kernel header file. */
#include <linux/mman.h> #include <linux/mman.h>
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
__BEGIN_DECLS __BEGIN_DECLS
/* Map addresses starting near ADDR and extending for LEN bytes. from /* Map addresses starting near ADDR and extending for LEN bytes. from
OFFSET into the file FD describes according to PROT and FLAGS. If ADDR OFFSET into the file FD describes according to PROT and FLAGS. If ADDR