aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-09-01 06:10:36 +0000
committerUlrich Drepper <drepper@redhat.com>2001-09-01 06:10:36 +0000
commiteaad82e00522075b805621309775131e27388791 (patch)
tree0db8ddb46f2a278b5e766f9a62606dce3dd240a5
parentcb2391e14af26237a71729d7af2d9202fc22f12c (diff)
downloadglibc-eaad82e00522075b805621309775131e27388791.tar
glibc-eaad82e00522075b805621309775131e27388791.tar.gz
glibc-eaad82e00522075b805621309775131e27388791.tar.bz2
glibc-eaad82e00522075b805621309775131e27388791.zip
Update.
2001-08-31 Richard Henderson <rth@redhat.com> * elf/dl-support.c (_dl_cpuclock_offset): Protect with NONAVAIL. (HP_TIMING_AVAIL): Set to HP_SMALL_TIMING_AVAIL if present. * elf/rtld.c (HP_TIMING_AVAIL): Likewise. (print_statistics): Make scalar unsigned long long. * sysdeps/alpha/hp-timing.h: New file. 2001-08-31 Jakub Jelinek <jakub@redhat.com> * stdio-common/perror.c (perror): Save errno early, pass it down to perror_internal. (perror_internal): Add errnum argument. 2001-08-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/alpha/dl-machine.h (elf_machine_rela): Remove unused code. Don't add old memory content for R_ALPHA_REFQUAD.
-rw-r--r--ChangeLog19
-rw-r--r--elf/dl-support.c13
-rw-r--r--elf/rtld.c16
-rw-r--r--stdio-common/perror.c10
-rw-r--r--sysdeps/alpha/dl-machine.h17
-rw-r--r--sysdeps/alpha/hp-timing.h118
6 files changed, 162 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index c22649af2e..a89e02e831 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2001-08-31 Richard Henderson <rth@redhat.com>
+
+ * elf/dl-support.c (_dl_cpuclock_offset): Protect with NONAVAIL.
+ (HP_TIMING_AVAIL): Set to HP_SMALL_TIMING_AVAIL if present.
+ * elf/rtld.c (HP_TIMING_AVAIL): Likewise.
+ (print_statistics): Make scalar unsigned long long.
+ * sysdeps/alpha/hp-timing.h: New file.
+
+2001-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ * stdio-common/perror.c (perror): Save errno early, pass it
+ down to perror_internal.
+ (perror_internal): Add errnum argument.
+
+2001-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/alpha/dl-machine.h (elf_machine_rela): Remove unused code.
+ Don't add old memory content for R_ALPHA_REFQUAD.
+
2001-08-30 Ulrich Drepper <drepper@redhat.com>
* crypt/md5-crypt.c (__md5_crypt_r): Compute used and required
diff --git a/elf/dl-support.c b/elf/dl-support.c
index cd56ed411f..1332e8a89f 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -93,8 +93,14 @@ struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
/* Nonzero during startup. */
int _dl_starting_up = 1;
+/* We expect less than a second for relocation. */
+#ifdef HP_SMALL_TIMING_AVAIL
+# undef HP_TIMING_AVAIL
+# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
+#endif
+
/* Initial value of the CPU clock. */
-#if HP_TIMING_AVAIL
+#ifndef HP_TIMING_NONAVAIL
hp_timing_t _dl_cpuclock_offset;
#endif
@@ -133,9 +139,8 @@ static void non_dynamic_init (void) __attribute__ ((unused));
static void
non_dynamic_init (void)
{
-#if HP_TIMING_AVAIL
- HP_TIMING_NOW (_dl_cpuclock_offset);
-#endif
+ if (HP_TIMING_AVAIL)
+ HP_TIMING_NOW (_dl_cpuclock_offset);
if (!_dl_pagesize)
_dl_pagesize = __getpagesize ();
diff --git a/elf/rtld.c b/elf/rtld.c
index fe521176e4..a01594a3ca 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -121,14 +121,20 @@ struct link_map _dl_rtld_map;
struct libname_list _dl_rtld_libname;
struct libname_list _dl_rtld_libname2;
+/* We expect less than a second for relocation. */
+#ifdef HP_SMALL_TIMING_AVAIL
+# undef HP_TIMING_AVAIL
+# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
+#endif
+
/* Variable for statistics. */
#ifndef HP_TIMING_NONAVAIL
static hp_timing_t rtld_total_time;
static hp_timing_t relocate_time;
static hp_timing_t load_time;
#endif
-extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */
-extern unsigned long int _dl_num_cache_relocations; /* in dl-lookup.c */
+extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */
+extern unsigned long int _dl_num_cache_relocations; /* in dl-reloc.c */
static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
hp_timing_t start_time);
@@ -136,7 +142,7 @@ static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
#ifdef RTLD_START
RTLD_START
#else
-#error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
+# error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
#endif
static ElfW(Addr)
@@ -1506,7 +1512,7 @@ print_statistics (void)
{
char pbuf[30];
HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
- cp = _itoa_word ((1000 * relocate_time) / rtld_total_time,
+ cp = _itoa_word ((1000ULL * relocate_time) / rtld_total_time,
pbuf + sizeof (pbuf), 10, 0);
wp = pbuf;
switch (pbuf + sizeof (pbuf) - cp)
@@ -1535,7 +1541,7 @@ print_statistics (void)
{
char pbuf[30];
HP_TIMING_PRINT (buf, sizeof (buf), load_time);
- cp = _itoa_word ((1000 * load_time) / rtld_total_time,
+ cp = _itoa_word ((1000ULL * load_time) / rtld_total_time,
pbuf + sizeof (pbuf), 10, 0);
wp = pbuf;
switch (pbuf + sizeof (pbuf) - cp)
diff --git a/stdio-common/perror.c b/stdio-common/perror.c
index a1995e975e..077eed5867 100644
--- a/stdio-common/perror.c
+++ b/stdio-common/perror.c
@@ -26,10 +26,9 @@
#endif
static void
-perror_internal (FILE *fp, const char *s)
+perror_internal (FILE *fp, const char *s, int errnum)
{
char buf[1024];
- int errnum = errno;
const char *colon;
const char *errstring;
@@ -55,6 +54,7 @@ perror_internal (FILE *fp, const char *s)
void
perror (const char *s)
{
+ int errnum = errno;
#ifdef USE_IN_LIBIO
FILE *fp;
int fd = -1;
@@ -73,20 +73,20 @@ perror (const char *s)
__close (fd);
/* Use standard error as is. */
- perror_internal (stderr, s);
+ perror_internal (stderr, s, errnum);
}
else
{
/* We don't have to do any special hacks regarding the file
position. Since the stderr stream wasn't used so far we just
write to the descriptor. */
- perror_internal (fp, s);
+ perror_internal (fp, s, errnum);
/* Close the stream. */
fclose (fp);
((_IO_FILE *) stderr)->_offset = _IO_pos_BAD;
}
#else
- perror_internal (stderr, s);
+ perror_internal (stderr, s, errnum);
#endif
}
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index a97bdf4501..2a414ca448 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -522,24 +522,7 @@ elf_machine_rela (struct link_map *map,
else if (r_type == R_ALPHA_REFQUAD)
{
void *reloc_addr_1 = reloc_addr;
- Elf64_Addr reloc_addr_val;
- /* Load value without causing unaligned trap. */
- memcpy (&reloc_addr_val, reloc_addr_1, 8);
- sym_value += reloc_addr_val;
- if (map == &_dl_rtld_map)
- {
- /* Undo the relocation done here during bootstrapping.
- Now we will relocate anew, possibly using a binding
- found in the user program or a loaded library rather
- than the dynamic linker's built-in definitions used
- while loading those libraries. */
- const Elf64_Sym *const dlsymtab
- = (void *) D_PTR (map, l_info[DT_SYMTAB]);
- sym_value -= map->l_addr;
- sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
- sym_value -= reloc->r_addend;
- }
/* Store value without causing unaligned trap. */
memcpy (reloc_addr_1, &sym_value, 8);
}
diff --git a/sysdeps/alpha/hp-timing.h b/sysdeps/alpha/hp-timing.h
new file mode 100644
index 0000000000..ccae06b487
--- /dev/null
+++ b/sysdeps/alpha/hp-timing.h
@@ -0,0 +1,118 @@
+/* High precision, low overhead timing functions. Alpha version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@redhat.com>, 2001.
+
+ 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 _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 IA-64. 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.
+
+ 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 have the timestamp register, but it's got only a 4 second
+ range. Use it for ld.so profiling only. */
+#define HP_TIMING_AVAIL (0)
+#define HP_SMALL_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 32 bit values for the times. */
+typedef unsigned int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(VAR) (VAR) = (0)
+
+/* The "rpcc" instruction returns a 32-bit counting half and a 32-bit
+ "virtual cycle counter displacement". Subtracting the two gives us
+ a virtual cycle count. */
+#define HP_TIMING_NOW(VAR) \
+ do { \
+ unsigned long int x_; \
+ asm volatile ("rpcc %0" : "=r"(x_)); \
+ (VAR) = (int) (x_) - (int) (x_ >> 32); \
+ } while (0)
+
+/* ??? Two rpcc instructions can be scheduled simultaneously. */
+#define HP_TIMING_DIFF_INIT() do { } while (0)
+
+/* It's simple arithmetic for us. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* ??? Don't bother, since we're only used for ld.so. */
+#define HP_TIMING_ACCUM(Sum, Diff) not implemented
+
+/* 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_word (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 */