1998-03-04 09:43  Ulrich Drepper  <drepper@cygnus.com>

	* elf/link.h (struct link_map): Add new field l_reloc_result.
	* elf/dl-reloc.c (_dl_relocate_object): Allocate array for results
	of relocation for the object to be profiled.
	* elf/dl-object.c (_dl_new_object): Initialize l_reloc_result field
	to NULL.
	* elf/rtld.c (_dl_start): Add comment that we must not allocate an
	array here.
	* elf/dl-runtime.c (profile_fixup): If l_reloc_result array already
	contains a result from a previous run use this instead of computing
	the value again.
	* elf/dl-minimal.c (malloc): Remove limit for size of allocation.

1998-03-04 11:32  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
This commit is contained in:
Ulrich Drepper 1998-03-04 09:53:17 +00:00
parent f6d8a525ef
commit ea7eb7e3eb
6 changed files with 99 additions and 53 deletions

View File

@ -1,4 +1,18 @@
Wed Mar 4 11:32:01 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> 1998-03-04 09:43 Ulrich Drepper <drepper@cygnus.com>
* elf/link.h (struct link_map): Add new field l_reloc_result.
* elf/dl-reloc.c (_dl_relocate_object): Allocate array for results
of relocation for the object to be profiled.
* elf/dl-object.c (_dl_new_object): Initialize l_reloc_result field
to NULL.
* elf/rtld.c (_dl_start): Add comment that we must not allocate an
array here.
* elf/dl-runtime.c (profile_fixup): If l_reloc_result array already
contains a result from a previous run use this instead of computing
the value again.
* elf/dl-minimal.c (malloc): Remove limit for size of allocation.
1998-03-04 11:32 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/m68k/dl-machine.h: (elf_machine_load_address): Use word * sysdeps/m68k/dl-machine.h: (elf_machine_load_address): Use word
offsets into the GOT. offsets into the GOT.

View File

@ -1,5 +1,5 @@
/* Minimal replacements for basic facilities used in the dynamic linker. /* Minimal replacements for basic facilities used in the dynamic linker.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -27,7 +27,7 @@
#include <errno.h> #include <errno.h>
/* Minimal `malloc' allocator for use while loading shared libraries. /* Minimal `malloc' allocator for use while loading shared libraries.
Only small blocks are allocated, and none are ever freed. */ No block is ever freed. */
static void *alloc_ptr, *alloc_end, *alloc_last_block; static void *alloc_ptr, *alloc_end, *alloc_last_block;
@ -61,13 +61,13 @@ malloc (size_t n)
{ {
/* Insufficient space left; allocate another page. */ /* Insufficient space left; allocate another page. */
caddr_t page; caddr_t page;
assert (n <= _dl_pagesize); size_t nup = (n + _dl_pagesize - 1) & ~(_dl_pagesize - 1);
page = __mmap (0, _dl_pagesize, PROT_READ|PROT_WRITE, page = __mmap (0, nup, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
assert (page != MAP_FAILED); assert (page != MAP_FAILED);
if (page != alloc_end) if (page != alloc_end)
alloc_ptr = page; alloc_ptr = page;
alloc_end = page + _dl_pagesize; alloc_end = page + nup;
} }
alloc_last_block = (void *) alloc_ptr; alloc_last_block = (void *) alloc_ptr;

View File

@ -1,5 +1,5 @@
/* Storage management for the chain of loaded shared objects. /* Storage management for the chain of loaded shared objects.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -45,6 +45,7 @@ _dl_new_object (char *realname, const char *libname, int type)
new->l_libname = newname; new->l_libname = newname;
new->l_type = type; new->l_type = type;
new->l_rpath_dirs = NULL; new->l_rpath_dirs = NULL;
new->l_reloc_result = NULL;
if (_dl_loaded == NULL) if (_dl_loaded == NULL)
{ {

View File

@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects. /* Relocate a shared object and resolve its references to other loaded objects.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -17,11 +17,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include <link.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <link.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "dynamic-link.h" #include "dynamic-link.h"
@ -67,6 +68,18 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
#include "dynamic-link.h" #include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, 1); ELF_DYNAMIC_RELOCATE (l, lazy, 1);
if (_dl_profile_map == l)
{
/* Allocate the array which will contain the already found
relocations. */
l->l_reloc_result =
(ElfW(Addr) *) calloc (sizeof (ElfW(Addr)),
l->l_info[DT_PLTRELSZ]->d_un.d_val);
if (l->l_reloc_result == NULL)
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
"cannot allocate memory for profiling", NULL);
}
} }
/* Mark the object so we know this work has been done. */ /* Mark the object so we know this work has been done. */

View File

@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects. /* On-demand PLT fixup for shared objects.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -162,55 +162,70 @@ profile_fixup (
struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr) struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
{ {
void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount; void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
ElfW(Addr) *resultp;
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 PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
ElfW(Addr) value; ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */ /* This is the address in the array where we store the result of previous
struct link_map **scope = _dl_object_relocation_scope (l); relocations. */
resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
/* Sanity check that we're really looking at a PLT relocation. */ value = *resultp;
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); if (value == 0)
/* Look up the target symbol. */
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{ {
default: /* This is the first time we have to relocate this object. */
{ const ElfW(Sym) *const symtab
const ElfW(Half) *vernum = (const ElfW(Half) *) = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
(l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr); const char *strtab =
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
const struct r_found_version *version = &l->l_versions[ndx];
if (version->hash != 0) const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
/* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
/* Look up the target symbol. */
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{
default:
{ {
value = _dl_lookup_versioned_symbol(strtab + sym->st_name, const ElfW(Half) *vernum = (const ElfW(Half) *)
&sym, scope, l->l_name, (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
version, ELF_MACHINE_JMP_SLOT); ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
break; const struct r_found_version *version = &l->l_versions[ndx];
if (version->hash != 0)
{
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
&sym, scope, l->l_name,
version,
ELF_MACHINE_JMP_SLOT);
break;
}
} }
} case 0:
case 0: value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope, l->l_name, ELF_MACHINE_JMP_SLOT);
l->l_name, ELF_MACHINE_JMP_SLOT); }
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
/* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value);
*_dl_global_scope_end = NULL;
/* Store the result for later runs. */
*resultp = value;
} }
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
/* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value);
*_dl_global_scope_end = NULL;
(*mcount_fct) (retaddr, value); (*mcount_fct) (retaddr, value);
return value; return value;

View File

@ -114,6 +114,9 @@ _dl_start (void *arg)
data access using the global offset table. */ data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0); ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
/* Please note that we don't allow profiling of this object and
therefore need not test whether we have to allocate the array
for the relocation results (as done in dl-reloc.c). */
/* Now life is sane; we can call functions and access global data. /* Now life is sane; we can call functions and access global data.
Set up to use the operating system facilities, and find out from Set up to use the operating system facilities, and find out from