aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-02-20 15:02:24 +0000
committerUlrich Drepper <drepper@redhat.com>1999-02-20 15:02:24 +0000
commitf420344cefcadede3a6a4827e4a2dbaca9866439 (patch)
treed9f1a9cb2e53d0f593cbe235a9fa8c10dadbc939 /elf
parent24d6084042539edf4ea7bf8dca3acfde8eea1600 (diff)
downloadglibc-f420344cefcadede3a6a4827e4a2dbaca9866439.zip
glibc-f420344cefcadede3a6a4827e4a2dbaca9866439.tar.gz
glibc-f420344cefcadede3a6a4827e4a2dbaca9866439.tar.bz2
Update.
* elf/dynamic-link.h (elf_get_dynamic_info): Take new argument with load address. Relocate d_ptr in DT_DTRTAB, DT_SYMTAB, DT_RELA, DT_REL, DT_JMPREL, DT_PLTGOT, and DT_VERSYM l_info entry. (_ELF_DYNAMIC_DO_RELOC): Take extra argument which specifies whether rel and rela relocations can both happen and skip one test if this is not possible. (ELF_DYNAMIC_DO_RELA, ELF_DYNAMIC_DO_REL): Call _ELF_DYNAMIC_DO_RELOC appropriately. * elf/dl-addr.c (_dl_addr): DT_SYMTAB and DT_STRTAB entries are already relocated. * elf/dl-deps.c (_dl_map_object_deps): DT_STRTAB entry is already relocated. * elf/dl-load.c (_dl_init_paths): DT_STRTAB entry is already relocated. (_dl_map_object_from_fd): Call elf_get_dynamic_info with new argument. (_dl_map_object): DT_STRTAB entry is already relocated. * elf/dl-lookup.c (do_lookup): DT_STRTAB and DT_SYMTAB entries are already relocated. * elf/dl-reloc.c (_dl_relocate_object): DT_STRTAB entry is already relocated. * elf/dl-runtime.c (fixup): DT_SYMTAB, DT_STRTAB, DT_JMPREL, and DT_VERSYM entries are already relocated. (profile_fixup): Likewise. * elf/dl-version.c: Rename VERSTAG macro into VERSYMIDX. Replace all users. (match_symbol): DT_STRTAB entry is already relocated. (_dl_check_map_versions): Likewise. Also fo DT_VERSYM. * elf/do-rel.h (elf_dynamic_do_rel): reladdr is now assumed to be relocated already. DT_SYMTAB and DT_VERSYM entries are also relocated. * elf/rtld.c (_dl_start): Pass extra argument to elf_get_dynamic_info. (find_needed): DT_STRTAB entry is already relocated. (dl_main): Pass extra argument to elf_get_dynamic_info. DT_STRTAB entry is already relocated. * sysdeps/alpha/dl-machine.h (elf_machine_fixup_plt): DT_JMPREL and DT_PLTGOT entries are already relocated. (elf_machine_rela): Likewise for DT_SYMTAB. * sysdeps/arm/dl-machine.h (elf_machine_rel): DT_STRTAB is already relocated. * sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise. * sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/powerpc/dl-machine.c (__process_machine_rela): Likewise. * sysdeps/mips/dl-machine.h (elf_machine_got_rel): Likewise. (elf_machine_got_rel): Likewise for DT_SYMTAB and DT_STRTAB. * grp/initgroups.c (initgroups): If function in current module was successful don't stop but continue to process to get all the groups.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-addr.c6
-rw-r--r--elf/dl-deps.c3
-rw-r--r--elf/dl-load.c14
-rw-r--r--elf/dl-lookup.c4
-rw-r--r--elf/dl-reloc.c4
-rw-r--r--elf/dl-runtime.c26
-rw-r--r--elf/dl-version.c23
-rw-r--r--elf/do-rel.h11
-rw-r--r--elf/dynamic-link.h113
-rw-r--r--elf/rtld.c14
10 files changed, 123 insertions, 95 deletions
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 2c9a9dd..14bff06 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -1,5 +1,5 @@
/* Locate the shared object symbol nearest a given address.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 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
@@ -62,8 +62,8 @@ _dl_addr (const void *address, Dl_info *info)
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_addr;
- symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
- strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
+ symtab = (const void *) match->l_info[DT_SYMTAB]->d_un.d_ptr;
+ strtab = (const void *) match->l_info[DT_STRTAB]->d_un.d_ptr;
/* We assume that the string table follows the symbol table, because
there is no way in ELF to know the size of the dynamic symbol table!! */
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 355618a..ca0d932 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -149,8 +149,7 @@ _dl_map_object_deps (struct link_map *map,
if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])
{
- const char *strtab = ((void *) l->l_addr
- + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
struct openaux_args args;
struct list *orig;
const ElfW(Dyn) *d;
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 3de1dca..345b97f 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -531,9 +531,9 @@ _dl_init_paths (const char *llp)
/* Allocate room for the search path and fill in information
from RPATH. */
l->l_rpath_dirs =
- decompose_rpath ((const char *)
- (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
- + l->l_info[DT_RPATH]->d_un.d_val), l);
+ decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
+ + l->l_info[DT_RPATH]->d_un.d_val),
+ l);
else
l->l_rpath_dirs = NULL;
}
@@ -983,7 +983,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
" phnum: ", buf3, "\n\n", NULL);
}
- elf_get_dynamic_info (l->l_ld, l->l_info);
+ elf_get_dynamic_info (l->l_ld, l->l_addr, l->l_info);
if (l->l_info[DT_HASH])
_dl_setup_hash (l);
@@ -1208,8 +1208,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
if (l->l_info[DT_SONAME] == NULL)
continue;
- soname = (const char *) (l->l_addr
- + l->l_info[DT_STRTAB]->d_un.d_ptr
+ soname = (const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
+ l->l_info[DT_SONAME]->d_un.d_val);
if (strcmp (name, soname) != 0)
continue;
@@ -1248,8 +1247,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
/* Make sure the cache information is available. */
if (l->l_rpath_dirs == NULL)
{
- size_t ptrval = (l->l_addr
- + l->l_info[DT_STRTAB]->d_un.d_ptr
+ size_t ptrval = (l->l_info[DT_STRTAB]->d_un.d_ptr
+ l->l_info[DT_RPATH]->d_un.d_val);
l->l_rpath_dirs =
decompose_rpath ((const char *) ptrval, l);
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index ef953c5..de5ecf5 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -110,8 +110,8 @@ do_lookup (const char *undef_name, unsigned long int hash,
map->l_name[0] ? map->l_name : _dl_argv[0],
"\n", NULL);
- symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
- strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+ symtab = (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
+ strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
verstab = map->l_versyms;
/* Search the appropriate hash bucket in this object's symbol table
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index be860af..54a2acc 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -66,8 +66,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
{
/* Do the actual relocation of the object's GOT and other data. */
- const char *strtab /* String table object symbols. */
- = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ /* String table object symbols. */
+ const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE(ref, version, flags) \
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 91700c2..a0f54bd 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects.
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -48,13 +48,11 @@ fixup (
struct link_map *l, ElfW(Word) reloc_offset)
{
const ElfW(Sym) *const symtab
- = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
- const char *strtab =
- (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ = (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;
+ const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
const PLTREL *const reloc
- = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
- reloc_offset);
+ = (const void *) (l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
ElfW(Addr) value;
@@ -67,8 +65,8 @@ fixup (
{
default:
{
- const ElfW(Half) *vernum = (const ElfW(Half) *)
- (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+ const ElfW(Half) *vernum =
+ (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
@@ -121,13 +119,11 @@ profile_fixup (
{
/* This is the first time we have to relocate this object. */
const ElfW(Sym) *const symtab
- = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
- const char *strtab =
- (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
+ = (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;
+ const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
const PLTREL *const reloc
- = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
- reloc_offset);
+ = (const void *) (l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
/* Sanity check that we're really looking at a PLT relocation. */
@@ -138,8 +134,8 @@ profile_fixup (
{
default:
{
- const ElfW(Half) *vernum = (const ElfW(Half) *)
- (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+ const ElfW(Half) *vernum =
+ (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
diff --git a/elf/dl-version.c b/elf/dl-version.c
index 4ba7f1a..fbc4165 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -1,5 +1,5 @@
/* Handle symbol and library versioning.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -28,7 +28,9 @@
#include <assert.h>
-#define VERSTAG(tag) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
+#ifndef VERSYMIDX
+# define VERSYMIDX(tag) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (tag))
+#endif
#define make_string(string, rest...) \
@@ -75,8 +77,7 @@ internal_function
match_symbol (const char *name, ElfW(Word) hash, const char *string,
struct link_map *map, int verbose, int weak)
{
- const char *strtab = (const char *) (map->l_addr
- + map->l_info[DT_STRTAB]->d_un.d_ptr);
+ const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
ElfW(Addr) def_offset;
ElfW(Verdef) *def;
@@ -86,7 +87,7 @@ match_symbol (const char *name, ElfW(Word) hash, const char *string,
map->l_name[0] ? map->l_name : _dl_argv[0],
" required by file ", name, "\n", NULL);
- if (map->l_info[VERSTAG (DT_VERDEF)] == NULL)
+ if (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL)
{
/* The file has no symbol versioning. I.e., the dependent
object was linked against another version of this file. We
@@ -98,7 +99,7 @@ no version information available (required by ",
return 0;
}
- def_offset = map->l_info[VERSTAG (DT_VERDEF)]->d_un.d_ptr;
+ def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
assert (def_offset != 0);
def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset);
@@ -173,10 +174,10 @@ _dl_check_map_versions (struct link_map *map, int verbose)
/* If we don't have a string table, we must be ok. */
if (map->l_info[DT_STRTAB] == NULL)
return 0;
- strtab = (const char *) (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+ strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
- dyn = map->l_info[VERSTAG (DT_VERNEED)];
- def = map->l_info[VERSTAG (DT_VERDEF)];
+ dyn = map->l_info[VERSYMIDX (DT_VERNEED)];
+ def = map->l_info[VERSYMIDX (DT_VERDEF)];
if (dyn != NULL)
{
@@ -282,8 +283,8 @@ _dl_check_map_versions (struct link_map *map, int verbose)
map->l_nversions = ndx_high + 1;
/* Compute the pointer to the version symbols. */
- map->l_versyms = ((void *) map->l_addr
- + map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
+ map->l_versyms =
+ (void *) map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
if (dyn != NULL)
{
diff --git a/elf/do-rel.h b/elf/do-rel.h
index c0f4824..803d250 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -1,5 +1,5 @@
/* Do relocations for ELF dynamic linking.
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -40,8 +40,8 @@ elf_dynamic_do_rel (struct link_map *map,
ElfW(Addr) reladdr, ElfW(Addr) relsize,
int lazy)
{
- const ElfW(Rel) *r = (const ElfW(Rel) *)(map->l_addr + reladdr);
- const ElfW(Rel) *end = (const ElfW(Rel) *)(map->l_addr + reladdr + relsize);
+ const ElfW(Rel) *r = (const void *) reladdr;
+ const ElfW(Rel) *end = (const void *) (reladdr + relsize);
if (lazy)
{
@@ -53,13 +53,12 @@ elf_dynamic_do_rel (struct link_map *map,
else
{
const ElfW(Sym) *const symtab =
- (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+ (const void *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
if (map->l_info[VERSYMIDX (DT_VERSYM)])
{
const ElfW(Half) *const version =
- (const ElfW(Half) *) (map->l_addr
- + map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+ (const void *) map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
for (; r < end; ++r)
{
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 3d96ecc..d322c12 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -21,6 +21,10 @@
#include <dl-machine.h>
#include <assert.h>
+#ifndef VERSYMIDX
+# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
+#endif
+
/* Global read-only variable defined in rtld.c which is nonzero if we
shall give more warning messages. */
@@ -30,13 +34,10 @@ extern int _dl_verbose __attribute__ ((unused));
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
static inline void __attribute__ ((unused))
-elf_get_dynamic_info (ElfW(Dyn) *dyn,
+elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM
+ DT_EXTRANUM])
{
- memset (info, '\0', ((DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM)
- * sizeof (ElfW(Dyn) *)));
-
if (! dyn)
return;
@@ -48,7 +49,7 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
dyn->d_tag < DT_LOPROC + DT_PROCNUM)
info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
- info[DT_VERSIONTAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn;
+ info[VERSYMIDX (dyn->d_tag)] = dyn;
else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM
+ DT_VERSIONTAGNUM] = dyn;
@@ -57,13 +58,41 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
++dyn;
}
- if (info[DT_RELA])
- assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
- if (info[DT_REL])
- assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
- if (info[DT_PLTREL])
- assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
- info[DT_PLTREL]->d_un.d_val == DT_RELA);
+ if (info[DT_PLTGOT] != NULL)
+ info[DT_PLTGOT]->d_un.d_ptr += l_addr;
+ if (info[DT_STRTAB] != NULL)
+ info[DT_STRTAB]->d_un.d_ptr += l_addr;
+ if (info[DT_SYMTAB] != NULL)
+ info[DT_SYMTAB]->d_un.d_ptr += l_addr;
+#if ! ELF_MACHINE_NO_RELA
+ if (info[DT_RELA] != NULL)
+ {
+ assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
+ info[DT_RELA]->d_un.d_ptr += l_addr;
+ }
+#endif
+#if ! ELF_MACHINE_NO_REL
+ if (info[DT_REL] != NULL)
+ {
+ assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
+ info[DT_REL]->d_un.d_ptr += l_addr;
+ }
+#endif
+ if (info[DT_PLTREL] != NULL)
+ {
+#if ELF_MACHINE_NO_RELA
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
+#elif ELF_MACHINE_NO_REL
+ assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#else
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL
+ || info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#endif
+ }
+ if (info[DT_JMPREL] != NULL)
+ info[DT_JMPREL]->d_un.d_ptr += l_addr;
+ if (info[VERSYMIDX (DT_VERSYM)] != NULL)
+ info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
}
#ifdef RESOLVE
@@ -73,13 +102,13 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
duplicating their code. It cannot be done in a more general function
because we must be able to completely inline. */
-/* On some machines, notably Sparc, DT_REL* includes DT_JMPREL in its
+/* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its
range. Note that according to the ELF spec, this is completely legal!
But conditionally define things so that on machines we know this will
not happen we do something more optimal. */
-#ifdef ELF_MACHINE_PLTREL_OVERLAP
-#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy) \
+# ifdef ELF_MACHINE_PLTREL_OVERLAP
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
do { \
struct { ElfW(Addr) start, size; int lazy; } ranges[3]; \
int ranges_index; \
@@ -96,7 +125,7 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
\
if ((do_lazy) \
&& (map)->l_info[DT_PLTREL] \
- && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC) \
+ && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
{ \
ranges[1].start = (map)->l_info[DT_JMPREL]->d_un.d_ptr; \
ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
@@ -111,8 +140,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
ranges[ranges_index].size, \
ranges[ranges_index].lazy); \
} while (0)
-#else
-#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy) \
+# else
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
do { \
struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \
int ranges_index; \
@@ -125,8 +154,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
ranges[0].start = (map)->l_info[DT_##RELOC]->d_un.d_ptr; \
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
} \
- if ((map)->l_info[DT_PLTREL] && \
- (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC) \
+ if ((map)->l_info[DT_PLTREL] \
+ && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
{ \
ElfW(Addr) start = (map)->l_info[DT_JMPREL]->d_un.d_ptr; \
\
@@ -151,28 +180,34 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
ranges[ranges_index].size, \
ranges[ranges_index].lazy); \
} while (0)
-#endif
-
-#if ! ELF_MACHINE_NO_REL
-#include "do-rel.h"
-#define ELF_DYNAMIC_DO_REL(map, lazy) \
- _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy)
-#else
-#define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */
-#endif
-
-#if ! ELF_MACHINE_NO_RELA
-#define DO_RELA
-#include "do-rel.h"
-#define ELF_DYNAMIC_DO_RELA(map, lazy) \
- _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy)
-#else
-#define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */
-#endif
+# endif
+
+# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
+# define _ELF_CHECK_REL 0
+# else
+# define _ELF_CHECK_REL 1
+# endif
+
+# if ! ELF_MACHINE_NO_REL
+# include "do-rel.h"
+# define ELF_DYNAMIC_DO_REL(map, lazy) \
+ _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL)
+# else
+# define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */
+# endif
+
+# if ! ELF_MACHINE_NO_RELA
+# define DO_RELA
+# include "do-rel.h"
+# define ELF_DYNAMIC_DO_RELA(map, lazy) \
+ _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL)
+# else
+# define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */
+# endif
/* This can't just be an inline function because GCC is too dumb
to inline functions containing inlines themselves. */
-#define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
+# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
(consider_profile)); \
diff --git a/elf/rtld.c b/elf/rtld.c
index 6aa3a65..762cdc5 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1,5 +1,5 @@
/* Run time dynamic linker.
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -156,7 +156,8 @@ _dl_start (void *arg)
/* Read our own dynamic section and fill in the info array. */
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
- elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_info);
+ elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_addr,
+ bootstrap_map.l_info);
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
@@ -290,8 +291,7 @@ find_needed (const char *name)
static int
match_version (const char *string, struct link_map *map)
{
- const char *strtab = (const char *) (map->l_addr
- + map->l_info[DT_STRTAB]->d_un.d_ptr);
+ const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
ElfW(Verdef) *def;
#define VERDEFTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
@@ -575,7 +575,8 @@ of this helper program; chances are you did not intend to run this program.\n\
assert (_dl_rtld_map.l_libname); /* How else did we get here? */
/* Extract the contents of the dynamic section for easy access. */
- elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_info);
+ elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr,
+ _dl_loaded->l_info);
if (_dl_loaded->l_info[DT_HASH])
/* Set up our cache of pointers into the hash table. */
_dl_setup_hash (_dl_loaded);
@@ -889,8 +890,7 @@ of this helper program; chances are you did not intend to run this program.\n\
if (dyn == NULL)
continue;
- strtab = (const char *)
- (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+ strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
if (first)