Skip to content

Commit

Permalink
* sysdeps/unix/sysv/linux/dl-osinfo.h (_dl_discover_osversion)
Browse files Browse the repository at this point in the history
	[(NEED_DL_SYSINFO || NEED_DL_SYSINFO_DSO) && SHARED]: Scan
	GLRO(dl_sysinfo_map) for PT_NOTE giving Linux kernel version,
	we can skip the uname call if it's there.
	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Don't use
	DL_SYSDEP_OSCHECK here.
	* elf/rtld.c (dl_main) [DL_SYSDEP_OSCHECK]: Do it here instead.

	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro):
	Add _dl_sysinfo_map.
	* elf/rtld.c (dl_main): Don't call _dl_init_paths early in the
	rtld_is_main case.  Call it unconditionally later.
	Move GLRO(dl_sysinfo_dso) handling earlier, before _dl_init_paths call.
	Initialize GLRO(dl_sysinfo_map).
	* elf/dl-load.c (open_path): Bail out if _dl_init_paths wasn't called.
	* sysdeps/generic/dl-sysdep.c (_DL_FIRST_EXTRA): New macro.
	(_dl_important_hwcaps)
	[(NEED_DL_SYSINFO || NEED_DL_SYSINFO_DSO) && SHARED]: Scan
	GLRO(dl_sysinfo_map) for PT_NOTE giving synthetic hwcap names
	and bit values.
	* elf/ldconfig.c (_DL_FIRST_EXTRA): New macro.
	(hwcap_extra): New static variable.
	(is_hwcap_platform): Check hwcap_extra for a matching name.
	Remove tls special case.
	(path_hwcap): Likewise.
	(parse_conf): Parse "hwcap" directive to define synthetic hwcap bits
	and their names, stored in hwcap_extra.
	(main) [USE_TLS]: Initialize final synthetic hwcap bit as "tls".

	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Use uint64_t for
	_dl_hwcap and _dl_hwcap_mask.
	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Cast a_val for
	AT_HWCAP to unsigned long int.
	* elf/dl-support.c (_dl_aux_init): Likewise.
	(_dl_hwcap): Update defn.

	* elf/cache.c (print_entry): Pad hwcap value with 0s in diagnostic.
	* elf/ldconfig.c (search_dir): Likewise.
  • Loading branch information
Roland McGrath committed Apr 7, 2005
1 parent da232bf commit ab1d521
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 124 deletions.
41 changes: 41 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
2005-04-07 Roland McGrath <roland@redhat.com>

* sysdeps/unix/sysv/linux/dl-osinfo.h (_dl_discover_osversion)
[(NEED_DL_SYSINFO || NEED_DL_SYSINFO_DSO) && SHARED]: Scan
GLRO(dl_sysinfo_map) for PT_NOTE giving Linux kernel version,
we can skip the uname call if it's there.
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Don't use
DL_SYSDEP_OSCHECK here.
* elf/rtld.c (dl_main) [DL_SYSDEP_OSCHECK]: Do it here instead.

* sysdeps/generic/ldsodefs.h (struct rtld_global_ro):
Add _dl_sysinfo_map.
* elf/rtld.c (dl_main): Don't call _dl_init_paths early in the
rtld_is_main case. Call it unconditionally later.
Move GLRO(dl_sysinfo_dso) handling earlier, before _dl_init_paths call.
Initialize GLRO(dl_sysinfo_map).
* elf/dl-load.c (open_path): Bail out if _dl_init_paths wasn't called.
* sysdeps/generic/dl-sysdep.c (_DL_FIRST_EXTRA): New macro.
(_dl_important_hwcaps)
[(NEED_DL_SYSINFO || NEED_DL_SYSINFO_DSO) && SHARED]: Scan
GLRO(dl_sysinfo_map) for PT_NOTE giving synthetic hwcap names
and bit values.
* elf/ldconfig.c (_DL_FIRST_EXTRA): New macro.
(hwcap_extra): New static variable.
(is_hwcap_platform): Check hwcap_extra for a matching name.
Remove tls special case.
(path_hwcap): Likewise.
(parse_conf): Parse "hwcap" directive to define synthetic hwcap bits
and their names, stored in hwcap_extra.
(main) [USE_TLS]: Initialize final synthetic hwcap bit as "tls".

* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Use uint64_t for
_dl_hwcap and _dl_hwcap_mask.
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Cast a_val for
AT_HWCAP to unsigned long int.
* elf/dl-support.c (_dl_aux_init): Likewise.
(_dl_hwcap): Update defn.

* elf/cache.c (print_entry): Pad hwcap value with 0s in diagnostic.
* elf/ldconfig.c (search_dir): Likewise.

2005-04-05 Roland McGrath <roland@redhat.com>

* NEWS: Copy 2.3.5 section from 2.3 branch.
Expand Down
4 changes: 2 additions & 2 deletions elf/cache.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 1999, 2000, 2001, 2002, 2003
/* Copyright (C) 1999,2000,2001,2002,2003,2005
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
Expand Down Expand Up @@ -99,7 +99,7 @@ print_entry (const char *lib, int flag, unsigned int osversion,
break;
}
if (hwcap != 0)
printf (", hwcap: 0x%" PRIx64, hwcap);
printf (", hwcap: %#.16" PRIx64, hwcap);
if (osversion != 0)
{
static const char *const abi_tag_os[] =
Expand Down
5 changes: 5 additions & 0 deletions elf/dl-load.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,11 @@ open_path (const char *name, size_t namelen, int preloaded,
const char *current_what = NULL;
int any = 0;

if (__builtin_expect (dirs == NULL, 0))
/* We're called before _dl_init_paths when loading the main executable
given on the command line when rtld is run directly. */
return -1;

buf = alloca (max_dirnamelen + max_capstrlen + namelen);
do
{
Expand Down
6 changes: 3 additions & 3 deletions elf/dl-support.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Support for dynamic linking code in static libc.
Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 1996-2002, 2003, 2004, 2005 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
Expand Down Expand Up @@ -121,7 +121,7 @@ int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;

ElfW(Phdr) *_dl_phdr;
size_t _dl_phnum;
unsigned long int _dl_hwcap __attribute__ ((nocommon));
uint64_t _dl_hwcap __attribute__ ((nocommon));

/* Prevailing state of the stack, PF_X indicating it's executable. */
ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X;
Expand Down Expand Up @@ -179,7 +179,7 @@ _dl_aux_init (ElfW(auxv_t) *av)
GL(dl_phnum) = av->a_un.a_val;
break;
case AT_HWCAP:
GLRO(dl_hwcap) = av->a_un.a_val;
GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
break;
#ifdef NEED_DL_SYSINFO
case AT_SYSINFO:
Expand Down
80 changes: 70 additions & 10 deletions elf/ldconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@

#include "dl-procinfo.h"

#ifdef _DL_FIRST_PLATFORM
# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
#else
# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
#endif

#ifndef LD_SO_CONF
# define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
#endif
Expand Down Expand Up @@ -115,6 +121,9 @@ static const char *config_file;
/* Mask to use for important hardware capabilities. */
static unsigned long int hwcap_mask = HWCAP_IMPORTANT;

/* Configuration-defined capabilities defined in kernel vDSOs. */
static const char *hwcap_extra[64 - _DL_FIRST_EXTRA];

/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *)
Expand Down Expand Up @@ -165,10 +174,10 @@ is_hwcap_platform (const char *name)
if (hwcap_idx != -1)
return 1;

#ifdef USE_TLS
if (strcmp (name, "tls") == 0)
return 1;
#endif
for (hwcap_idx = _DL_FIRST_EXTRA; hwcap_idx < 64; ++hwcap_idx)
if (hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA] != NULL
&& !strcmp (name, hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA]))
return 1;

return 0;
}
Expand Down Expand Up @@ -203,11 +212,11 @@ path_hwcap (const char *path)
h = _dl_string_platform (ptr + 1);
if (h == (uint64_t) -1)
{
#ifdef USE_TLS
if (strcmp (ptr + 1, "tls") == 0)
h = 63;
else
#endif
for (h = _DL_FIRST_EXTRA; h < 64; ++h)
if (hwcap_extra[h - _DL_FIRST_EXTRA] != NULL
&& !strcmp (ptr + 1, hwcap_extra[h - _DL_FIRST_EXTRA]))
break;
if (h == 64)
break;
}
}
Expand Down Expand Up @@ -636,7 +645,7 @@ search_dir (const struct dir_entry *entry)
if (opt_verbose)
{
if (hwcap != 0)
printf ("%s: (hwcap: 0x%" PRIx64 ")\n", entry->path, hwcap);
printf ("%s: (hwcap: %#.16" PRIx64 ")\n", entry->path, hwcap);
else
printf ("%s:\n", entry->path);
}
Expand Down Expand Up @@ -1017,6 +1026,53 @@ parse_conf (const char *filename, bool do_chroot)
if (dir[0] != '\0')
parse_conf_include (filename, lineno, do_chroot, dir);
}
else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
{
cp += 6;
char *p, *name = NULL;
unsigned long int n = strtoul (cp, &cp, 0);
if (cp != NULL && isblank (*cp))
while ((p = strsep (&cp, " \t")) != NULL)
if (p[0] != '\0')
{
if (name == NULL)
name = p;
else
{
name = NULL;
break;
}
}
if (name == NULL)
{
error (EXIT_FAILURE, 0, _("%s:%u: bad syntax in hwcap line"),
filename, lineno);
break;
}
if (n >= (64 - _DL_FIRST_EXTRA))
error (EXIT_FAILURE, 0,
_("%s:%u: hwcap index %lu above maximum %u"),
filename, lineno, n, 64 - _DL_FIRST_EXTRA - 1);
if (hwcap_extra[n] == NULL)
{
for (unsigned long int h = 0; h < (64 - _DL_FIRST_EXTRA); ++h)
if (hwcap_extra[h] != NULL && !strcmp (name, hwcap_extra[h]))
error (EXIT_FAILURE, 0,
_("%s:%u: hwcap index %lu already defined as %s"),
filename, lineno, h, name);
hwcap_extra[n] = xstrdup (name);
}
else
{
if (strcmp (name, hwcap_extra[n]))
error (EXIT_FAILURE, 0,
_("%s:%u: hwcap index %lu already defined as %s"),
filename, lineno, n, hwcap_extra[n]);
if (opt_verbose)
error (0, 0, _("%s:%u: duplicate hwcap %lu %s"),
filename, lineno, n, name);
}
}
else
add_dir (cp);
}
Expand Down Expand Up @@ -1118,6 +1174,10 @@ main (int argc, char **argv)
add_dir (argv[i]);
}

#ifdef USE_TLS
hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
#endif

set_hwcap ();

if (opt_chroot)
Expand Down
Loading

0 comments on commit ab1d521

Please sign in to comment.