summaryrefslogtreecommitdiffstats
path: root/tests/addrcfi.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2013-08-27 15:40:56 +0200
committerMark Wielaard <[email protected]>2013-09-02 23:20:00 +0200
commit292b1787b6ccc429ebba177600dffdb5b33443f7 (patch)
tree75cca24450b1d98767a33af06d89f49f787580bb /tests/addrcfi.c
parent20f4c123ba93a56798c0819e33f527611fc0ce47 (diff)
tests: Add run-addrcfi.sh test for libdw cfi dwarf_frame_* functions.
We require architecture backends to implement the ebl abi_cfi hook to provide the ABI's default CFI program as used by the libdw dwarf cfi functions. There is the addrcfi test program that prints the return address, cfa location expression and register states as returned by various dwarf_cfi_* and dwarf_frame functions. But that has to be run by hand. The new run-addrcfi.sh tests hooks addrcfi up to some existing architecture specific test files and known addresses to more easily (and automaticly) check that the default CFI program is implemented correctly and to test the libdw cfi frame info functionality. Only i386 and x86_64 are tested for now since other backends don't have the abi_cfi hook yet. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'tests/addrcfi.c')
-rw-r--r--tests/addrcfi.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/tests/addrcfi.c b/tests/addrcfi.c
index bc8bc32b..7678884b 100644
--- a/tests/addrcfi.c
+++ b/tests/addrcfi.c
@@ -1,5 +1,5 @@
/* Test program for CFI handling.
- Copyright (C) 2009-2010 Red Hat, Inc.
+ Copyright (C) 2009-2010, 2013 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -28,6 +28,25 @@
#include <error.h>
#include <string.h>
+#include "../libdw/known-dwarf.h"
+
+static const char *
+op_name (unsigned int code)
+{
+ static const char *const known[] =
+ {
+#define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE)
+#define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
+ ALL_KNOWN_DW_OP
+#undef ONE_KNOWN_DW_OP
+#undef ONE_KNOWN_DW_OP_DESC
+ };
+
+ if (likely (code < sizeof (known) / sizeof (known[0])))
+ return known[code];
+
+ return NULL;
+}
static void
print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias)
@@ -35,13 +54,13 @@ print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias)
if (result < 0)
printf ("indeterminate (%s)\n", dwarf_errmsg (-1));
else if (nops == 0)
- printf ("%s\n", result == 0 ? "same_value" : "undefined");
+ printf ("%s\n", ops == NULL ? "same_value" : "undefined");
else
{
printf ("%s expression:", result == 0 ? "location" : "value");
for (size_t i = 0; i < nops; ++i)
{
- printf (" %#x", ops[i].atom);
+ printf (" %s", op_name(ops[i].atom));
if (ops[i].number2 == 0)
{
if (ops[i].atom == DW_OP_addr)
@@ -116,7 +135,10 @@ handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi,
printf ("\treturn address in reg%u%s\n",
ra_regno, signalp ? " (signal frame)" : "");
- Dwarf_Op *cfa_ops;
+ // Point cfa_ops to dummy to match print_detail expectations.
+ // (nops == 0 && cfa_ops != NULL => "undefined")
+ Dwarf_Op dummy;
+ Dwarf_Op *cfa_ops = &dummy;
size_t cfa_nops;
result = dwarf_frame_cfa (stuff->frame, &cfa_ops, &cfa_nops);