d347a4ab1d
2003-07-31 Jakub Jelinek <jakub@redhat.com> * dlfcn/dlerror.c (once): New. (dlerror): Call __libc_once. (_dlerror_run): Remove once. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h (struct sigcontext): Sync with 2.5.7 and 2.5.73 kernel changes. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * dlfcn/eval.c (funcall): Add noinline attribute to shut up warnings. * elf/rtld.c (dl_main): Cast ElfW(Addr) arguments with %Zx/%Zd formats to size_t. * elf/dl-lookup.c (_dl_debug_bindings): Likewise. * elf/tst-tls6.c (do_test): Use %zd format for l_tls_modid. * elf/tst-tls8.c (do_test): Use %zd format for modid1 and modid2. * gmon/tst-sprofil.c (main): Add parens to shut up warning. * iconv/tst-iconv3.c (main): Use %td instead of %zd for pointer difference argument. * stdio-common/tst-wc-printf.c (main): Cast arguments with %C format to wint_t. * stdlib/tst-limits.c (main): For WORD_BIT and LONG_BIT, use %d format and cast expected value to int. * sysdeps/generic/libc-start.c (STATIC): Add __attribute__((always_inline) if LIBC_START_MAIN is already defined. * sysdeps/powerpc/fpu/w_sqrt.c (a_nan, a_inf): Change from uint32_t to ieee_float_shape_type. (__sqrt): Avoid type punning. * sysdeps/powerpc/fpu/w_sqrtf.c (a_nan, a_inf): Change from uint32_t to ieee_float_shape_type. (__sqrtf): Avoid type punning. * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Don't define refsym if in dl-conflict.c. * sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/unix/sysv/linux/i386/semctl.c (union semun): Add __old_buf. (__new_semctl): Shut up warning. * sysdeps/unix/sysv/linux/semctl.c (union semun): Add __old_buf. (__new_semctl): Shut up warning. * sysdeps/unix/sysv/linux/shmctl.c (__new_shmctl): Wrap long lines. Change old into union of __old_shmid_ds and __old_shminfo structs. Adjust all users. * wcsmbs/wcsmbs-tst1.c (main): Cast arguments with %C format to wint_t. 2003-07-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/utimes.c (__utimes): Fix actime and modtime computation. * sysdeps/unix/sysv/linux/futimes.c (__futimes): Likewise. * sysdeps/posix/utimes.c (__utimes): Likewise.
202 lines
4.2 KiB
C
202 lines
4.2 KiB
C
/* You don't really want to know what this hack is for.
|
|
Copyright (C) 1996, 1997, 2000, 2001 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
|
|
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. */
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <dlfcn.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static void *funcall (char **stringp) __attribute_noinline__;
|
|
static void *eval (char **stringp);
|
|
|
|
|
|
long int weak_function
|
|
__strtol_internal (const char *nptr, char **endptr, int base, int group)
|
|
{
|
|
unsigned long int result = 0;
|
|
long int sign = 1;
|
|
|
|
while (*nptr == ' ' || *nptr == '\t')
|
|
++nptr;
|
|
|
|
if (*nptr == '-')
|
|
{
|
|
sign = -1;
|
|
++nptr;
|
|
}
|
|
else if (*nptr == '+')
|
|
++nptr;
|
|
|
|
if (*nptr < '0' || *nptr > '9')
|
|
{
|
|
if (endptr != NULL)
|
|
*endptr = (char *) nptr;
|
|
return 0L;
|
|
}
|
|
|
|
assert (base == 0);
|
|
base = 10;
|
|
if (*nptr == '0')
|
|
{
|
|
if (nptr[1] == 'x' || nptr[1] == 'X')
|
|
{
|
|
base = 16;
|
|
nptr += 2;
|
|
}
|
|
else
|
|
base = 8;
|
|
}
|
|
|
|
while (*nptr >= '0' && *nptr <= '9')
|
|
{
|
|
unsigned long int digval = *nptr - '0';
|
|
if (result > LONG_MAX / 10
|
|
|| (sign > 0 ? result == LONG_MAX / 10 && digval > LONG_MAX % 10
|
|
: (result == ((unsigned long int) LONG_MAX + 1) / 10
|
|
&& digval > ((unsigned long int) LONG_MAX + 1) % 10)))
|
|
{
|
|
errno = ERANGE;
|
|
return sign > 0 ? LONG_MAX : LONG_MIN;
|
|
}
|
|
result *= base;
|
|
result += digval;
|
|
++nptr;
|
|
}
|
|
|
|
return (long int) result * sign;
|
|
}
|
|
|
|
|
|
static void *
|
|
funcall (char **stringp)
|
|
{
|
|
void *args[strlen (*stringp)], **ap = args;
|
|
void *argcookie = &args[1];
|
|
|
|
do
|
|
{
|
|
/* Evaluate the next token. */
|
|
*ap++ = eval (stringp);
|
|
|
|
/* Whitespace is irrelevant. */
|
|
while (isspace (**stringp))
|
|
++*stringp;
|
|
|
|
/* Terminate at closing paren or end of line. */
|
|
} while (**stringp != '\0' && **stringp != ')');
|
|
if (**stringp != '\0')
|
|
/* Swallow closing paren. */
|
|
++*stringp;
|
|
|
|
if (args[0] == NULL)
|
|
{
|
|
static const char unknown[] = "Unknown function\n";
|
|
write (1, unknown, sizeof unknown - 1);
|
|
return NULL;
|
|
}
|
|
|
|
/* Do it to it. */
|
|
__builtin_return (__builtin_apply (args[0],
|
|
&argcookie,
|
|
(char *) ap - (char *) &args[1]));
|
|
}
|
|
|
|
static void *
|
|
eval (char **stringp)
|
|
{
|
|
void *value;
|
|
char *p = *stringp, c;
|
|
|
|
/* Whitespace is irrelevant. */
|
|
while (isspace (*p))
|
|
++p;
|
|
|
|
switch (*p)
|
|
{
|
|
case '"':
|
|
/* String constant. */
|
|
value = ++p;
|
|
do
|
|
if (*p == '\\')
|
|
{
|
|
switch (*strcpy (p, p + 1))
|
|
{
|
|
case 't':
|
|
*p = '\t';
|
|
break;
|
|
case 'n':
|
|
*p = '\n';
|
|
break;
|
|
}
|
|
++p;
|
|
}
|
|
while (*p != '\0' && *p++ != '"');
|
|
if (p[-1] == '"')
|
|
p[-1] = '\0';
|
|
break;
|
|
|
|
case '(':
|
|
*stringp = ++p;
|
|
return funcall (stringp);
|
|
|
|
default:
|
|
/* Try to parse it as a number. */
|
|
value = (void *) __strtol_internal (p, stringp, 0, 0);
|
|
if (*stringp != p)
|
|
return value;
|
|
|
|
/* Anything else is a symbol that produces its address. */
|
|
value = p;
|
|
do
|
|
++p;
|
|
while (*p != '\0' && !isspace (*p) && (!ispunct (*p) || *p == '_'));
|
|
c = *p;
|
|
*p = '\0';
|
|
value = dlsym (NULL, value);
|
|
*p = c;
|
|
break;
|
|
}
|
|
|
|
*stringp = p;
|
|
return value;
|
|
}
|
|
|
|
|
|
extern void _start (void) __attribute__ ((noreturn));
|
|
void
|
|
__attribute__ ((noreturn))
|
|
_start (void)
|
|
{
|
|
char *buf = NULL;
|
|
size_t bufsz = 0;
|
|
|
|
while (__getdelim (&buf, &bufsz, '\n', stdin) > 0)
|
|
{
|
|
char *p = buf;
|
|
eval (&p);
|
|
}
|
|
|
|
exit (0);
|
|
}
|