mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
Mon Jun 3 00:30:35 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* elf/dl-lookup.c (_dl_lookup_symbol): Take new arg RELOC_ADDR and don't allow a defn resolving to that address. * elf/link.h: Update prototype and comment. * elf/dl-runtime.c (fixup): Define local `resolve' function and pass it to elf_machine_relplt. * elf/dl-reloc.c (_dl_relocate_object: resolve): Take new arg RELOC_ADDR and pass it through to _dl_lookup_symbol. * elf/do-rel.h (elf_dynamic_do_rel): Pass RESOLVE to elf_machine_rel instead of calling it ourselves and passing its results. (elf_dynamic_do_rel): RESOLVE fn takes new arg RELOC_ADDR. * elf/rtld.c (dl_main): Pass 0 for RELOC_ADDR to _dl_lookup_symbol. * sysdeps/i386/dl-machine.h (elf_machine_rel): Remove SYM_LOADADDR arg. Add RESOLVE function ptr arg. Call *RESOLVE as necessary. * sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/stub/dl-machine.h: Likewise. * csu/initfini.c (_fini): Add extern decl for i_am_not_a_leaf. * elf/dlfcn.h (dl_open_mode): Enumerated type removed. (RTLD_LAZY, RTLD_NOW): Define these as macros instead. (RTLD_GLOBAL): New macro. (dlopen): Take arg of type int instead of dl_open_mode. * elf/dlopen.c: Likewise. * math/math.h (_Mldbl): New macro, either produces L suffix or not. (M_*): Use it for these constants.
This commit is contained in:
parent
6c03c2cf27
commit
710f7bab59
29
ChangeLog
29
ChangeLog
@ -1,5 +1,34 @@
|
||||
Mon Jun 3 00:30:35 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Take new arg RELOC_ADDR and
|
||||
don't allow a defn resolving to that address.
|
||||
* elf/link.h: Update prototype and comment.
|
||||
* elf/dl-runtime.c (fixup): Define local `resolve' function and pass
|
||||
it to elf_machine_relplt.
|
||||
* elf/dl-reloc.c (_dl_relocate_object: resolve): Take new arg
|
||||
RELOC_ADDR and pass it through to _dl_lookup_symbol.
|
||||
* elf/do-rel.h (elf_dynamic_do_rel): Pass RESOLVE to elf_machine_rel
|
||||
instead of calling it ourselves and passing its results.
|
||||
(elf_dynamic_do_rel): RESOLVE fn takes new arg RELOC_ADDR.
|
||||
* elf/rtld.c (dl_main): Pass 0 for RELOC_ADDR to _dl_lookup_symbol.
|
||||
* sysdeps/i386/dl-machine.h (elf_machine_rel): Remove SYM_LOADADDR
|
||||
arg. Add RESOLVE function ptr arg. Call *RESOLVE as necessary.
|
||||
* sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise.
|
||||
* sysdeps/stub/dl-machine.h: Likewise.
|
||||
|
||||
Sun Jun 2 14:56:49 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* csu/initfini.c (_fini): Add extern decl for i_am_not_a_leaf.
|
||||
|
||||
* elf/dlfcn.h (dl_open_mode): Enumerated type removed.
|
||||
(RTLD_LAZY, RTLD_NOW): Define these as macros instead.
|
||||
(RTLD_GLOBAL): New macro.
|
||||
(dlopen): Take arg of type int instead of dl_open_mode.
|
||||
* elf/dlopen.c: Likewise.
|
||||
|
||||
* math/math.h (_Mldbl): New macro, either produces L suffix or not.
|
||||
(M_*): Use it for these constants.
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Arg NOSELF renamed to NOPLT.
|
||||
Reject SHN_UNDEF defns iff NOPLT is nonzero.
|
||||
* elf/link.h (_dl_lookup_symbol): Update prototype and comment.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Special .init and .fini section support.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 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
|
||||
@ -101,10 +101,13 @@ _fini (void)
|
||||
\n\
|
||||
cat > /dev/null <<\\EOF.fini.skip");
|
||||
|
||||
/* Let GCC know that _fini is not a leaf function by having a dummy
|
||||
function call here. We arrange for this call to be omitted from
|
||||
either crt file. */
|
||||
i_am_not_a_leaf();
|
||||
{
|
||||
/* Let GCC know that _fini is not a leaf function by having a dummy
|
||||
function call here. We arrange for this call to be omitted from
|
||||
either crt file. */
|
||||
extern void i_am_not_a_leaf (void);
|
||||
i_am_not_a_leaf ();
|
||||
}
|
||||
|
||||
asm ("\nEOF.fini.skip\
|
||||
\n\
|
||||
|
@ -23,13 +23,15 @@ Cambridge, MA 02139, USA. */
|
||||
#include <assert.h>
|
||||
|
||||
/* Search loaded objects' symbol tables for a definition of the symbol
|
||||
UNDEF_NAME. If NOPLT is nonzero, then a PLT entry cannot satisfy the
|
||||
reference; some different binding must be found. */
|
||||
UNDEF_NAME. The chosen value can't be RELOC_ADDR. If NOPLT is nonzero,
|
||||
then a PLT entry cannot satisfy the reference; some different binding
|
||||
must be found. */
|
||||
|
||||
Elf32_Addr
|
||||
_dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
struct link_map *symbol_scope,
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt)
|
||||
{
|
||||
unsigned long int hash = elf_hash (undef_name);
|
||||
@ -59,6 +61,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
const Elf32_Sym *sym = &symtab[symidx];
|
||||
|
||||
if (sym->st_value == 0 || /* No value. */
|
||||
reloc_addr == map->l_addr + sym->st_value || /* Self ref. */
|
||||
(noplt && sym->st_shndx == SHN_UNDEF)) /* Unwanted PLT entry. */
|
||||
continue;
|
||||
|
||||
|
@ -60,10 +60,11 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref, int noplt)
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
{
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope,
|
||||
l->l_name, noplt);
|
||||
l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
|
||||
real_next = l->l_next;
|
||||
|
@ -67,34 +67,15 @@ fixup (
|
||||
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
|
||||
reloc_offset);
|
||||
|
||||
const Elf32_Sym *definer;
|
||||
Elf32_Addr loadbase;
|
||||
struct link_map *scope, *real_next;
|
||||
|
||||
/* Look up the symbol's run-time value. */
|
||||
|
||||
real_next = l->l_next;
|
||||
if (l->l_info[DT_SYMBOLIC])
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
{
|
||||
l->l_next = _dl_loaded;
|
||||
if (l->l_prev)
|
||||
l->l_prev->l_next = real_next;
|
||||
scope = l;
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, _dl_loaded,
|
||||
l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
else
|
||||
scope = _dl_loaded;
|
||||
|
||||
definer = &symtab[ELF32_R_SYM (reloc->r_info)];
|
||||
loadbase = _dl_lookup_symbol (strtab + definer->st_name, &definer,
|
||||
scope, l->l_name, 1);
|
||||
|
||||
/* Restore list frobnication done above for DT_SYMBOLIC. */
|
||||
l->l_next = real_next;
|
||||
if (l->l_prev)
|
||||
l->l_prev->l_next = l;
|
||||
|
||||
/* Apply the relocation with that value. */
|
||||
elf_machine_relplt (l, reloc, loadbase, definer);
|
||||
/* Perform the specified relocation. */
|
||||
elf_machine_relplt (l, reloc, &symtab[ELF32_R_SYM (reloc->r_info)], resolve);
|
||||
|
||||
return *(Elf32_Addr *) (l->l_addr + reloc->r_offset);
|
||||
}
|
||||
|
18
elf/dlfcn.h
18
elf/dlfcn.h
@ -1,5 +1,5 @@
|
||||
/* dlfcn.h -- User functions for run-time dynamic loading.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 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
|
||||
@ -21,16 +21,18 @@ Cambridge, MA 02139, USA. */
|
||||
#define _DLFCN_H 1
|
||||
|
||||
|
||||
/* Type of the second argument to `dlopen'. */
|
||||
typedef enum
|
||||
{
|
||||
RTLD_LAZY = 1, /* Lazy function call binding. */
|
||||
RTLD_NOW = 2 /* Immediate function call binding. */
|
||||
} dl_open_mode;
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x002 /* Immediate function call binding. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x100
|
||||
|
||||
/* Open the shared object FILE and map it in; return a handle that can be
|
||||
passed to `dlsym' to get symbol values from it. */
|
||||
extern void *dlopen (const char *__file, dl_open_mode);
|
||||
extern void *dlopen (const char *__file, int __mode);
|
||||
|
||||
/* Unmap and close a shared object opened by `dlopen'.
|
||||
The handle cannot be used again after calling `dlclose'. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* dlopen -- Load a shared object at run time.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 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
|
||||
@ -22,7 +22,7 @@ Cambridge, MA 02139, USA. */
|
||||
#include <dlfcn.h>
|
||||
|
||||
void *
|
||||
dlopen (const char *file, dl_open_mode mode)
|
||||
dlopen (const char *file, int mode)
|
||||
{
|
||||
struct link_map *new, *l;
|
||||
|
||||
|
25
elf/do-rel.h
25
elf/do-rel.h
@ -38,7 +38,7 @@ static inline void
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
int reltag, int sztag,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **symbol,
|
||||
int noplt),
|
||||
Elf32_Addr reloc_addr, int noplt),
|
||||
int lazy)
|
||||
{
|
||||
const Elf32_Sym *const symtab
|
||||
@ -53,28 +53,7 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
elf_machine_lazy_rel (map, r);
|
||||
else
|
||||
for (; r < end; ++r)
|
||||
{
|
||||
const Elf32_Sym *definer = &symtab[ELF32_R_SYM (r->r_info)];
|
||||
Elf32_Addr loadbase;
|
||||
|
||||
if (ELF32_R_SYM (r->r_info) == STN_UNDEF)
|
||||
loadbase = 0; /* This value will not be consulted. */
|
||||
else if (ELF32_ST_BIND (definer->st_info) == STB_LOCAL)
|
||||
/* Local symbols always refer to the containing object. */
|
||||
loadbase = map->l_addr;
|
||||
else
|
||||
{
|
||||
if (resolve)
|
||||
loadbase = (*resolve)
|
||||
(&definer, elf_machine_pltrel_p (ELF32_R_TYPE (r->r_info)));
|
||||
else
|
||||
{
|
||||
assert (definer->st_shndx != SHN_UNDEF);
|
||||
loadbase = map->l_addr;
|
||||
}
|
||||
}
|
||||
elf_machine_rel (map, r, loadbase, definer);
|
||||
}
|
||||
elf_machine_rel (map, r, &symtab[ELF32_R_SYM (r->r_info)], resolve);
|
||||
}
|
||||
|
||||
#undef elf_dynamic_do_rel
|
||||
|
@ -185,12 +185,15 @@ extern void _dl_setup_hash (struct link_map *map);
|
||||
reference; it is replaced with the defining symbol, and the base load
|
||||
address of the defining object is returned. SYMBOL_SCOPE is the head of
|
||||
the chain used for searching. REFERENCE_NAME should name the object
|
||||
containing the reference; it is used in error messages. If NOPLT is
|
||||
nonzero, then the reference must not be resolved to a PLT entry. */
|
||||
containing the reference; it is used in error messages. RELOC_ADDR is
|
||||
the address being fixed up and the chosen symbol cannot be one with this
|
||||
value. If NOPLT is nonzero, then the reference must not be resolved to
|
||||
a PLT entry. */
|
||||
extern Elf32_Addr _dl_lookup_symbol (const char *undef,
|
||||
const Elf32_Sym **sym,
|
||||
struct link_map *symbol_scope,
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt);
|
||||
|
||||
|
||||
|
@ -318,7 +318,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
|
||||
_dl_loaded, "argument",
|
||||
0);
|
||||
0, 0);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
|
||||
|
37
math/math.h
37
math/math.h
@ -127,20 +127,31 @@ extern int matherr __P ((struct exception *));
|
||||
|
||||
|
||||
#ifdef __USE_BSD
|
||||
|
||||
/* Some useful constants. */
|
||||
#define M_E 2.7182818284590452354 /* e */
|
||||
#define M_LOG2E 1.4426950408889634074 /* log 2e */
|
||||
#define M_LOG10E 0.43429448190325182765 /* log 10e */
|
||||
#define M_LN2 0.69314718055994530942 /* log e2 */
|
||||
#define M_LN10 2.30258509299404568402 /* log e10 */
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#define M_PI_2 1.57079632679489661923 /* pi/2 */
|
||||
#define M_PI_4 0.78539816339744830962 /* pi/4 */
|
||||
#define M_1_PI 0.31830988618379067154 /* 1/pi */
|
||||
#define M_2_PI 0.63661977236758134308 /* 2/pi */
|
||||
#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
|
||||
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
|
||||
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
||||
#define M_E _Mldbl(2.7182818284590452354) /* e */
|
||||
#define M_LOG2E _Mldbl(1.4426950408889634074) /* log 2e */
|
||||
#define M_LOG10E _Mldbl(0.43429448190325182765) /* log 10e */
|
||||
#define M_LN2 _Mldbl(0.69314718055994530942) /* log e2 */
|
||||
#define M_LN10 _Mldbl(2.30258509299404568402) /* log e10 */
|
||||
#define M_PI _Mldbl(3.14159265358979323846) /* pi */
|
||||
#define M_PI_2 _Mldbl(1.57079632679489661923) /* pi/2 */
|
||||
#define M_PI_4 _Mldbl(0.78539816339744830962) /* pi/4 */
|
||||
#define M_1_PI _Mldbl(0.31830988618379067154) /* 1/pi */
|
||||
#define M_2_PI _Mldbl(0.63661977236758134308) /* 2/pi */
|
||||
#define M_2_SQRTPI _Mldbl(1.12837916709551257390) /* 2/sqrt(pi) */
|
||||
#define M_SQRT2 _Mldbl(1.41421356237309504880) /* sqrt(2) */
|
||||
#define M_SQRT1_2 _Mldbl(0.70710678118654752440) /* 1/sqrt(2) */
|
||||
|
||||
/* Our constants might specify more precision than `double' can represent.
|
||||
Use `long double' constants in standard and GNU C, where they are
|
||||
supported and the cast to `double'. */
|
||||
#if __STDC__ - 0 || __GNUC__ - 0
|
||||
#define _Mldbl(x) x##L
|
||||
#else /* Traditional C. */
|
||||
#define _Mldbl(x) x
|
||||
#endif /* Standard or GNU C. */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1011,7 +1011,9 @@ static const char *re_error_msgid[] =
|
||||
This is a variable only so users of regex can assign to it; we never
|
||||
change it ourselves. */
|
||||
#if defined (MATCH_MAY_ALLOCATE)
|
||||
int re_max_failures = 20000;
|
||||
/* 8600 was enough to cause a crash on Ultrix,
|
||||
whose default stack limit is 2mb. */
|
||||
int re_max_failures = 8000;
|
||||
#else
|
||||
int re_max_failures = 2000;
|
||||
#endif
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
# The following lines list filename patterns matching canonical configurations,
|
||||
# and the associated versions to use for various libraries. The entire
|
||||
# list processed, with earlier entries taking precedence over later entries.
|
||||
# So loose patterns at the end of the list can give defaults.
|
||||
# list is processed, with earlier entries taking precedence over later
|
||||
# entries. So loose patterns at the end of the list can give defaults.
|
||||
|
||||
# Configuration Library versions
|
||||
# ------------- ------- --------
|
||||
|
@ -73,20 +73,31 @@ elf_machine_load_address (void)
|
||||
|
||||
static inline void
|
||||
elf_machine_rel (struct link_map *map,
|
||||
const Elf32_Rel *reloc,
|
||||
Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
|
||||
const Elf32_Rel *reloc, const Elf32_Sym *sym,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt))
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
|
||||
const Elf32_Addr sym_value = sym ? sym_loadaddr + sym->st_value : 0;
|
||||
Elf32_Addr loadbase;
|
||||
|
||||
switch (ELF32_R_TYPE (reloc->r_info))
|
||||
{
|
||||
case R_386_COPY:
|
||||
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
|
||||
break;
|
||||
case R_386_GLOB_DAT:
|
||||
loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) :
|
||||
/* RESOLVE is null during bootstrap relocation. */
|
||||
map->l_addr);
|
||||
*reloc_addr = sym ? (loadbase + sym->st_value) : 0;
|
||||
break;
|
||||
case R_386_JMP_SLOT:
|
||||
*reloc_addr = sym_value;
|
||||
loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 1) :
|
||||
/* RESOLVE is null during bootstrap relocation. */
|
||||
map->l_addr);
|
||||
*reloc_addr = sym ? (loadbase + sym->st_value) : 0;
|
||||
break;
|
||||
case R_386_32:
|
||||
if (map->l_type == lt_interpreter)
|
||||
@ -100,14 +111,17 @@ elf_machine_rel (struct link_map *map,
|
||||
*reloc_addr -= (map->l_addr +
|
||||
dlsymtab[ELF32_R_SYM (reloc->r_info)].st_value);
|
||||
}
|
||||
*reloc_addr += sym_value;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*reloc_addr += sym ? (loadbase + sym->st_value) : 0;
|
||||
break;
|
||||
case R_386_RELATIVE:
|
||||
if (map->l_type != lt_interpreter) /* Already done in dynamic linker. */
|
||||
*reloc_addr += map->l_addr;
|
||||
break;
|
||||
case R_386_PC32:
|
||||
*reloc_addr += sym_value - (Elf32_Addr) reloc_addr;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*reloc_addr += ((sym ? (loadbase + sym->st_value) : 0) -
|
||||
(Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_386_NONE: /* Alright, Wilbur. */
|
||||
break;
|
||||
|
@ -73,43 +73,67 @@ elf_machine_load_address (void)
|
||||
|
||||
static inline void
|
||||
elf_machine_rela (struct link_map *map,
|
||||
const Elf32_Rela *reloc,
|
||||
Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
|
||||
const Elf32_Rel *reloc, const Elf32_Sym *sym,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt))
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
|
||||
const Elf32_Addr sym_value = sym ? sym_loadaddr + sym->st_value : 0;
|
||||
Elf32_Addr loadbase;
|
||||
|
||||
switch (ELF32_R_TYPE (reloc->r_info))
|
||||
{
|
||||
case R_68K_COPY:
|
||||
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
|
||||
break;
|
||||
case R_68K_GLOB_DAT:
|
||||
loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) :
|
||||
/* RESOLVE is null during bootstrap relocation. */
|
||||
map->l_addr);
|
||||
*reloc_addr = sym ? (loadbase + sym->st_value) : 0;
|
||||
break;
|
||||
case R_68K_JMP_SLOT:
|
||||
*reloc_addr = sym_value;
|
||||
loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 1) :
|
||||
/* RESOLVE is null during bootstrap relocation. */
|
||||
map->l_addr);
|
||||
*reloc_addr = sym ? (loadbase + sym->st_value) : 0;
|
||||
break;
|
||||
case R_68K_8:
|
||||
*(char *) reloc_addr = sym_value + reloc->r_addend;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ reloc->r_addend);
|
||||
break;
|
||||
case R_68K_16:
|
||||
*(short *) reloc_addr = sym_value + reloc->r_addend;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ reloc->r_addend);
|
||||
break;
|
||||
case R_68K_32:
|
||||
*reloc_addr = sym_value + reloc->r_addend;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ 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
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ reloc->r_addend
|
||||
- (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_68K_PC16:
|
||||
*(short *) reloc_addr = (sym_value + reloc->r_addend
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ reloc->r_addend
|
||||
- (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_68K_PC32:
|
||||
*reloc_addr = sym_value + reloc->r_addend - (Elf32_Addr) reloc_addr;
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
*reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
|
||||
+ reloc->r_addend
|
||||
- (Elf32_Addr) reloc_addr);
|
||||
break;
|
||||
case R_68K_NONE: /* Alright, Wilbur. */
|
||||
break;
|
||||
|
@ -61,16 +61,19 @@ elf_machine_load_address (void)
|
||||
|
||||
static inline void
|
||||
elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
|
||||
const Elf32_Rel *reloc,
|
||||
Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
|
||||
const Elf32_Rel *reloc, const Elf32_Sym *sym,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt))
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = (Elf32_Addr *) reloc->r_offset;
|
||||
const Elf32_Addr sym_value = sym_loadaddr + sym->st_value;
|
||||
Elf32_Addr loadbase;
|
||||
|
||||
switch (ELF32_R_TYPE (reloc->r_info))
|
||||
{
|
||||
case R_MACHINE_COPY:
|
||||
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
|
||||
loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
|
||||
memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
|
||||
break;
|
||||
default:
|
||||
assert (! "unexpected dynamic reloc type");
|
||||
@ -81,8 +84,10 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
|
||||
|
||||
static inline void
|
||||
elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
|
||||
const Elf32_Rela *reloc,
|
||||
Elf32_Addr sym_loadaddr, const Elf32_Sym *sym)
|
||||
const Elf32_Rel *reloc, const Elf32_Sym *sym,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt))
|
||||
{
|
||||
_dl_signal_error (0, "Elf32_Rela relocation requested -- unused on "
|
||||
ELF_MACHINE_NAME);
|
||||
|
Loading…
Reference in New Issue
Block a user