+2016-09-09 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * elfread.c (auxv.h): New include.
+ (elf_gnu_ifunc_resolve_addr): Pass HWCAP to ifunc resolver.
+
2016-09-08 Tom Tromey <tom@tromey.com>
* remote.c (remote_notif_stop_ack, remote_wait_as)
#include "gdb_bfd.h"
#include "build-id.h"
#include "location.h"
+#include "auxv.h"
extern void _initialize_elfread (void);
CORE_ADDR start_at_pc, address;
struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
struct value *function, *address_val;
+ CORE_ADDR hwcap = 0;
+ struct value *hwcap_val;
/* Try first any non-intrusive methods without an inferior call. */
function = allocate_value (func_func_type);
set_value_address (function, pc);
- /* STT_GNU_IFUNC resolver functions have no parameters. FUNCTION is the
- function entry address. ADDRESS may be a function descriptor. */
+ /* STT_GNU_IFUNC resolver functions usually receive the HWCAP vector as
+ parameter. FUNCTION is the function entry address. ADDRESS may be a
+ function descriptor. */
- address_val = call_function_by_hand (function, 0, NULL);
+ target_auxv_search (¤t_target, AT_HWCAP, &hwcap);
+ hwcap_val = value_from_longest (builtin_type (gdbarch)
+ ->builtin_unsigned_long, hwcap);
+ address_val = call_function_by_hand (function, 1, &hwcap_val);
address = value_as_address (address_val);
address = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
¤t_target);
+2016-09-09 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * 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-06 Pedro Alves <palves@redhat.com>
* gdb.base/new-ui-pending-input.c: New file.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
extern volatile int gnu_ifunc_initialized;
+extern volatile unsigned long resolver_hwcap;
extern int init_stub (int arg);
extern int final (int arg);
asm (".type gnu_ifunc, %gnu_indirect_function");
final_t
-gnu_ifunc (void)
+gnu_ifunc (unsigned long hwcap)
{
+ resolver_hwcap = hwcap;
if (! gnu_ifunc_initialized)
return init_stub;
else
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)
{
gdb_test "p gnu_ifunc (3)" " = 4"
+# Test that the resolver received its argument.
+
+set actual_hwcap "0x0"
+set test "info auxv"
+gdb_test_multiple $test $test {
+ -re "\r\n\\d+\\s+AT_HWCAP\[^\r\n\]+($hex)\r\n.*$gdb_prompt $" {
+ set actual_hwcap $expect_out(1,string)
+ }
+ -re ".*$gdb_prompt $" {
+ pass "$test (no HWCAP)"
+ }
+}
+
+gdb_test "p/x resolver_hwcap" "= $actual_hwcap" "resolver received HWCAP"
+
# Test GDB will skip the gnu_ifunc resolver on first call.
gdb_test "step" "\r\nfinal .*"