glibc/elf/dl-misc.c
Ulrich Drepper 6dd67bd565 Update.
2002-08-24  Ulrich Drepper  <drepper@redhat.com>

	* locale/programs/charmap.c (charmap_new_char): Don't use
	ULONG_MAX as maximum UCS4 value.

	* sysdeps/unix/sysv/linux/ia64/sys/user.h: New file.

	* sysdeps/generic/strtol.c: We don't need the isascii test in glibc.

	* malloc/hooks.c (public_sET_STATe): use size_t as type for i.
	* malloc/malloc.c (mALLINFo): Likewise.

	* libio/wstrops.c (_IO_wstr_pbackfail): Use WEOF in comparison.

	* libio/wfileops.c (_IO_wfile_overflow): Use EOF not WEOF when
	examining result of _IO_do_flush call.

	* stdio-common/vfprintf.c (vfprintf): Use correct type in va_arg.
	Use prec not spec when sizing buffers.

	* catgets/open_catalog.c (__open_catalog): Add casts to avoid warnings.
	* locale/loadarchive.c (_nl_load_locale_from_archive): Likewise.
	* locale/loadlocale.c (_nl_intern_locale_data): Likewise.
	* stdio-common/vfscanf.c (inchar): Likewise.
	* misc/efgcvt_r.c (fcvt_r): Likewise.
	* elf/dl-misc.c (_dl_debug_vdprintf): Likewise.
	* elf/readlib.c (process_file): Likewise.
	* elf/sprof.c (load_profdata): Likewise.
	* sysdeps/ia64/hp-timing.h (HP_TIMING_PRINT): Likewise.
	* locale/programs/linereader.c (get_toplvl_escape): Likewise.
	* locale/programs/charmap.c (charmap_read): Likewise.
	* libio/fileops.c: Likewise.
	* libio/fmemopen.c: Likewise.
	* stdlib/strtod.c: Likewise.
	* elf/dl-load.c: Likewise.
	* iconv/iconvconfig.c: Likewise.
	* iconv/iconv_prog.c (process_block): Likewise.

	* sysdeps/unix/sysv/linux/ia64/Makefile: Define _ASM_IA64_CURRENT_H
	macro to calm down the compiler.

	* iconv/gconv_cache.c (__gconv_load_cache): Add cast to avoid warning.

	* sysdeps/ia64/elf/initfini.c: Don't use newlines embedded in string.

	* sysdeps/unix/sysv/linux/i386/sysdep.S: Update comment regarding
	placement of errno definition.
	* sysdeps/unix/sysv/linux/m68k/sysdep.S: Likewise.
	* sysdeps/unix/sysv/linux/mips/sysdep.S: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/sysdep.S: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S: Likewise.

	* resolv/nss_dns/dns-host.c (MAXPACKET): Increase minimum value
	from 1024 to 65536, to avoid buffer overrun.

2002-08-16  Paul Eggert  <eggert@twinsun.com>

	* resolv/gethnamaddr.c (MAXPACKET): Increase minimum value
	from 1024 to 65536, to avoid buffer overrun.
	* resolv/res_query.c (MAXPACKET): Likewise.

	architectures.
2002-08-25 04:51:08 +00:00

287 lines
6.7 KiB
C

/* Miscellaneous support functions for dynamic linker
Copyright (C) 1997,1998,1999,2000,2001,2002 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 <fcntl.h>
#include <ldsodefs.h>
#include <limits.h>
#include <link.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <stdio-common/_itoa.h>
#ifndef MAP_ANON
/* This is the only dl-sysdep.c function that is actually needed at run-time
by _dl_map_object. */
int
_dl_sysdep_open_zero_fill (void)
{
return __open ("/dev/zero", O_RDONLY);
}
#endif
/* Read the whole contents of FILE into new mmap'd space with given
protections. *SIZEP gets the size of the file. On error MAP_FAILED
is returned. */
void *
internal_function
_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
{
void *result = MAP_FAILED;
struct stat64 st;
int fd = __open (file, O_RDONLY);
if (fd >= 0)
{
if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
{
*sizep = st.st_size;
/* No need to map the file if it is empty. */
if (*sizep != 0)
/* Map a copy of the file contents. */
result = __mmap (NULL, *sizep, prot,
#ifdef MAP_COPY
MAP_COPY
#else
MAP_PRIVATE
#endif
#ifdef MAP_FILE
| MAP_FILE
#endif
, fd, 0);
}
__close (fd);
}
return result;
}
/* Bare-bone printf implementation. This function only knows about
the formats and flags needed and can handle only up to 64 stripes in
the output. */
static void
_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
{
const int niovmax = 64;
struct iovec iov[niovmax];
int niov = 0;
pid_t pid = 0;
char pidbuf[7];
while (*fmt != '\0')
{
const char *startp = fmt;
if (tag_p > 0)
{
/* Generate the tag line once. It consists of the PID and a
colon followed by a tab. */
if (pid == 0)
{
char *p;
pid = __getpid ();
assert (pid >= 0 && pid < 100000);
p = _itoa (pid, &pidbuf[5], 10, 0);
while (p > pidbuf)
*--p = '0';
pidbuf[5] = ':';
pidbuf[6] = '\t';
}
/* Append to the output. */
assert (niov < niovmax);
iov[niov].iov_len = 7;
iov[niov++].iov_base = pidbuf;
/* No more tags until we see the next newline. */
tag_p = -1;
}
/* Skip everything except % and \n (if tags are needed). */
while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
++fmt;
/* Append constant string. */
assert (niov < niovmax);
if ((iov[niov].iov_len = fmt - startp) != 0)
iov[niov++].iov_base = (char *) startp;
if (*fmt == '%')
{
/* It is a format specifier. */
char fill = ' ';
int width = -1;
int prec = -1;
#if LONG_MAX != INT_MAX
int long_mod = 0;
#endif
/* Recognize zero-digit fill flag. */
if (*++fmt == '0')
{
fill = '0';
++fmt;
}
/* See whether with comes from a parameter. Note that no other
way to specify the width is implemented. */
if (*fmt == '*')
{
width = va_arg (arg, int);
++fmt;
}
/* Handle precision. */
if (*fmt == '.' && fmt[1] == '*')
{
prec = va_arg (arg, int);
fmt += 2;
}
/* Recognize the l modifier. It is only important on some
platforms where long and int have a different size. We
can use the same code for size_t. */
if (*fmt == 'l' || *fmt == 'Z')
{
#if LONG_MAX != INT_MAX
long_mod = 1;
#endif
++fmt;
}
switch (*fmt)
{
/* Integer formatting. */
case 'u':
case 'x':
{
/* We have to make a difference if long and int have a
different size. */
#if LONG_MAX != INT_MAX
unsigned long int num = (long_mod
? va_arg (arg, unsigned long int)
: va_arg (arg, unsigned int));
#else
unsigned long int num = va_arg (arg, unsigned int);
#endif
/* We use alloca() to allocate the buffer with the most
pessimistic guess for the size. Using alloca() allows
having more than one integer formatting in a call. */
char *buf = (char *) alloca (3 * sizeof (unsigned long int));
char *endp = &buf[3 * sizeof (unsigned long int)];
char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
/* Pad to the width the user specified. */
if (width != -1)
while (endp - cp < width)
*--cp = fill;
iov[niov].iov_base = cp;
iov[niov].iov_len = endp - cp;
++niov;
}
break;
case 's':
/* Get the string argument. */
iov[niov].iov_base = va_arg (arg, char *);
iov[niov].iov_len = strlen (iov[niov].iov_base);
if (prec != -1)
iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
++niov;
break;
case '%':
iov[niov].iov_base = (void *) fmt;
iov[niov].iov_len = 1;
++niov;
break;
default:
assert (! "invalid format specifier");
}
++fmt;
}
else if (*fmt == '\n')
{
/* See whether we have to print a single newline character. */
if (fmt == startp)
{
iov[niov].iov_base = (char *) startp;
iov[niov++].iov_len = 1;
}
else
/* No, just add it to the rest of the string. */
++iov[niov - 1].iov_len;
/* Next line, print a tag again. */
tag_p = 1;
++fmt;
}
}
/* Finally write the result. */
__writev (fd, iov, niov);
}
/* Write to debug file. */
void
_dl_debug_printf (const char *fmt, ...)
{
va_list arg;
va_start (arg, fmt);
_dl_debug_vdprintf (GL(dl_debug_fd), 1, fmt, arg);
va_end (arg);
}
INTDEF(_dl_debug_printf)
/* Write to debug file but don't start with a tag. */
void
_dl_debug_printf_c (const char *fmt, ...)
{
va_list arg;
va_start (arg, fmt);
_dl_debug_vdprintf (GL(dl_debug_fd), -1, fmt, arg);
va_end (arg);
}
/* Write the given file descriptor. */
void
_dl_dprintf (int fd, const char *fmt, ...)
{
va_list arg;
va_start (arg, fmt);
_dl_debug_vdprintf (fd, 0, fmt, arg);
va_end (arg);
}