Files
binutils-gdb/gdb/testsuite/gdb.base/gnu-ifunc.c
Andreas Arnez e1b2624a08 Pass HWCAP to ifunc resolver
On various GNU Elf architectures, including AArch64, ARM, s390/s390x,
ppc32/64, and sparc32/64, the dynamic loader passes HWCAP as a parameter
to each ifunc resolver.  Currently there is an open glibc Bugzilla that
requests this to be generalized to all architectures:

  https://sourceware.org/bugzilla/show_bug.cgi?id=19766

And various ifunc resolvers already rely on receiving HWCAP.  Currently
GDB always calls an ifunc resolver without any arguments; thus the
resolver may receive garbage, and based on that, the resolver may decide
to return a function that is not suited for the given platform.

This patch always passes HWCAP to ifunc resolvers, even on systems where
the dynamic loader currently behaves otherwise.  The rationale is
that (1) the dynamic loader may get adjusted on those systems as well in
the future; (2) passing an unused argument should not cause a problem
with existing resolvers; and (3) the logic is much simpler without such
a distinction.

gdb/ChangeLog:

	* elfread.c (auxv.h): New include.
	(elf_gnu_ifunc_resolve_addr): Pass HWCAP to ifunc resolver.

gdb/testsuite/ChangeLog:

	* gdb.base/gnu-ifunc-lib.c (resolver_hwcap): New external
	variable declaration.
	(gnu_ifunc): Add parameter hwcap.  Store it in resolver_hwcap.
	* gdb.base/gnu-ifunc.c (resolver_hwcap): New global variable.
	* gdb.base/gnu-ifunc.exp: Add test to verify that the resolver
	received HWCAP as its argument.
2016-09-09 19:59:53 +02:00

66 lines
1.5 KiB
C

/* This testcase is part of GDB, the GNU debugger.
Copyright 2009-2016 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
int
init_stub (int arg)
{
return 0;
}
int
final (int arg)
{
return arg + 1;
}
/* Make differentiation of how the gnu_ifunc call resolves before and after
calling gnu_ifunc_pre. This ensures the resolved function address is not
being cached anywhere for the debugging purposes. */
volatile int gnu_ifunc_initialized;
/* This stores the argument received by the ifunc resolver. */
volatile unsigned long resolver_hwcap = -1;
static void
gnu_ifunc_pre (void)
{
assert (!gnu_ifunc_initialized);
gnu_ifunc_initialized = 1;
}
extern int gnu_ifunc (int arg);
int
main (void)
{
int i;
gnu_ifunc_pre ();
i = gnu_ifunc (1); /* break-at-call */
assert (i == 2);
gnu_ifunc (2); /* break-at-nextcall */
return 0; /* break-at-exit */
}