/* 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
#include <stdio_ext.h>
#include <locale.h>
#include <stdlib.h>
-#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)
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)
handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi,
GElf_Addr pc, struct stuff *stuff)
{
+ if (cfi == NULL)
+ {
+ printf ("handle_cfi no CFI (%s): %s\n", which, dwarf_errmsg (-1));
+ return -1;
+ }
+
int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame);
if (result != 0)
{
- error (0, 0, "dwarf_cfi_addrframe (%s): %s", which, dwarf_errmsg (-1));
+ printf ("dwarf_cfi_addrframe (%s): %s\n", which, dwarf_errmsg (-1));
return 1;
}
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);