mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 22:30:07 +00:00
2005-05-09 Daniel Jacobowitz <dan@codesourcery.com>
Mark Mitchell <mark@codesourcery.com> * sysdeps/arm/bits/link.h: New file. * sysdeps/arm/dl-trampoline.S: New file. * sysdeps/arm/dl-machine.h: Check RESOLVE_MAP instead of RESOLVE. (elf_machine_runtime_setup): Check dl_profile before calling _dl_name_match_p. (ELF_MACHINE_RUNTIME_TRAMPOLINE): Delete. (elf_machine_rel, elf_machine_rela): Use RESOLVE_MAP. (fix_bad_pc24): Use auto instead of static.
This commit is contained in:
parent
efaef362b3
commit
849e84dde3
@ -1,3 +1,15 @@
|
||||
2005-05-09 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* sysdeps/arm/bits/link.h: New file.
|
||||
* sysdeps/arm/dl-trampoline.S: New file.
|
||||
* sysdeps/arm/dl-machine.h: Check RESOLVE_MAP instead of RESOLVE.
|
||||
(elf_machine_runtime_setup): Check dl_profile before calling
|
||||
_dl_name_match_p.
|
||||
(ELF_MACHINE_RUNTIME_TRAMPOLINE): Delete.
|
||||
(elf_machine_rel, elf_machine_rela): Use RESOLVE_MAP.
|
||||
(fix_bad_pc24): Use auto instead of static.
|
||||
|
||||
2005-05-09 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 2005 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _LINK_H
|
||||
# error "Never include <bits/link.h> directly; use <link.h> instead."
|
||||
#endif
|
||||
|
||||
|
||||
/* Registers for entry into PLT on ARM. */
|
||||
typedef struct La_arm_regs
|
||||
{
|
||||
uint32_t lr_reg[4];
|
||||
uint32_t lr_sp;
|
||||
uint32_t lr_lr;
|
||||
/* Coprocessor registers used for argument passing. The data
|
||||
stored here depends on the coprocessors available in the
|
||||
system which are used for function calls in the current ABI.
|
||||
VFP uses eight 64-bit registers, and iWMMXt uses ten. */
|
||||
uint32_t lr_coproc[42];
|
||||
} La_arm_regs;
|
||||
|
||||
/* Return values for calls from PLT on ARM. */
|
||||
typedef struct La_arm_retval
|
||||
{
|
||||
/* Up to four integer registers can be used for a return value in
|
||||
some ABIs (APCS complex long double). */
|
||||
uint32_t lrv_reg[4];
|
||||
|
||||
/* Any coprocessor registers which might be used to return values
|
||||
in the current ABI. */
|
||||
uint32_t lrv_coproc[12];
|
||||
} La_arm_retval;
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern Elf32_Addr la_arm_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
La_arm_regs *__regs,
|
||||
unsigned int *__flags,
|
||||
const char *__symname,
|
||||
long int *__framesizep);
|
||||
extern unsigned int la_arm_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
const La_arm_regs *__inregs,
|
||||
La_arm_retval *__outregs,
|
||||
const char *symname);
|
||||
|
||||
__END_DECLS
|
@ -110,7 +110,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
{
|
||||
got[2] = (Elf32_Addr) &_dl_runtime_profile;
|
||||
|
||||
if (_dl_name_match_p (GLRO(dl_profile), l))
|
||||
if (GLRO(dl_profile) != NULL
|
||||
&& _dl_name_match_p (GLRO(dl_profile), l))
|
||||
/* Say that we really want profiling and the timers are
|
||||
started. */
|
||||
GL(dl_profile_map) = l;
|
||||
@ -129,119 +130,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
#define BX(x) "mov\tpc, " #x
|
||||
#endif
|
||||
|
||||
#ifndef PROF
|
||||
# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
||||
.text\n\
|
||||
.globl _dl_runtime_resolve\n\
|
||||
.type _dl_runtime_resolve, #function\n\
|
||||
.align 2\n\
|
||||
_dl_runtime_resolve:\n\
|
||||
@ we get called with\n\
|
||||
@ stack[0] contains the return address from this call\n\
|
||||
@ ip contains &GOT[n+3] (pointer to function)\n\
|
||||
@ lr points to &GOT[2]\n\
|
||||
\n\
|
||||
@ stack arguments\n\
|
||||
stmdb sp!,{r0-r3}\n\
|
||||
\n\
|
||||
@ get pointer to linker struct\n\
|
||||
ldr r0, [lr, #-4]\n\
|
||||
\n\
|
||||
@ prepare to call fixup()\n\
|
||||
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each\n\
|
||||
sub r1, ip, lr\n\
|
||||
sub r1, r1, #4\n\
|
||||
add r1, r1, r1\n\
|
||||
\n\
|
||||
@ call fixup routine\n\
|
||||
bl fixup\n\
|
||||
\n\
|
||||
@ save the return\n\
|
||||
mov ip, r0\n\
|
||||
\n\
|
||||
@ get arguments and return address back\n\
|
||||
ldmia sp!, {r0-r3,lr}\n\
|
||||
\n\
|
||||
@ jump to the newly found address\n\
|
||||
" BX(ip) "\n\
|
||||
\n\
|
||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve\n\
|
||||
\n\
|
||||
.globl _dl_runtime_profile\n\
|
||||
.type _dl_runtime_profile, #function\n\
|
||||
.align 2\n\
|
||||
_dl_runtime_profile:\n\
|
||||
@ stack arguments\n\
|
||||
stmdb sp!, {r0-r3}\n\
|
||||
\n\
|
||||
@ get pointer to linker struct\n\
|
||||
ldr r0, [lr, #-4]\n\
|
||||
\n\
|
||||
@ prepare to call fixup()\n\
|
||||
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each\n\
|
||||
sub r1, ip, lr\n\
|
||||
sub r1, r1, #4\n\
|
||||
add r1, r1, r1\n\
|
||||
\n\
|
||||
@ call profiling fixup routine\n\
|
||||
bl profile_fixup\n\
|
||||
\n\
|
||||
@ save the return\n\
|
||||
mov ip, r0\n\
|
||||
\n\
|
||||
@ get arguments and return address back\n\
|
||||
ldmia sp!, {r0-r3,lr}\n\
|
||||
\n\
|
||||
@ jump to the newly found address\n\
|
||||
" BX(ip) "\n\
|
||||
\n\
|
||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve\n\
|
||||
.previous\n\
|
||||
");
|
||||
#else // PROF
|
||||
# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
||||
.text\n\
|
||||
.globl _dl_runtime_resolve\n\
|
||||
.globl _dl_runtime_profile\n\
|
||||
.type _dl_runtime_resolve, #function\n\
|
||||
.type _dl_runtime_profile, #function\n\
|
||||
.align 2\n\
|
||||
_dl_runtime_resolve:\n\
|
||||
_dl_runtime_profile:\n\
|
||||
@ we get called with\n\
|
||||
@ stack[0] contains the return address from this call\n\
|
||||
@ ip contains &GOT[n+3] (pointer to function)\n\
|
||||
@ lr points to &GOT[2]\n\
|
||||
\n\
|
||||
@ stack arguments\n\
|
||||
stmdb sp!, {r0-r3}\n\
|
||||
\n\
|
||||
@ get pointer to linker struct\n\
|
||||
ldr r0, [lr, #-4]\n\
|
||||
\n\
|
||||
@ prepare to call fixup()\n\
|
||||
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each\n\
|
||||
sub r1, ip, lr\n\
|
||||
sub r1, r1, #4\n\
|
||||
add r1, r1, r1\n\
|
||||
\n\
|
||||
@ call profiling fixup routine\n\
|
||||
bl fixup\n\
|
||||
\n\
|
||||
@ save the return\n\
|
||||
mov ip, r0\n\
|
||||
\n\
|
||||
@ get arguments and return address back\n\
|
||||
ldmia sp!, {r0-r3,lr}\n\
|
||||
\n\
|
||||
@ jump to the newly found address\n\
|
||||
" BX(ip) "\n\
|
||||
\n\
|
||||
.size _dl_runtime_profile, .-_dl_runtime_profile\n\
|
||||
.previous\n\
|
||||
");
|
||||
#endif //PROF
|
||||
|
||||
/* Mask identifying addresses reserved for the user program,
|
||||
where the dynamic linker should not map anything. */
|
||||
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
|
||||
@ -355,10 +243,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
|
||||
Prelinked libraries may use Elf32_Rela though. */
|
||||
#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
|
||||
|
||||
#ifdef RESOLVE
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
/* Deal with an out-of-range PC24 reloc. */
|
||||
static Elf32_Addr
|
||||
auto Elf32_Addr
|
||||
fix_bad_pc24 (Elf32_Addr *const reloc_addr, Elf32_Addr value)
|
||||
{
|
||||
static void *fix_page;
|
||||
@ -425,9 +313,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||
#endif
|
||||
{
|
||||
const Elf32_Sym *const refsym = sym;
|
||||
Elf32_Addr value = RESOLVE (&sym, version, r_type);
|
||||
if (sym)
|
||||
value += sym->st_value;
|
||||
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
@ -535,9 +422,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
# ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
const Elf32_Sym *const refsym = sym;
|
||||
# endif
|
||||
Elf32_Addr value = RESOLVE (&sym, version, r_type);
|
||||
if (sym)
|
||||
value += sym->st_value;
|
||||
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
@ -637,4 +523,4 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||
_dl_reloc_bad_type (map, r_type, 1);
|
||||
}
|
||||
|
||||
#endif /* RESOLVE */
|
||||
#endif /* RESOLVE_MAP */
|
||||
|
214
sysdeps/arm/dl-trampoline.S
Normal file
214
sysdeps/arm/dl-trampoline.S
Normal file
@ -0,0 +1,214 @@
|
||||
/* PLT trampolines. ARM version.
|
||||
Copyright (C) 2005 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 Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <libc-symbols.h>
|
||||
|
||||
#if defined(__USE_BX__)
|
||||
#define BX(x) bx x
|
||||
#else
|
||||
#define BX(x) mov pc, x
|
||||
#endif
|
||||
|
||||
.text
|
||||
.globl _dl_runtime_resolve
|
||||
.type _dl_runtime_resolve, #function
|
||||
cfi_startproc
|
||||
.align 2
|
||||
_dl_runtime_resolve:
|
||||
cfi_adjust_cfa_offset (4)
|
||||
cfi_rel_offset (lr, 0)
|
||||
|
||||
@ we get called with
|
||||
@ stack[0] contains the return address from this call
|
||||
@ ip contains &GOT[n+3] (pointer to function)
|
||||
@ lr points to &GOT[2]
|
||||
|
||||
@ Save arguments. We save r4 to realign the stack.
|
||||
stmdb sp!,{r0-r4}
|
||||
cfi_adjust_cfa_offset (20)
|
||||
cfi_rel_offset (r0, 0)
|
||||
cfi_rel_offset (r1, 4)
|
||||
cfi_rel_offset (r2, 8)
|
||||
cfi_rel_offset (r3, 12)
|
||||
|
||||
@ get pointer to linker struct
|
||||
ldr r0, [lr, #-4]
|
||||
|
||||
@ prepare to call _dl_fixup()
|
||||
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each
|
||||
sub r1, ip, lr
|
||||
sub r1, r1, #4
|
||||
add r1, r1, r1
|
||||
|
||||
@ call fixup routine
|
||||
bl _dl_fixup
|
||||
|
||||
@ save the return
|
||||
mov ip, r0
|
||||
|
||||
@ get arguments and return address back. We restore r4
|
||||
@ only to realign the stack.
|
||||
ldmia sp!, {r0-r4,lr}
|
||||
cfi_adjust_cfa_offset (-24)
|
||||
|
||||
@ jump to the newly found address
|
||||
BX(ip)
|
||||
|
||||
cfi_endproc
|
||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve
|
||||
|
||||
.globl _dl_runtime_profile
|
||||
.type _dl_runtime_profile, #function
|
||||
cfi_startproc
|
||||
.align 2
|
||||
_dl_runtime_profile:
|
||||
cfi_adjust_cfa_offset (4)
|
||||
cfi_rel_offset (lr, 0)
|
||||
|
||||
@ we get called with
|
||||
@ stack[0] contains the return address from this call
|
||||
@ ip contains &GOT[n+3] (pointer to function)
|
||||
@ lr points to &GOT[2]
|
||||
|
||||
@ Stack layout:
|
||||
@ 212 - saved lr
|
||||
@ 208 - framesize returned from pltenter
|
||||
@ 16 - La_arm_regs
|
||||
@ 8 - Saved two arguments to _dl_profile_fixup
|
||||
@ 4 - Saved result of _dl_profile_fixup
|
||||
@ 0 - outgoing argument to _dl_profile_fixup
|
||||
@ For now, we only save the general purpose registers.
|
||||
|
||||
sub sp, sp, #196
|
||||
cfi_adjust_cfa_offset (196)
|
||||
stmia sp, {r0-r3}
|
||||
cfi_rel_offset (r0, 0)
|
||||
cfi_rel_offset (r1, 4)
|
||||
cfi_rel_offset (r2, 8)
|
||||
cfi_rel_offset (r3, 12)
|
||||
|
||||
sub sp, sp, #16
|
||||
cfi_adjust_cfa_offset (16)
|
||||
|
||||
@ Save sp and lr.
|
||||
add r0, sp, #216
|
||||
str r0, [sp, #32]
|
||||
ldr r2, [sp, #212]
|
||||
str r2, [sp, #36]
|
||||
|
||||
@ get pointer to linker struct
|
||||
ldr r0, [lr, #-4]
|
||||
|
||||
@ prepare to call _dl_profile_fixup()
|
||||
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each
|
||||
sub r1, ip, lr
|
||||
sub r1, r1, #4
|
||||
add r1, r1, r1
|
||||
|
||||
@ Save these two arguments for pltexit.
|
||||
add r3, sp, #8
|
||||
stmia r3!, {r0,r1}
|
||||
|
||||
@ Set up extra args for _dl_profile_fixup.
|
||||
@ r2 and r3 are already loaded.
|
||||
add ip, sp, #208
|
||||
str ip, [sp, #0]
|
||||
|
||||
@ call profiling fixup routine
|
||||
bl _dl_profile_fixup
|
||||
|
||||
@ The address to call is now in r0.
|
||||
|
||||
@ Check whether we're wrapping this function.
|
||||
ldr ip, [sp, #208]
|
||||
cmp ip, #0
|
||||
bge 1f
|
||||
cfi_remember_state
|
||||
|
||||
@ save the return
|
||||
mov ip, r0
|
||||
|
||||
@ get arguments and return address back
|
||||
add sp, sp, #16
|
||||
cfi_adjust_cfa_offset (-16)
|
||||
ldmia sp, {r0-r3,sp,lr}
|
||||
cfi_adjust_cfa_offset (-200)
|
||||
|
||||
@ jump to the newly found address
|
||||
BX(ip)
|
||||
|
||||
cfi_restore_state
|
||||
1:
|
||||
@ The new frame size is in ip.
|
||||
|
||||
@ New stack layout:
|
||||
@ 268 - saved r7
|
||||
@ 264 - saved result of _dl_profile_fixup
|
||||
@ 72 - La_arm_regs
|
||||
@ 64 - Saved two arguments to _dl_profile_fixup
|
||||
@ 0 - La_arm_retval
|
||||
@ For now, we only save the general purpose registers.
|
||||
|
||||
@ Build the new frame.
|
||||
str r7, [sp, #212]
|
||||
cfi_rel_offset (r7, 212)
|
||||
sub r7, sp, #56
|
||||
cfi_def_cfa_register (r7)
|
||||
cfi_adjust_cfa_offset (56)
|
||||
sub sp, sp, ip
|
||||
bic sp, sp, #7
|
||||
|
||||
@ Save the _dl_profile_fixup result around the call to memcpy.
|
||||
str r0, [r7, #264]
|
||||
|
||||
@ Copy the stack arguments.
|
||||
mov r0, sp
|
||||
add r1, r7, #272
|
||||
mov r2, ip
|
||||
bl memcpy
|
||||
|
||||
@ Call the function.
|
||||
add ip, r7, #72
|
||||
ldmia ip, {r0-r3}
|
||||
ldr ip, [r7, #264]
|
||||
mov lr, pc
|
||||
BX(ip)
|
||||
stmia r7, {r0-r3}
|
||||
|
||||
@ Call pltexit.
|
||||
add ip, r7, #64
|
||||
ldmia ip, {r0,r1}
|
||||
add r2, r7, #72
|
||||
add r3, r7, #0
|
||||
bl _dl_call_pltexit
|
||||
|
||||
@ Return to caller.
|
||||
ldmia r7, {r0-r3}
|
||||
mov sp, r7
|
||||
cfi_def_cfa_register (sp)
|
||||
ldr r7, [sp, #268]
|
||||
ldr lr, [sp, #92]
|
||||
add sp, sp, #272
|
||||
cfi_adjust_cfa_offset (-272)
|
||||
BX(lr)
|
||||
|
||||
cfi_endproc
|
||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve
|
||||
.previous
|
Loading…
Reference in New Issue
Block a user