mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 06:20:06 +00:00
Update.
1998-12-27 Ulrich Drepper <drepper@cygnus.com> * elf/dl-lookup.c (_dl_num_relocations): New variable. (do_lookup): Increment _dl_num_relocations for every call. * elf/rtld.c (print_statistics): New function. (_dl_debug_statistics): New variable. Set when statistics are asked for. (rtld_total_time, relocate_time, load_time): New variables. Used in print_statistics. (_dl_start): Record start and end time of startup. Call print_statistics if needed. (dk_main): Record times for relocations and loading. (process_dl_debug): Recognize statistics. Low-level, low-overhead, high-precision timing funcationality. * sysdeps/generic/hp-timing.h: New file. * sysdeps/i386/i686/Makefile: New file. * sysdeps/i386/i686/hp-timing.h: New file. * sysdeps/i386/i686/hp-timing.c: New file. * sysdeps/i386/dl-machine.h (elf_machine_rel): Reverse order of OR clauses to avoid accessing global variables during rtld relocation. * sunrpc/rpc_main.c: Unify messages. * sysdeps/unix/sysv/linux/arm/Dist: Add ioperm.c and sys/io.h.
This commit is contained in:
parent
8352b484cf
commit
db276fa11c
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
|||||||
|
1998-12-27 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* elf/dl-lookup.c (_dl_num_relocations): New variable.
|
||||||
|
(do_lookup): Increment _dl_num_relocations for every call.
|
||||||
|
* elf/rtld.c (print_statistics): New function.
|
||||||
|
(_dl_debug_statistics): New variable. Set when statistics are asked
|
||||||
|
for.
|
||||||
|
(rtld_total_time, relocate_time, load_time): New variables. Used
|
||||||
|
in print_statistics.
|
||||||
|
(_dl_start): Record start and end time of startup. Call
|
||||||
|
print_statistics if needed.
|
||||||
|
(dk_main): Record times for relocations and loading.
|
||||||
|
(process_dl_debug): Recognize statistics.
|
||||||
|
|
||||||
|
Low-level, low-overhead, high-precision timing funcationality.
|
||||||
|
* sysdeps/generic/hp-timing.h: New file.
|
||||||
|
* sysdeps/i386/i686/Makefile: New file.
|
||||||
|
* sysdeps/i386/i686/hp-timing.h: New file.
|
||||||
|
* sysdeps/i386/i686/hp-timing.c: New file.
|
||||||
|
|
||||||
|
* sysdeps/i386/dl-machine.h (elf_machine_rel): Reverse order of OR
|
||||||
|
clauses to avoid accessing global variables during rtld relocation.
|
||||||
|
|
||||||
|
* sunrpc/rpc_main.c: Unify messages.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/arm/Dist: Add ioperm.c and sys/io.h.
|
||||||
|
|
||||||
1998-12-27 Roland McGrath <roland@baalperazim.frob.com>
|
1998-12-27 Roland McGrath <roland@baalperazim.frob.com>
|
||||||
|
|
||||||
* sysdeps/mach/hurd/bits/statfs.h (struct statfs, struct statfs64):
|
* sysdeps/mach/hurd/bits/statfs.h (struct statfs, struct statfs64):
|
||||||
|
174
elf/rtld.c
174
elf/rtld.c
@ -26,6 +26,7 @@
|
|||||||
#include <stdio-common/_itoa.h>
|
#include <stdio-common/_itoa.h>
|
||||||
#include <entry.h>
|
#include <entry.h>
|
||||||
#include <fpu_control.h>
|
#include <fpu_control.h>
|
||||||
|
#include <hp-timing.h>
|
||||||
#include "dynamic-link.h"
|
#include "dynamic-link.h"
|
||||||
#include "dl-librecon.h"
|
#include "dl-librecon.h"
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ static void print_unresolved (int errcode, const char *objname,
|
|||||||
static void print_missing_version (int errcode, const char *objname,
|
static void print_missing_version (int errcode, const char *objname,
|
||||||
const char *errsting);
|
const char *errsting);
|
||||||
|
|
||||||
|
/* Print the various times we collected. */
|
||||||
|
static void print_statistics (void);
|
||||||
|
|
||||||
/* This is a list of all the modes the dynamic loader can be in. */
|
/* This is a list of all the modes the dynamic loader can be in. */
|
||||||
enum mode { normal, list, verify, trace };
|
enum mode { normal, list, verify, trace };
|
||||||
@ -86,6 +89,7 @@ int _dl_debug_symbols;
|
|||||||
int _dl_debug_versions;
|
int _dl_debug_versions;
|
||||||
int _dl_debug_reloc;
|
int _dl_debug_reloc;
|
||||||
int _dl_debug_files;
|
int _dl_debug_files;
|
||||||
|
int _dl_debug_statistics;
|
||||||
const char *_dl_inhibit_rpath; /* RPATH values which should be
|
const char *_dl_inhibit_rpath; /* RPATH values which should be
|
||||||
ignored. */
|
ignored. */
|
||||||
const char *_dl_origin_path;
|
const char *_dl_origin_path;
|
||||||
@ -118,6 +122,12 @@ struct link_map _dl_rtld_map;
|
|||||||
struct libname_list _dl_rtld_libname;
|
struct libname_list _dl_rtld_libname;
|
||||||
struct libname_list _dl_rtld_libname2;
|
struct libname_list _dl_rtld_libname2;
|
||||||
|
|
||||||
|
/* Variable for statistics. */
|
||||||
|
static hp_timing_t rtld_total_time;
|
||||||
|
static hp_timing_t relocate_time;
|
||||||
|
static hp_timing_t load_time;
|
||||||
|
extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */
|
||||||
|
|
||||||
#ifdef RTLD_START
|
#ifdef RTLD_START
|
||||||
RTLD_START
|
RTLD_START
|
||||||
#else
|
#else
|
||||||
@ -128,6 +138,8 @@ static ElfW(Addr)
|
|||||||
_dl_start (void *arg)
|
_dl_start (void *arg)
|
||||||
{
|
{
|
||||||
struct link_map bootstrap_map;
|
struct link_map bootstrap_map;
|
||||||
|
hp_timing_t start_time;
|
||||||
|
ElfW(Addr) start_addr;
|
||||||
|
|
||||||
/* This #define produces dynamic linking inline functions for
|
/* This #define produces dynamic linking inline functions for
|
||||||
bootstrap relocation instead of general-purpose relocation. */
|
bootstrap relocation instead of general-purpose relocation. */
|
||||||
@ -136,6 +148,9 @@ _dl_start (void *arg)
|
|||||||
((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
|
((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
|
||||||
#include "dynamic-link.h"
|
#include "dynamic-link.h"
|
||||||
|
|
||||||
|
if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
|
||||||
|
HP_TIMING_NOW (start_time);
|
||||||
|
|
||||||
/* Figure out the run-time load address of the dynamic linker itself. */
|
/* Figure out the run-time load address of the dynamic linker itself. */
|
||||||
bootstrap_map.l_addr = elf_machine_load_address ();
|
bootstrap_map.l_addr = elf_machine_load_address ();
|
||||||
|
|
||||||
@ -160,6 +175,16 @@ _dl_start (void *arg)
|
|||||||
the operating system's program loader where to find the program
|
the operating system's program loader where to find the program
|
||||||
header table in core. */
|
header table in core. */
|
||||||
|
|
||||||
|
if (HP_TIMING_AVAIL)
|
||||||
|
{
|
||||||
|
/* If it hasn't happen yet record the startup time. */
|
||||||
|
if (! HP_TIMING_INLINE)
|
||||||
|
HP_TIMING_NOW (start_time);
|
||||||
|
|
||||||
|
/* Initialize the timing functions. */
|
||||||
|
HP_TIMING_DIFF_INIT ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Transfer data about ourselves to the permanent link_map structure. */
|
/* Transfer data about ourselves to the permanent link_map structure. */
|
||||||
_dl_rtld_map.l_addr = bootstrap_map.l_addr;
|
_dl_rtld_map.l_addr = bootstrap_map.l_addr;
|
||||||
_dl_rtld_map.l_ld = bootstrap_map.l_ld;
|
_dl_rtld_map.l_ld = bootstrap_map.l_ld;
|
||||||
@ -176,7 +201,23 @@ _dl_start (void *arg)
|
|||||||
file access. It will call `dl_main' (below) to do all the real work
|
file access. It will call `dl_main' (below) to do all the real work
|
||||||
of the dynamic linker, and then unwind our frame and run the user
|
of the dynamic linker, and then unwind our frame and run the user
|
||||||
entry point on the same stack we entered on. */
|
entry point on the same stack we entered on. */
|
||||||
return _dl_sysdep_start (arg, &dl_main);
|
start_addr = _dl_sysdep_start (arg, &dl_main);
|
||||||
|
|
||||||
|
if (HP_TIMING_AVAIL)
|
||||||
|
{
|
||||||
|
hp_timing_t end_time;
|
||||||
|
|
||||||
|
/* Get the current time. */
|
||||||
|
HP_TIMING_NOW (end_time);
|
||||||
|
|
||||||
|
/* Compute the difference. */
|
||||||
|
HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dl_debug_statistics)
|
||||||
|
print_statistics ();
|
||||||
|
|
||||||
|
return start_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now life is peachy; we can do all normal operations.
|
/* Now life is peachy; we can do all normal operations.
|
||||||
@ -300,6 +341,9 @@ dl_main (const ElfW(Phdr) *phdr,
|
|||||||
int has_interp = 0;
|
int has_interp = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int paths_initialized = 0;
|
int paths_initialized = 0;
|
||||||
|
hp_timing_t start;
|
||||||
|
hp_timing_t stop;
|
||||||
|
hp_timing_t diff;
|
||||||
|
|
||||||
/* Process the environment variable which control the behaviour. */
|
/* Process the environment variable which control the behaviour. */
|
||||||
process_envvars (&mode, &lazy);
|
process_envvars (&mode, &lazy);
|
||||||
@ -413,7 +457,13 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
|
{
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
|
_dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
|
||||||
|
HP_TIMING_DIFF (load_time, start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
phdr = _dl_loaded->l_phdr;
|
phdr = _dl_loaded->l_phdr;
|
||||||
phent = _dl_loaded->l_phnum;
|
phent = _dl_loaded->l_phnum;
|
||||||
@ -562,6 +612,9 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
containing a '/' are ignored since it is insecure. */
|
containing a '/' are ignored since it is insecure. */
|
||||||
char *list = strdupa (preloadlist);
|
char *list = strdupa (preloadlist);
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
|
|
||||||
while ((p = strsep (&list, " :")) != NULL)
|
while ((p = strsep (&list, " :")) != NULL)
|
||||||
if (p[0] != '\0'
|
if (p[0] != '\0'
|
||||||
&& (! __libc_enable_secure || strchr (p, '/') == NULL))
|
&& (! __libc_enable_secure || strchr (p, '/') == NULL))
|
||||||
@ -572,6 +625,10 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
/* It is no duplicate. */
|
/* It is no duplicate. */
|
||||||
++npreloads;
|
++npreloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
HP_TIMING_DIFF (diff, start, stop);
|
||||||
|
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the contents of the file. */
|
/* Read the contents of the file. */
|
||||||
@ -621,6 +678,8 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
file[file_size - 1] = '\0';
|
file[file_size - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
|
|
||||||
if (file != problem)
|
if (file != problem)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
@ -646,6 +705,10 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
++npreloads;
|
++npreloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
HP_TIMING_DIFF (diff, start, stop);
|
||||||
|
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||||
|
|
||||||
/* We don't need the file anymore. */
|
/* We don't need the file anymore. */
|
||||||
__munmap (file, file_size);
|
__munmap (file, file_size);
|
||||||
}
|
}
|
||||||
@ -668,7 +731,11 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||||
specified some libraries to load, these are inserted before the actual
|
specified some libraries to load, these are inserted before the actual
|
||||||
dependencies in the executable's searchlist for symbol resolution. */
|
dependencies in the executable's searchlist for symbol resolution. */
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
_dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace, 0);
|
_dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace, 0);
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
HP_TIMING_DIFF (diff, start, stop);
|
||||||
|
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||||
|
|
||||||
/* Mark all objects as being in the global scope. */
|
/* Mark all objects as being in the global scope. */
|
||||||
for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; )
|
for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; )
|
||||||
@ -884,6 +951,9 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
|
|
||||||
struct link_map *l;
|
struct link_map *l;
|
||||||
int consider_profiling = _dl_profile != NULL;
|
int consider_profiling = _dl_profile != NULL;
|
||||||
|
hp_timing_t start;
|
||||||
|
hp_timing_t stop;
|
||||||
|
hp_timing_t add;
|
||||||
|
|
||||||
/* If we are profiling we also must do lazy reloaction. */
|
/* If we are profiling we also must do lazy reloaction. */
|
||||||
lazy |= consider_profiling;
|
lazy |= consider_profiling;
|
||||||
@ -891,13 +961,19 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
l = _dl_loaded;
|
l = _dl_loaded;
|
||||||
while (l->l_next)
|
while (l->l_next)
|
||||||
l = l->l_next;
|
l = l->l_next;
|
||||||
|
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (l != &_dl_rtld_map)
|
if (l != &_dl_rtld_map)
|
||||||
_dl_relocate_object (l, l->l_scope, lazy, consider_profiling);
|
_dl_relocate_object (l, l->l_scope, lazy, consider_profiling);
|
||||||
|
|
||||||
l = l->l_prev;
|
l = l->l_prev;
|
||||||
} while (l);
|
}
|
||||||
|
while (l);
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
|
||||||
|
HP_TIMING_DIFF (relocate_time, start, stop);
|
||||||
|
|
||||||
/* Do any necessary cleanups for the startup OS interface code.
|
/* Do any necessary cleanups for the startup OS interface code.
|
||||||
We do these now so that no calls are made after rtld re-relocation
|
We do these now so that no calls are made after rtld re-relocation
|
||||||
@ -907,9 +983,15 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
_dl_sysdep_start_cleanup ();
|
_dl_sysdep_start_cleanup ();
|
||||||
|
|
||||||
if (_dl_rtld_map.l_opencount > 0)
|
if (_dl_rtld_map.l_opencount > 0)
|
||||||
/* There was an explicit ref to the dynamic linker as a shared lib.
|
{
|
||||||
Re-relocate ourselves with user-controlled symbol definitions. */
|
/* There was an explicit ref to the dynamic linker as a shared lib.
|
||||||
_dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
|
Re-relocate ourselves with user-controlled symbol definitions. */
|
||||||
|
HP_TIMING_NOW (start);
|
||||||
|
_dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
|
||||||
|
HP_TIMING_NOW (stop);
|
||||||
|
HP_TIMING_DIFF (add, start, stop);
|
||||||
|
HP_TIMING_ACCUM_NT (relocate_time, add);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set up the variable which helps the assembler startup code. */
|
/* Now set up the variable which helps the assembler startup code. */
|
||||||
@ -1101,6 +1183,14 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
if (memcmp (dl_debug, "statistics", 10) == 0)
|
||||||
|
{
|
||||||
|
_dl_debug_statistics = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1110,6 +1200,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
|
|||||||
char *startp = strndupa (dl_debug, len);
|
char *startp = strndupa (dl_debug, len);
|
||||||
_dl_sysdep_error ("warning: debug option `", startp,
|
_dl_sysdep_error ("warning: debug option `", startp,
|
||||||
"' unknown; try LD_DEBUG=help\n", NULL);
|
"' unknown; try LD_DEBUG=help\n", NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1291,3 +1382,74 @@ process_envvars (enum mode *modep, int *lazyp)
|
|||||||
|
|
||||||
*modep = mode;
|
*modep = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print the various times we collected. */
|
||||||
|
static void
|
||||||
|
print_statistics (void)
|
||||||
|
{
|
||||||
|
char buf[200];
|
||||||
|
char *cp;
|
||||||
|
char *wp;
|
||||||
|
|
||||||
|
/* Total time rtld used. */
|
||||||
|
if (HP_TIMING_AVAIL)
|
||||||
|
{
|
||||||
|
HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
|
||||||
|
_dl_debug_message (1, "\nruntime linker statistics:\n"
|
||||||
|
" total startup time in dynamic loader: ",
|
||||||
|
buf, "\n", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print relocation statistics. */
|
||||||
|
if (HP_TIMING_AVAIL)
|
||||||
|
{
|
||||||
|
HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
|
||||||
|
_dl_debug_message (1, " time needed for relocation: ", buf,
|
||||||
|
NULL);
|
||||||
|
cp = _itoa_word ((1000 * relocate_time) / rtld_total_time,
|
||||||
|
buf + sizeof (buf), 10, 0);
|
||||||
|
wp = buf;
|
||||||
|
switch (buf + sizeof (buf) - cp)
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
*wp++ = *cp++;
|
||||||
|
case 2:
|
||||||
|
*wp++ = *cp++;
|
||||||
|
case 1:
|
||||||
|
*wp++ = '.';
|
||||||
|
*wp++ = *cp++;
|
||||||
|
}
|
||||||
|
*wp = '\0';
|
||||||
|
_dl_debug_message (0, " (", buf, "%)\n", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[sizeof (buf) - 1] = '\0';
|
||||||
|
_dl_debug_message (1, " number of relocations: ",
|
||||||
|
_itoa_word (_dl_num_relocations,
|
||||||
|
buf + sizeof (buf) - 1, 10, 0),
|
||||||
|
"\n", NULL);
|
||||||
|
|
||||||
|
/* Time spend while loading the object and the dependencies. */
|
||||||
|
if (HP_TIMING_AVAIL)
|
||||||
|
{
|
||||||
|
HP_TIMING_PRINT (buf, sizeof (buf), load_time);
|
||||||
|
_dl_debug_message (1, " time needed to load objects: ", buf,
|
||||||
|
NULL);
|
||||||
|
cp = _itoa_word ((1000 * load_time) / rtld_total_time,
|
||||||
|
buf + sizeof (buf), 10, 0);
|
||||||
|
wp = buf;
|
||||||
|
switch (buf + sizeof (buf) - cp)
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
*wp++ = *cp++;
|
||||||
|
case 2:
|
||||||
|
*wp++ = *cp++;
|
||||||
|
case 1:
|
||||||
|
*wp++ = '.';
|
||||||
|
*wp++ = *cp++;
|
||||||
|
}
|
||||||
|
*wp = '\0';
|
||||||
|
_dl_debug_message (0, " (", buf, "%)\n", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -459,7 +459,7 @@ check_nettype (const char *name, const char *list_to_check[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf (stderr, _ ("illegal nettype :\'%s\'\n"), name);
|
fprintf (stderr, _ ("illegal nettype :`%s'\n"), name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1144,7 +1144,7 @@ checkfiles (const char *infile, const char *outfile)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("file '%s' already exists and may be overwritten\n"),
|
_("file `%s' already exists and may be overwritten\n"),
|
||||||
outfile);
|
outfile);
|
||||||
crash ();
|
crash ();
|
||||||
}
|
}
|
||||||
@ -1411,7 +1411,7 @@ parseargs (int argc, const char *argv[], struct commandline *cmd)
|
|||||||
static void
|
static void
|
||||||
usage (void)
|
usage (void)
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("usage: %s infile\n"), cmdname);
|
fprintf (stderr, _("usage: %s infile\n"), cmdname);
|
||||||
fprintf (stderr, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \
|
fprintf (stderr, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \
|
||||||
[-I [-K seconds]] [-Y path] infile\n"), cmdname);
|
[-I [-K seconds]] [-Y path] infile\n"), cmdname);
|
||||||
fprintf (stderr, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \
|
fprintf (stderr, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \
|
||||||
|
80
sysdeps/generic/hp-timing.h
Normal file
80
sysdeps/generic/hp-timing.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* High precision, low overhead timing functions. i686 version.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||||
|
|
||||||
|
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., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef _HP_TIMING_H
|
||||||
|
#define _HP_TIMING_H 1
|
||||||
|
|
||||||
|
|
||||||
|
/* There are no generic definitions for the times. We could write something
|
||||||
|
using the `gettimeofday' system call where available but the overhead of
|
||||||
|
the system call might be too high.
|
||||||
|
|
||||||
|
In case a platform supports timers in the hardware the following macros
|
||||||
|
and types must be defined:
|
||||||
|
|
||||||
|
- HP_TIMING_AVAIL: test for availability.
|
||||||
|
|
||||||
|
- HP_TIMING_INLINE: this macro is non-zero if the functionality is not
|
||||||
|
implemented using function calls but instead uses some inlined code
|
||||||
|
which might simply consist of a few assembler instructions. We have to
|
||||||
|
know this since we might want to use the macros here in places where we
|
||||||
|
cannot make function calls.
|
||||||
|
|
||||||
|
- hp_timing_t: This is the type for variables used to store the time
|
||||||
|
values.
|
||||||
|
|
||||||
|
- HP_TIMING_ZERO: clear `hp_timing_t' object.
|
||||||
|
|
||||||
|
- HP_TIMING_NOW: place timestamp for current time in variable given as
|
||||||
|
parameter.
|
||||||
|
|
||||||
|
- HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
|
||||||
|
HP_TIMING_DIFF macro.
|
||||||
|
|
||||||
|
- HP_TIMING_DIFF: compute difference between two times and store it
|
||||||
|
in a third. Source and destination might overlap.
|
||||||
|
|
||||||
|
- HP_TIMING_ACCUM: add time difference to another variable. This might
|
||||||
|
be a bit more complicated to implement for some platforms as the
|
||||||
|
operation should be thread-safe and 64bit arithmetic on 32bit platforms
|
||||||
|
is not.
|
||||||
|
|
||||||
|
- HP_TIMING_ACCUM_NT: this is the variant for situations where we know
|
||||||
|
there are no threads involved.
|
||||||
|
|
||||||
|
- HP_TIMING_PRINT: write decimal representation of the timing value into
|
||||||
|
the given string. This operation need not be inline even though
|
||||||
|
HP_TIMING_INLINE is specified.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Provide dummy definitions. */
|
||||||
|
#define HP_TIMING_AVAIL (0)
|
||||||
|
#define HP_TIMING_INLINE (0)
|
||||||
|
typedef int hp_timing_t;
|
||||||
|
#define HP_TIMING_ZERO(Var)
|
||||||
|
#define HP_TIMING_NOW(var)
|
||||||
|
#define HP_TIMING_DIFF_INIT()
|
||||||
|
#define HP_TIMING_DIFF(Diff, Start, End)
|
||||||
|
#define HP_TIMING_ACCUM(Sum, Diff)
|
||||||
|
#define HP_TIMING_ACCUM_NT(Sum, Diff)
|
||||||
|
#define HP_TIMING_PRINT(Buf, Len, Val)
|
||||||
|
|
||||||
|
#endif /* hp-timing.h */
|
@ -335,7 +335,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
|||||||
found. */
|
found. */
|
||||||
break;
|
break;
|
||||||
if (sym->st_size > refsym->st_size
|
if (sym->st_size > refsym->st_size
|
||||||
|| (_dl_verbose && sym->st_size < refsym->st_size))
|
|| (sym->st_size < refsym->st_size && _dl_verbose))
|
||||||
{
|
{
|
||||||
const char *strtab;
|
const char *strtab;
|
||||||
|
|
||||||
|
3
sysdeps/i386/i686/Makefile
Normal file
3
sysdeps/i386/i686/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
ifeq ($(subdir),csu)
|
||||||
|
sysdep_routines += hp-timing
|
||||||
|
endif
|
24
sysdeps/i386/i686/hp-timing.c
Normal file
24
sysdeps/i386/i686/hp-timing.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/* Support for high precision, low overhead timing functions. i686 version.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||||
|
|
||||||
|
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., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <hp-timing.h>
|
||||||
|
|
||||||
|
/* We have to define the variable for the overhead. */
|
||||||
|
hp_timing_t __libc_hp_timing_overhead;
|
160
sysdeps/i386/i686/hp-timing.h
Normal file
160
sysdeps/i386/i686/hp-timing.h
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/* High precision, low overhead timing functions. i686 version.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||||
|
|
||||||
|
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., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef _HP_TIMING_H
|
||||||
|
#define _HP_TIMING_H 1
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <stdio-common/_itoa.h>
|
||||||
|
|
||||||
|
/* The macros defined here use the timestamp counter in i586 and up versions
|
||||||
|
of the x86 processors. They provide a very accurate way to measure the
|
||||||
|
time with very little overhead. The time values themself have no real
|
||||||
|
meaning, only differences are interesting.
|
||||||
|
|
||||||
|
This version is for the i686 processors. The difference to the i586
|
||||||
|
version is that the timerstamp register is unconditionally used. This is
|
||||||
|
not the case for the i586 version where we have to perform runtime test
|
||||||
|
whether the processor really has this capability. We have to make this
|
||||||
|
distinction since the sysdeps/i386/i586 code is supposed to work on all
|
||||||
|
platforms while the i686 already contains i686-specific code.
|
||||||
|
|
||||||
|
The list of macros we need includes the following:
|
||||||
|
|
||||||
|
- HP_TIMING_AVAIL: test for availability.
|
||||||
|
|
||||||
|
- HP_TIMING_INLINE: this macro is non-zero if the functionality is not
|
||||||
|
implemented using function calls but instead uses some inlined code
|
||||||
|
which might simply consist of a few assembler instructions. We have to
|
||||||
|
know this since we might want to use the macros here in places where we
|
||||||
|
cannot make function calls.
|
||||||
|
|
||||||
|
- hp_timing_t: This is the type for variables used to store the time
|
||||||
|
values.
|
||||||
|
|
||||||
|
- HP_TIMING_ZERO: clear `hp_timing_t' object.
|
||||||
|
|
||||||
|
- HP_TIMING_NOW: place timestamp for current time in variable given as
|
||||||
|
parameter.
|
||||||
|
|
||||||
|
- HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
|
||||||
|
HP_TIMING_DIFF macro.
|
||||||
|
|
||||||
|
- HP_TIMING_DIFF: compute difference between two times and store it
|
||||||
|
in a third. Source and destination might overlap.
|
||||||
|
|
||||||
|
- HP_TIMING_ACCUM: add time difference to another variable. This might
|
||||||
|
be a bit more complicated to implement for some platforms as the
|
||||||
|
operation should be thread-safe and 64bit arithmetic on 32bit platforms
|
||||||
|
is not.
|
||||||
|
|
||||||
|
- HP_TIMING_ACCUM_NT: this is the variant for situations where we know
|
||||||
|
there are no threads involved.
|
||||||
|
|
||||||
|
- HP_TIMING_PRINT: write decimal representation of the timing value into
|
||||||
|
the given string. This operation need not be inline even though
|
||||||
|
HP_TIMING_INLINE is specified.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* We always assume having the timestamp register. */
|
||||||
|
#define HP_TIMING_AVAIL (1)
|
||||||
|
|
||||||
|
/* We indeed have inlined functions. */
|
||||||
|
#define HP_TIMING_INLINE (1)
|
||||||
|
|
||||||
|
/* We use 64bit values for the times. */
|
||||||
|
typedef unsigned long long int hp_timing_t;
|
||||||
|
|
||||||
|
/* Internal variabled used to store the overhead of the measurement
|
||||||
|
opcodes. */
|
||||||
|
extern hp_timing_t __libc_hp_timing_overhead;
|
||||||
|
|
||||||
|
/* Set timestamp value to zero. */
|
||||||
|
#define HP_TIMING_ZERO(Var) (Var) = (0)
|
||||||
|
|
||||||
|
/* That's quite simple. Use the `rdtsc' instruction. Note that the value
|
||||||
|
might not be 100% accurate since there might be some more instructions
|
||||||
|
running in this moment. This could be changed by using a barrier like
|
||||||
|
'cpuid' right before the `rdtsc' instruciton. But we are not interested
|
||||||
|
in accurate clock cycles here so we don't do this. */
|
||||||
|
#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
|
||||||
|
|
||||||
|
/* Use two 'rdtsc' instructions in a row to find out how long it takes. */
|
||||||
|
#define HP_TIMING_DIFF_INIT() \
|
||||||
|
do { \
|
||||||
|
int __cnt = 5; \
|
||||||
|
__libc_hp_timing_overhead = ~0ull; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
hp_timing_t __t1, __t2; \
|
||||||
|
HP_TIMING_NOW (__t1); \
|
||||||
|
HP_TIMING_NOW (__t2); \
|
||||||
|
if (__t2 - __t1 < __libc_hp_timing_overhead) \
|
||||||
|
__libc_hp_timing_overhead = __t2 - __t1; \
|
||||||
|
} \
|
||||||
|
while (--__cnt > 0); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* It's simple arithmetic for us. */
|
||||||
|
#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
|
||||||
|
|
||||||
|
/* We have to jump through hoops to get this correctly implemented. */
|
||||||
|
#define HP_TIMING_ACCUM(Sum, Diff) \
|
||||||
|
do { \
|
||||||
|
char __not_done; \
|
||||||
|
hp_timing_t __oldval = (Sum); \
|
||||||
|
hp_timing_t __diff = (Diff) - __libc_hp_timing_overhead; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
hp_timing_t __newval = __oldval + __diff; \
|
||||||
|
int __temp0, __temp1; \
|
||||||
|
__asm__ __volatile__ ("xchgl %4, %%ebx\n\t" \
|
||||||
|
"lock; cmpxchg8b %1\n\t" \
|
||||||
|
"sete %0\n\t" \
|
||||||
|
"movl %4, %%ebx" \
|
||||||
|
: "=q" (__not_done), "=m" (Sum), \
|
||||||
|
"=A" (__oldval), "=c" (__temp0), \
|
||||||
|
"=SD" (__temp1) \
|
||||||
|
: "1" (Sum), "2" (__oldval), \
|
||||||
|
"3" (__newval >> 32), \
|
||||||
|
"4" (__newval & 0xffffffff) \
|
||||||
|
: "memory"); \
|
||||||
|
} \
|
||||||
|
while (__not_done); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* No threads, no extra work. */
|
||||||
|
#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
|
||||||
|
|
||||||
|
/* Print the time value. */
|
||||||
|
#define HP_TIMING_PRINT(Buf, Len, Val) \
|
||||||
|
do { \
|
||||||
|
char __buf[20]; \
|
||||||
|
char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
|
||||||
|
int __len = (Len); \
|
||||||
|
char *__dest = (Buf); \
|
||||||
|
while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
|
||||||
|
*__dest++ = *__cp++; \
|
||||||
|
memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* hp-timing.h */
|
@ -1,7 +1,9 @@
|
|||||||
clone.S
|
clone.S
|
||||||
init-first.h
|
init-first.h
|
||||||
|
ioperm.c
|
||||||
setresuid.c
|
setresuid.c
|
||||||
setresgid.c
|
setresgid.c
|
||||||
setfsuid.c
|
setfsuid.c
|
||||||
setfsgid.c
|
setfsgid.c
|
||||||
bits/armsigctx.h
|
bits/armsigctx.h
|
||||||
|
sys/io.h
|
||||||
|
Loading…
Reference in New Issue
Block a user