merge of e2a995c33fd064248b6f0ea6bac17108b3c258a9
     and f565e33ab1efbd438729f7ef059a5a943a5e1bd6
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 70fbf62..dc56748 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-29  Roland McGrath  <roland@redhat.com>
+
+	* loc2c.c: File removed.
+	* loc2c.h: File removed.
+	* loc2c-runtime.h: File removed.
+	* test2.c: File removed.
+	* Makefile.am (EXTRA_DIST): Variable removed.
+	(noinst_HEADERS): Remove loc2c.h from here.
+
 2005-07-28  Ulrich Drepper  <drepper@redhat.com>
 
 	* libdwfl.h: Add a few missing extern for function prototypes.
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index 217cde2..243f67f 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -25,8 +25,6 @@
 	   -I$(srcdir)/../libdw -I.. -I$(srcdir)/../lib
 VERSION = 1
 
-EXTRA_DIST = test2.c loc2c.c
-
 noinst_LIBRARIES = libdwfl.a
 if !MUDFLAP
 noinst_LIBRARIES += libdwfl_pic.a
@@ -78,6 +76,6 @@
 	fi
 endif
 
-noinst_HEADERS = libdwflP.h loc2c.h
+noinst_HEADERS = libdwflP.h
 
 CLEANFILES = $(am_libdwfl_pic_a_OBJECTS)
diff --git a/libdwfl/loc2c-runtime.h b/libdwfl/loc2c-runtime.h
deleted file mode 100644
index af27f79..0000000
--- a/libdwfl/loc2c-runtime.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* target operations */
-
-#include <linux/types.h>
-#define intptr_t long
-#define uintptr_t unsigned long
-
-
-/* These three macro definitions are generic, just shorthands
-   used by the generated code.  */
-
-#define op_abs(x)	(x < 0 ? -x : x)
-
-#define fetch_bitfield(target, base, higherbits, nbits)			      \
-  target = (((base) >> (sizeof (base) * 8 - (higherbits) - (nbits)))	      \
-	    & (((__typeof (base)) 1 << (nbits)) - 1))
-
-#define store_bitfield(target, base, higherbits, nbits)			      \
-  target = (target							      \
-	    &~ ((((__typeof (base)) 1 << (nbits)) - 1)			      \
-		<< (sizeof (base) * 8 - (higherbits) - (nbits)))	      \
-	    | ((__typeof (base)) (value)				      \
-	       << (sizeof (base) * 8 - (higherbits) - (nbits))))
-
-
-/* These operations are target-specific.  */
-#include <asm/uaccess.h>
-
-#define fetch_register(regno) ((intptr_t) regs->dwarf_register_##regno)
-
-#if defined __i386__
-
-#define dwarf_register_0 eax
-#define dwarf_register_1 ecx
-#define dwarf_register_2 edx
-#define dwarf_register_3 ebx
-#define dwarf_register_4 esp
-#define dwarf_register_5 ebp
-#define dwarf_register_6 esi
-#define dwarf_register_7 edi
-
-#elif defined __x86_64__
-
-#define dwarf_register_0 eax
-#define dwarf_register_1 edx
-#define dwarf_register_2 ecx
-#define dwarf_register_3 ebx
-#define dwarf_register_4 esi
-#define dwarf_register_5 edi
-#define dwarf_register_6 ebp
-#define dwarf_register_7 esp
-#define dwarf_register_8 r8
-#define dwarf_register_9 r9
-#define dwarf_register_10 r10
-#define dwarf_register_11 r11
-#define dwarf_register_12 r12
-#define dwarf_register_13 r13
-#define dwarf_register_14 r14
-#define dwarf_register_15 r15
-
-#elif defined __powerpc__
-
-#undef fetch_register
-#define fetch_register(regno) ((intptr_t) regs->gpr[regno])
-
-#endif
-
-#if defined __i386__ || defined __x86_64__
-
-#define deref(size, addr)						      \
-  ({									      \
-    int _bad = 0;							      \
-    u8 _b; u16 _w; u32 _l; u64 _q;					      \
-    intptr_t _v;							      \
-    switch (size)							      \
-      {									      \
-      case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break;    \
-      case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break;    \
-      case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break;     \
-      case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break;     \
-      default: _v = __get_user_bad();					      \
-      }									      \
-    if (_bad)								      \
-      goto deref_fault;							      \
-    _v;									      \
-  })
-
-#elif defined __powerpc64__
-
-#define deref(size, addr)						      \
-  ({									      \
-    int _bad = 0;							      \
-    intptr_t _v;							      \
-    switch (size)							      \
-      {									      \
-      case 1: __get_user_asm(_v,addr,_bad,"lbz",1); break;		      \
-      case 2: __get_user_asm(_v,addr,_bad,"lhz",1); break;		      \
-      case 4: __get_user_asm(_v,addr,_bad,"lwz",1); break;		      \
-      case 8: __get_user_asm(_v,addr,_bad,"ld",1); break;		      \
-      default: _v = __get_user_bad();					      \
-      }									      \
-    if (_bad)								      \
-      goto deref_fault;							      \
-    _v;									      \
-  })
-
-#elif defined __powerpc__
-
-#define deref(size, addr)						      \
-  ({									      \
-    int _bad = 0;							      \
-    intptr_t _v;							      \
-    switch (size)							      \
-      {									      \
-      case 1: __get_user_asm(_v,addr,_bad,"lbz"); break;		      \
-      case 2: __get_user_asm(_v,addr,_bad,"lhz"); break;		      \
-      case 4: __get_user_asm(_v,addr,_bad,"lwz"); break;		      \
-      case 8: __get_user_asm(_v,addr,_bad,"ld"); break;			      \
-      default: _v = __get_user_bad();					      \
-      }									      \
-    if (_bad)								      \
-      goto deref_fault;							      \
-    _v;									      \
-  })
-
-#endif
diff --git a/libdwfl/loc2c.c b/libdwfl/loc2c.c
deleted file mode 100644
index 816eb06..0000000
--- a/libdwfl/loc2c.c
+++ /dev/null
@@ -1,1398 +0,0 @@
-#include <config.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <obstack.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <error.h>
-#include <dwarf.h>
-#include <libdw.h>
-#include <assert.h>
-
-#define _(x) x
-
-#define STACK_TYPE	"intptr_t"  /* Must be the signed type.  */
-#define UTYPE		"uintptr_t" /* Must be the unsigned type.  */
-#define SFORMAT		"%" PRId64 "L"
-#define UFORMAT		"%" PRIu64 "UL"
-#define AFORMAT		"%#" PRIx64 "UL"
-#define STACKFMT	"s%u"
-
-struct location
-{
-  struct location *next;
-
-  const Dwarf_Loc *ops;
-  size_t nops;
-
-  Dwarf_Word byte_size;
-
-  enum { loc_address, loc_register, loc_noncontiguous, loc_final } type;
-  union
-  {
-    struct			/* loc_address or loc_final */
-    {
-      char *program;		/* C fragment, leaves address in s0.  */
-      unsigned int stack_depth;	/* Temporaries "s0..<N>" used by it.  */
-      struct location *frame_base;
-      bool used_deref;		/* Program uses "deref" macro.  */
-    } address;
-    unsigned int regno;		/* loc_register */
-    struct location *pieces;	/* loc_noncontiguous */
-  };
-};
-
-
-static const char *
-dwarf_diename_integrate (Dwarf_Die *die)
-{
-  Dwarf_Attribute attr_mem;
-  return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
-}
-
-/* Synthesize a new loc_address using the program on the obstack.  */
-static struct location *
-new_synthetic_loc (struct obstack *pool, struct location *origin, bool deref)
-{
-  obstack_1grow (pool, '\0');
-  char *program = obstack_finish (pool);
-
-  struct location *loc = obstack_alloc (pool, sizeof *loc);
-  loc->next = NULL;
-  loc->byte_size = 0;
-  loc->type = loc_address;
-  loc->address.program = program;
-  loc->address.stack_depth = 0;
-  loc->address.frame_base = NULL;
-  loc->address.used_deref = deref;
-
-  if (origin->type == loc_register)
-    {
-      loc->ops = origin->ops;
-      loc->nops = origin->nops;
-    }
-  else
-    {
-      loc->ops = NULL;
-      loc->nops = 0;
-    }
-
-  return loc;
-}
-
-
-/* Die in the middle of an expression.  */
-static struct location *
-lose (const char *failure, const Dwarf_Loc *lexpr, size_t i)
-{
-  error (2, 0, _("%s in DWARF expression [%Zu] at %" PRIu64
-		 " (%#x: %" PRId64 ", %" PRId64 ")"),
-	 failure, i, lexpr[i].offset,
-	 lexpr[i].atom, lexpr[i].number, lexpr[i].number2);
-  return NULL;
-}
-
-/* Translate a (constrained) DWARF expression into C code
-   emitted to the obstack POOL.  INDENT is the number of indentation levels.
-   ADDRBIAS is the difference between runtime and Dwarf info addresses.
-   INPUT is null or an expression to be initially pushed on the stack.
-   If NEED_FB is null, fail on DW_OP_fbreg, else set *NEED_FB to true
-   and emit "frame_base" for it.  On success, set *MAX_STACK to the number
-   of stack slots required.  On failure, set *LOSER to the index in EXPR
-   of the operation we could not handle.
-
-   Returns a failure message or null for success.  */
-
-static const char *
-translate (struct obstack *pool, int indent, Dwarf_Addr addrbias,
-	   const Dwarf_Loc *expr, const size_t len,
-	   struct location *input,
-	   bool *need_fb, size_t *loser,
-	   struct location *loc)
-{
-  loc->ops = expr;
-  loc->nops = len;
-
-#define DIE(msg) return (*loser = i, _(msg))
-
-#define emit(fmt, ...) obstack_printf (pool, fmt, ## __VA_ARGS__)
-
-  unsigned int stack_depth = 0, max_stack = 0;
-  inline void deepen (void)
-    {
-      if (stack_depth == max_stack)
-	++max_stack;
-    }
-
-#define POP(var)							      \
-    if (stack_depth > 0)						      \
-      --stack_depth;							      \
-    else if (tos_register != -1)					      \
-      fetch_tos_register ();						      \
-    else								      \
-      goto underflow;							      \
-    int var = stack_depth
-#define PUSH 		(deepen (), stack_depth++)
-#define STACK(idx)	(stack_depth - 1 - (idx))
-
-  /* Don't put stack operations in the arguments to this.  */
-#define push(fmt, ...) \
-  emit ("%*s" STACKFMT " = " fmt ";\n", indent * 2, "", PUSH, ## __VA_ARGS__)
-
-  int tos_register = -1;
-  inline void fetch_tos_register (void)
-    {
-      deepen ();
-      emit ("%*s" STACKFMT " = fetch_register (%d);\n",
-	    indent * 2, "", stack_depth, tos_register);
-      tos_register = -1;
-    }
-
-  if (input != NULL)
-    switch (input->type)
-      {
-      case loc_address:
-	push ("addr");
-	break;
-
-      case loc_register:
-	tos_register = input->regno;
-	break;
-
-      default:
-	abort ();
-	break;
-      }
-
-  size_t i;
-
-  inline const char *finish (struct location *piece)
-    {
-      if (stack_depth > 1)
-	DIE ("multiple values left on stack");
-      if (stack_depth == 1)
-	{
-	  obstack_1grow (pool, '\0');
-	  char *program = obstack_finish (pool);
-	  piece->type = loc_address;
-	  piece->address.program = program;
-	  piece->address.stack_depth = max_stack;
-	  piece->address.frame_base = NULL;
-	}
-      else if (tos_register == -1)
-	DIE ("stack underflow");
-      else if (obstack_object_size (pool) != 0)
-	DIE ("register value must stand alone in location expression");
-      else
-	{
-	  piece->type = loc_register;
-	  piece->regno = tos_register;
-	}
-      return NULL;
-    }
-
-  struct location *pieces = NULL, **tailpiece = &pieces;
-  size_t piece_expr_start = 0;
-  for (i = 0; i < len; ++i)
-    {
-      unsigned int reg;
-      uint_fast8_t sp;
-      Dwarf_Word value;
-
-      switch (expr[i].atom)
-	{
-	  /* Basic stack operations.  */
-	case DW_OP_nop:
-	  break;
-
-	case DW_OP_dup:
-	  if (stack_depth < 1)
-	    goto underflow;
-	  else
-	    {
-	      unsigned int tos = STACK (0);
-	      push (STACKFMT, tos);
-	    }
-	  break;
-
-	case DW_OP_drop:
-	  POP (ignore);
-	  emit ("%*s/* drop " STACKFMT "*/\n", indent * 2, "", ignore);
-	  break;
-
-	case DW_OP_pick:
-	  sp = expr[i].number;
-	op_pick:
-	  if (sp >= stack_depth)
-	    goto underflow;
-	  sp = STACK (sp);
-	  push (STACKFMT, sp);
-	  break;
-
-	case DW_OP_over:
-	  sp = 1;
-	  goto op_pick;
-
-	case DW_OP_swap:
-	  if (stack_depth < 2)
-	    goto underflow;
-	  deepen ();		/* Use a temporary slot.  */
-	  emit ("%*s"
-		STACKFMT " = " STACKFMT ", "
-		STACKFMT " = " STACKFMT ", "
-		STACKFMT " = " STACKFMT ";\n",
-		indent * 2, "",
-		STACK (-1), STACK (0),
-		STACK (0), STACK (1),
-		STACK (1), STACK (-1));
-	  break;
-
-	case DW_OP_rot:
-	  if (stack_depth < 3)
-	    goto underflow;
-	  deepen ();		/* Use a temporary slot.  */
-	  emit ("%*s"
-		STACKFMT " = " STACKFMT ", "
-		STACKFMT " = " STACKFMT ", "
-		STACKFMT " = " STACKFMT ", "
-		STACKFMT " = " STACKFMT ";\n",
-		indent * 2, "",
-		STACK (-1), STACK (0),
-		STACK (0), STACK (1),
-		STACK (1), STACK (2),
-		STACK (3), STACK (-1));
-	  break;
-
-
-	  /* Control flow operations.  */
-	case DW_OP_skip:
-	  {
-	    Dwarf_Off target = expr[i].offset + 3 + expr[i].number;
-	    while (i + 1 < len && expr[i + 1].offset < target)
-	      ++i;
-	    if (expr[i + 1].offset != target)
-	      DIE ("invalid skip target");
-	    break;
-	  }
-
-	case DW_OP_bra:
-	  DIE ("conditional branches not supported");
-	  break;
-
-
-	  /* Memory access.  */
-	case DW_OP_deref:
-	  {
-	    POP (addr);
-	    push ("deref (sizeof (void *), " STACKFMT ")", addr);
-	    loc->address.used_deref = true;
-	  }
-	  break;
-
-	case DW_OP_deref_size:
-	  {
-	    POP (addr);
-	    push ("deref (" UFORMAT ", " STACKFMT ")",
-		  expr[i].number, addr);
-	    loc->address.used_deref = true;
-	  }
-	  break;
-
-	case DW_OP_xderef:
-	  {
-	    POP (addr);
-	    POP (as);
-	    push ("xderef (sizeof (void *), " STACKFMT ", " STACKFMT ")",
-		  addr, as);
-	    loc->address.used_deref = true;
-	  }
-	  break;
-
-	case DW_OP_xderef_size:
-	  {
-	    POP (addr);
-	    POP (as);
-	    push ("xderef (" UFORMAT ", " STACKFMT ", " STACKFMT ")",
-		  expr[i].number, addr, as);
-	    loc->address.used_deref = true;
-	  }
-	  break;
-
-	  /* Constant-value operations.  */
-
-	case DW_OP_addr:
-	  push (AFORMAT, addrbias + expr[i].number);
-	  break;
-
-	case DW_OP_lit0 ... DW_OP_lit31:
-	  value = expr[i].atom - DW_OP_lit0;
-	  goto op_const;
-
-	case DW_OP_const1u:
-	case DW_OP_const1s:
-	case DW_OP_const2u:
-	case DW_OP_const2s:
-	case DW_OP_const4u:
-	case DW_OP_const4s:
-	case DW_OP_const8u:
-	case DW_OP_const8s:
-	case DW_OP_constu:
-	case DW_OP_consts:
-	  value = expr[i].number;
-	op_const:
-	  push (SFORMAT, value);
-	  break;
-
-	  /* Arithmetic operations.  */
-#define UNOP(dw_op, c_op)						      \
-	case DW_OP_##dw_op:						      \
-	  {								      \
-	    POP (tos);							      \
-	    push ("%s (" STACKFMT ")", #c_op, tos);			      \
-	  }								      \
-	  break
-#define BINOP(dw_op, c_op)						      \
-	case DW_OP_##dw_op:						      \
-	  {								      \
-	    POP (b);							      \
-	    POP (a);							      \
-	    push (STACKFMT " %s " STACKFMT, a, #c_op, b);		      \
-	  }								      \
-	  break
-
-	  UNOP (abs, op_abs);
-	  BINOP (and, &);
-	  BINOP (div, /);
-	  BINOP (minus, -);
-	  BINOP (mod, %);
-	  BINOP (mul, *);
-	  UNOP (neg, -);
-	  UNOP (not, ~);
-	  BINOP (or, |);
-	  BINOP (plus, +);
-	  BINOP (shl, <<);
-	  BINOP (shra, >>);
-	  BINOP (xor, ^);
-
-	  /* Comparisons are binary operators too.  */
-	  BINOP (le, <=);
-	  BINOP (ge, >=);
-	  BINOP (eq, ==);
-	  BINOP (lt, <);
-	  BINOP (gt, >);
-	  BINOP (ne, !=);
-
-#undef	UNOP
-#undef	BINOP
-
-	case DW_OP_shr:
-	  {
-	    POP (b);
-	    POP (a);
-	    push ("(%s) " STACKFMT " >> (%s)" STACKFMT,
-		  UTYPE, a, UTYPE, b);
-	    break;
-	  }
-
-	case DW_OP_plus_uconst:
-	  {
-	    POP (x);
-	    push (STACKFMT " + " UFORMAT, x, expr[i].number);
-	  }
-	  break;
-
-
-	  /* Register-relative addressing.  */
-	case DW_OP_breg0 ... DW_OP_breg31:
-	  reg = expr[i].atom - DW_OP_breg0;
-	  value = expr[i].number;
-	  goto op_breg;
-
-	case DW_OP_bregx:
-	  reg = expr[i].number;
-	  value = expr[i].number2;
-	op_breg:
-	  push ("fetch_register (%u) + " SFORMAT, reg, value);
-	  break;
-
-	case DW_OP_fbreg:
-	  if (need_fb == NULL)
-	    DIE ("DW_OP_fbreg from DW_AT_frame_base");
-	  *need_fb = true;
-	  push ("frame_base + " SFORMAT, expr[i].number);
-	  break;
-
-	  /* Direct register contents.  */
-	case DW_OP_reg0 ... DW_OP_reg31:
-	  reg = expr[i].atom - DW_OP_reg0;
-	  goto op_reg;
-
-	case DW_OP_regx:
-	  reg = expr[i].number;
-	op_reg:
-	  tos_register = reg;
-	  break;
-
-	  /* Special magic.  */
-	case DW_OP_piece:
-	  if (stack_depth > 1)
-	    /* If this ever happens we could copy the program.  */
-	    DIE ("DW_OP_piece left multiple values on stack");
-	  else
-	    {
-	      struct location *piece = obstack_alloc (pool, sizeof *piece);
-	      const char *failure = finish (piece);
-	      if (unlikely (failure != NULL))
-		return failure;
-
-	      piece->ops = &expr[piece_expr_start];
-	      piece->nops = i - piece_expr_start;
-	      piece_expr_start = i + 1;
-
-	      piece->byte_size = expr[i].number;
-
-	      *tailpiece = piece;
-	      tailpiece = &piece->next;
-	      piece->next = NULL;
-	    }
-	  break;
-
-	case DW_OP_push_object_address:
-	  DIE ("XXX DW_OP_push_object_address");
-	  break;
-
-	default:
-	  DIE ("unrecognized operation");
-	  break;
-	}
-    }
-
-  if (likely (pieces == NULL))
-    return finish (loc);
-
-  if (piece_expr_start != i)
-    DIE ("extra operations after last DW_OP_piece");
-
-  loc->type = loc_noncontiguous;
-  loc->pieces = pieces;
-
-  return NULL;
-
- underflow:
-  DIE ("stack underflow");
-
-#undef emit
-#undef push
-#undef PUSH
-#undef POP
-#undef STACK
-#undef DIE
-}
-
-/* Translate a location starting from an address or nothing.  */
-static struct location *
-location_from_address (struct obstack *pool,
-		       int indent, Dwarf_Addr dwbias,
-		       const Dwarf_Loc *expr, size_t len, Dwarf_Addr address,
-		       struct location **input, Dwarf_Attribute *fb_attr)
-{
-  bool need_fb = false;
-  size_t loser;
-  struct location *loc = obstack_alloc (pool, sizeof *loc);
-  const char *failure = translate (pool, indent + 1, dwbias, expr, len,
-				   *input, &need_fb, &loser, loc);
-  if (unlikely (failure != NULL))
-    return lose (failure, expr, loser);
-
-  loc->next = NULL;
-  if (need_fb)
-    {
-      /* The main expression uses DW_OP_fbreg, so we need to compute
-	 the DW_AT_frame_base attribute expression's value first.  */
-
-      Dwarf_Loc *fb_expr;
-      size_t fb_len;
-      switch (dwarf_addrloclists (fb_attr, address - dwbias,
-				  &fb_expr, &fb_len, 1))
-	{
-	case 1:			/* Should always happen.  */
-	  if (fb_len == 0)
-	    goto fb_inaccessible;
-	  break;
-
-	default:		/* Shouldn't happen.  */
-	case -1:
-	  error (2, 0, "dwarf_addrloclists (form %#x): %s",
-		 dwarf_whatform (fb_attr), dwarf_errmsg (-1));
-	  return NULL;
-
-	case 0:			/* Shouldn't happen.  */
-	fb_inaccessible:
-	  error (2, 0, "DW_AT_frame_base not accessible at this address");
-	  return NULL;
-	}
-
-      loc->address.frame_base = obstack_alloc (pool, sizeof *loc);
-      failure = translate (pool, indent + 1, dwbias, fb_expr, fb_len, NULL,
-			   NULL, &loser, loc->address.frame_base);
-      if (unlikely (failure != NULL))
-	return lose (failure, fb_expr, loser);
-    }
-
-  if (*input != NULL)
-    (*input)->next = loc;
-  *input = loc;
-
-  return loc;
-}
-
-/* Translate a location starting from a non-address "on the top of the
-   stack".  The *INPUT location is a register name or noncontiguous
-   object specification, and this expression wants to find the "address"
-   of an object relative to that "address".  */
-
-static struct location *
-location_relative (struct obstack *pool,
-		   int indent, Dwarf_Addr dwbias,
-		   const Dwarf_Loc *expr, size_t len, Dwarf_Addr address,
-		   struct location **input, Dwarf_Attribute *fb_attr)
-{
-  Dwarf_Sword *stack;
-  unsigned int stack_depth = 0, max_stack = 0;
-  inline void deepen (void)
-    {
-      if (stack_depth == max_stack)
-	{
-	  ++max_stack;
-	  obstack_blank (pool, sizeof stack[0]);
-	  stack = (void *) obstack_base (pool);
-	}
-    }
-
-#define POP(var)							      \
-    if (stack_depth > 0)						      \
-      --stack_depth;							      \
-    else								      \
-      goto underflow;							      \
-    int var = stack_depth
-#define PUSH 		(deepen (), stack_depth++)
-#define STACK(idx)	(stack_depth - 1 - (idx))
-#define STACKWORD(idx)	stack[STACK (idx)]
-
-  /* Don't put stack operations in the arguments to this.  */
-#define push(value) (stack[PUSH] = (value))
-
-  const char *failure = NULL;
-#define DIE(msg) do { failure = _(msg); goto fail; } while (0)
-
-  struct location *head = NULL;
-  size_t i;
-  for (i = 0; i < len; ++i)
-    {
-      uint_fast8_t sp;
-      Dwarf_Word value;
-
-      switch (expr[i].atom)
-	{
-	  /* Basic stack operations.  */
-	case DW_OP_nop:
-	  break;
-
-	case DW_OP_dup:
-	  if (stack_depth < 1)
-	    goto underflow;
-	  else
-	    {
-	      unsigned int tos = STACK (0);
-	      push (stack[tos]);
-	    }
-	  break;
-
-	case DW_OP_drop:
-	  if (stack_depth > 0)
-	    --stack_depth;
-	  else if (*input != NULL)
-	    /* Mark that we have consumed the input.  */
-	    *input = NULL;
-	  else
-	    /* Hits if cleared above, or if we had no input at all.  */
-	    goto underflow;
-	  break;
-
-	case DW_OP_pick:
-	  sp = expr[i].number;
-	op_pick:
-	  if (sp >= stack_depth)
-	    goto underflow;
-	  sp = STACK (sp);
-	  push (stack[sp]);
-	  break;
-
-	case DW_OP_over:
-	  sp = 1;
-	  goto op_pick;
-
-	case DW_OP_swap:
-	  if (stack_depth < 2)
-	    goto underflow;
-	  deepen ();		/* Use a temporary slot.  */
-	  STACKWORD (-1) = STACKWORD (0);
-	  STACKWORD (0) = STACKWORD (1);
-	  STACKWORD (1) = STACKWORD (-1);
-	  break;
-
-	case DW_OP_rot:
-	  if (stack_depth < 3)
-	    goto underflow;
-	  deepen ();		/* Use a temporary slot.  */
-	  STACKWORD (-1) = STACKWORD (0);
-	  STACKWORD (0) = STACKWORD (1);
-	  STACKWORD (2) = STACKWORD (2);
-	  STACKWORD (2) = STACKWORD (-1);
-	  break;
-
-
-	  /* Control flow operations.  */
-	case DW_OP_bra:
-	  {
-	    POP (taken);
-	    if (stack[taken] == 0)
-	      break;
-	  }
-	  /*FALLTHROUGH*/
-
-	case DW_OP_skip:
-	  {
-	    Dwarf_Off target = expr[i].offset + 3 + expr[i].number;
-	    while (i + 1 < len && expr[i + 1].offset < target)
-	      ++i;
-	    if (expr[i + 1].offset != target)
-	      DIE ("invalid skip target");
-	    break;
-	  }
-
-	  /* Memory access.  */
-	case DW_OP_deref:
-	case DW_OP_deref_size:
-	case DW_OP_xderef:
-	case DW_OP_xderef_size:
-
-	  /* Register-relative addressing.  */
-	case DW_OP_breg0 ... DW_OP_breg31:
-	case DW_OP_bregx:
-	case DW_OP_fbreg:
-
-	  /* This started from a register, but now it's following a pointer.
-	     So we can do the translation starting from address here.  */
-	  return location_from_address (pool, indent, dwbias,
-					expr, len, address, input, fb_attr);
-
-
-	  /* Constant-value operations.  */
-	case DW_OP_addr:
-	  push (dwbias + expr[i].number);
-	  break;
-
-	case DW_OP_lit0 ... DW_OP_lit31:
-	  value = expr[i].atom - DW_OP_lit0;
-	  goto op_const;
-
-	case DW_OP_const1u:
-	case DW_OP_const1s:
-	case DW_OP_const2u:
-	case DW_OP_const2s:
-	case DW_OP_const4u:
-	case DW_OP_const4s:
-	case DW_OP_const8u:
-	case DW_OP_const8s:
-	case DW_OP_constu:
-	case DW_OP_consts:
-	  value = expr[i].number;
-	op_const:
-	  push (value);
-	  break;
-
-	  /* Arithmetic operations.  */
-#define UNOP(dw_op, c_op)						      \
-	case DW_OP_##dw_op:						      \
-	  {								      \
-	    POP (tos);							      \
-	    push (c_op (stack[tos])); 					      \
-	  }								      \
-	  break
-#define BINOP(dw_op, c_op)						      \
-	case DW_OP_##dw_op:						      \
-	  {								      \
-	    POP (b);							      \
-	    POP (a);							      \
- 	    push (stack[a] c_op stack[b]);				      \
-	  }								      \
-	  break
-
-#define op_abs(x) (x < 0 ? -x : x)
-	  UNOP (abs, op_abs);
-	  BINOP (and, &);
-	  BINOP (div, /);
-	  BINOP (mod, %);
-	  BINOP (mul, *);
-	  UNOP (neg, -);
-	  UNOP (not, ~);
-	  BINOP (or, |);
-	  BINOP (shl, <<);
-	  BINOP (shra, >>);
-	  BINOP (xor, ^);
-
-	  /* Comparisons are binary operators too.  */
-	  BINOP (le, <=);
-	  BINOP (ge, >=);
-	  BINOP (eq, ==);
-	  BINOP (lt, <);
-	  BINOP (gt, >);
-	  BINOP (ne, !=);
-
-#undef	UNOP
-#undef	BINOP
-
-	case DW_OP_shr:
-	  {
-	    POP (b);
-	    POP (a);
-	    push ((Dwarf_Word) stack[a] >> (Dwarf_Word) stack[b]);
-	    break;
-	  }
-
-	  /* Simple addition we may be able to handle relative to
-	     the starting register name.  */
-	case DW_OP_minus:
-	  {
-	    POP (tos);
-	    value = -stack[tos];
-	    goto plus;
-	  }
-	case DW_OP_plus:
-	  {
-	    POP (tos);
-	    value = stack[tos];
-	    goto plus;
-	  }
-	case DW_OP_plus_uconst:
-	  value = expr[i].number;
-	plus:
-	  if (stack_depth > 0)
-	    {
-	      /* It's just private diddling after all.  */
-	      POP (a);
-	      push (stack[a] + value);
-	      break;
-	    }
-	  if (*input == NULL)
-	    goto underflow;
-
-	  /* This is the primary real-world case: the expression takes
-	     the input address and adds a constant offset.  */
-
-	  while ((*input)->type == loc_noncontiguous)
-	    {
-	      /* We are starting from a noncontiguous object (DW_OP_piece).
-		 Find the piece we want.  */
-
-	      struct location *piece = (*input)->pieces;
-	      while (piece != NULL && value >= piece->byte_size)
-		{
-		  value -= piece->byte_size;
-		  piece = piece->next;
-		}
-	      if (piece == NULL)
-		DIE ("offset outside available pieces");
-
-	      *input = piece;
-	    }
-
-	  switch ((*input)->type)
-	    {
-	    case loc_address:
-	      {
-		/* The piece we want is actually in memory.  Use the same
-		   program to compute the address from the preceding input.  */
-
-		struct location *loc = obstack_alloc (pool, sizeof *loc);
-		*loc = **input;
-		if (head == NULL)
-		  head = loc;
-		(*input)->next = loc;
-		if (value == 0)
-		  {
-		    /* The piece addresses exactly where we want to go.  */
-		    loc->next = NULL;
-		    *input = loc;
-		  }
-		else
-		  {
-		    /* Add a second fragment to offset the piece address.  */
-		    obstack_printf (pool, "%*saddr += " SFORMAT "\n",
-				    indent * 2, "", value);
-		    *input = loc->next = new_synthetic_loc (pool, *input,
-							    false);
-		  }
-
-		if (i + 1 < len)
-		  {
-		    /* This expression keeps going, but further
-		       computations now have an address to start with.
-		       So we can punt to the address computation generator.  */
-		    loc = location_from_address (pool, indent, dwbias,
-						 &expr[i + 1], len - i - 1,
-						 address, input, fb_attr);
-		    if (loc == NULL)
-		      return NULL;
-		  }
-
-		/* That's all she wrote.  */
-		return head;
-	      }
-
-	    case loc_register:
-	      // XXX
-
-	    default:
-	      abort ();
-	    }
-	  break;
-
-	  /* Direct register contents.  */
-	case DW_OP_reg0 ... DW_OP_reg31:
-	case DW_OP_regx:
-	  DIE ("register");
-	  break;
-
-	  /* Special magic.  */
-	case DW_OP_piece:
-	  DIE ("DW_OP_piece");
-	  break;
-
-	case DW_OP_push_object_address:
-	  DIE ("XXX DW_OP_push_object_address");
-	  break;
-
-	default:
-	  DIE ("unrecognized operation");
-	  break;
-	}
-    }
-
-  if (stack_depth > 1)
-    DIE ("multiple values left on stack");
-
-  if (stack_depth > 0)		/* stack_depth == 1 */
-    {
-      if (*input != NULL)
-	DIE ("multiple values left on stack");
-
-      /* Could handle this if it ever actually happened.  */
-      DIE ("relative expression computed constant");
-    }
-
-  return head;
-
- underflow:
-  if (*input == NULL)
-    DIE ("stack underflow");
-  else
-    DIE ("cannot handle location expression");
-
- fail:
-  return lose (failure, expr, i);
-}
-
-
-/* Translate a C fragment for the location expression, using *INPUT
-   as the starting location, begin from scratch if *INPUT is null.
-   If DW_OP_fbreg is used, it may have a subfragment computing from
-   the FB_ATTR location expression.
-
-   On errors, exit and never return (XXX ?).  On success, return the
-   first fragment created, which is also chained onto (*INPUT)->next.
-   *INPUT is then updated with the new tail of that chain.  */
-
-struct location *
-c_translate_location (struct obstack *pool,
-		      int indent, Dwarf_Addr dwbias,
-		      Dwarf_Attribute *loc_attr, Dwarf_Addr address,
-		      struct location **input, Dwarf_Attribute *fb_attr)
-{
-  Dwarf_Loc *expr;
-  size_t len;
-  switch (dwarf_addrloclists (loc_attr, address - dwbias, &expr, &len, 1))
-    {
-    case 1:			/* Should always happen.  */
-      if (len == 0)
-	goto inaccessible;
-      break;
-
-    default:			/* Shouldn't happen.  */
-    case -1:
-      error (2, 0, "dwarf_addrloclists (form %#x): %s",
-	     dwarf_whatform (fb_attr), dwarf_errmsg (-1));
-      return NULL;
-
-    case 0:			/* Shouldn't happen.  */
-    inaccessible:
-      error (2, 0, "not accessible at this address");
-      return NULL;
-    }
-
-  ++indent;
-  switch (*input == NULL ? loc_address : (*input)->type)
-    {
-    case loc_address:
-      /* We have a previous address computation.
-	 This expression will compute starting with that on the stack.  */
-      return location_from_address (pool, indent, dwbias, expr, len, address,
-				    input, fb_attr);
-
-    case loc_noncontiguous:
-    case loc_register:
-      /* The starting point is not an address computation, but a
-	 register.  We can only handle limited computations from here.  */
-      return location_relative (pool, indent, dwbias, expr, len, address,
-				input, fb_attr);
-
-    case loc_final:		/* Bogus caller.  */
-    default:
-      abort ();
-      break;
-    }
-
-  return NULL;
-}
-
-
-/* Emit "uintNN_t TARGET = ...;".  */
-static bool
-emit_base_fetch (struct obstack *pool, Dwarf_Word byte_size,
-		 const char *target, bool decl, struct location *loc)
-{
-  if (decl)
-    obstack_printf (pool, "uint%" PRIu64 "_t ", byte_size * 8);
-
-  switch (loc->type)
-    {
-    case loc_address:
-      if (byte_size != 0 && byte_size != (Dwarf_Word) -1)
-	obstack_printf (pool, "%s = deref (%" PRIu64 ", addr); ",
-			target, byte_size);
-      else
-	obstack_printf (pool, "%s = deref (sizeof %s, addr); ",
-			target, target);
-      return true;
-
-    case loc_register:
-      obstack_printf (pool, "%s = fetch_register (%u);", target, loc->regno);
-      break;
-
-    case loc_noncontiguous:
-      /* Could be handled if it ever happened.  */
-      error (2, 0, _("noncontiguous locations not supported"));
-      break;
-
-    default:
-      abort ();
-      break;
-    }
-
-  return false;
-}
-
-/* Translate a fragment to dereference the given pointer type,
-   where *INPUT is the location of the pointer with that type.
-
-   We chain on a loc_address program that yields this pointer value
-   (i.e. the location of what it points to).  */
-
-void
-c_translate_pointer (struct obstack *pool, int indent,
-		     Dwarf_Addr dwbias __attribute__ ((unused)),
-		     Dwarf_Die *typedie, struct location **input)
-{
-  obstack_printf (pool, "%*s{ ", (indent + 2) * 2, "");
-
-  bool deref = false;
-  Dwarf_Attribute attr_mem;
-  Dwarf_Word byte_size;
-  if (dwarf_attr_integrate (typedie, DW_AT_byte_size, &attr_mem) == NULL)
-    {
-      obstack_printf (pool, "uintptr_t ");
-      emit_base_fetch (pool, 0, "tmp", false, *input);
-    }
-  else if (dwarf_formudata (&attr_mem, &byte_size) != 0)
-    error (2, 0,
-	   _("cannot get byte_size attribute for type %s: %s"),
-	   dwarf_diename_integrate (typedie) ?: "<anonymous>",
-	   dwarf_errmsg (-1));
-  else
-    deref = emit_base_fetch (pool, byte_size, "tmp", true, *input);
-
-  obstack_printf (pool, " addr = tmp; }\n");
-
-  struct location *loc = new_synthetic_loc (pool, *input, deref);
-  (*input)->next = loc;
-  *input = loc;
-}
-
-/* Determine the byte size of a base type.  */
-static Dwarf_Word
-base_byte_size (Dwarf_Die *typedie)
-{
-  Dwarf_Attribute attr_mem;
-  Dwarf_Word size;
-  if (dwarf_attr_integrate (typedie, DW_AT_byte_size, &attr_mem) != NULL
-      && dwarf_formudata (&attr_mem, &size) == 0)
-    return size;
-
-  error (2, 0,
-	 _("cannot get byte_size attribute for type %s: %s"),
-	 dwarf_diename_integrate (typedie) ?: "<anonymous>",
-	 dwarf_errmsg (-1));
-  return -1;
-}
-
-/* Emit a code fragment like:
-	{ uintNN_t tmp = ...; S1 S2 S3, tmp, B0, Bn); }
-*/
-static void
-emit_bitfield (struct obstack *pool, int indent,
-	       Dwarf_Die *die, Dwarf_Word byte_size, struct location *loc,
-	       const char *s1, const char *s2, const char *s3)
-{
-  Dwarf_Word bit_offset, bit_size;
-  Dwarf_Attribute attr_mem;
-  if (dwarf_attr_integrate (die, DW_AT_bit_offset, &attr_mem) == NULL
-      || dwarf_formudata (&attr_mem, &bit_offset) != 0
-      || dwarf_attr_integrate (die, DW_AT_bit_size, &attr_mem) == NULL
-      || dwarf_formudata (&attr_mem, &bit_size) != 0)
-    error (2, 0, _("cannot get bit field parameters: %s"),
-	   dwarf_errmsg (-1));
-
-  /* Emit "{ uintNN_t tmp = ...;" to fetch the base type.  */
-
-  obstack_printf (pool, "%*s{ ", indent * 2, "");
-  emit_base_fetch (pool, byte_size, "tmp", true, loc);
-
-  obstack_printf (pool, "%s%s%s, tmp, %" PRIu64 ", %" PRIu64 "); }\n",
-		  s1, s2, s3, bit_offset, bit_size);
-}
-
-/* Translate a fragment to fetch the value of variable or member DIE
-   at the *INPUT location and store it in variable TARGET.  */
-
-void
-c_translate_fetch (struct obstack *pool, int indent,
-		   Dwarf_Addr dwbias __attribute__ ((unused)),
-		   Dwarf_Die *die, Dwarf_Attribute *typeattr,
-		   struct location **input, const char *target)
-{
-  ++indent;
-
-  Dwarf_Attribute size_attr;
-  Dwarf_Word byte_size;
-  if (dwarf_attr_integrate (die, DW_AT_byte_size, &size_attr) == NULL
-      || dwarf_formudata (&size_attr, &byte_size) != 0)
-    {
-      Dwarf_Die basedie;
-      if (dwarf_formref_die (typeattr, &basedie) == NULL)
-	error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
-      byte_size = base_byte_size (&basedie);
-    }
-
-  bool deref = false;
-  if (dwarf_hasattr_integrate (die, DW_AT_bit_offset))
-    /* This is a bit field.  */
-    emit_bitfield (pool, indent, die, byte_size, *input,
-		   "fetch_bitfield (", target, "");
-  else
-    switch (byte_size)
-      {
-      case 1:
-      case 2:
-      case 4:
-      case 8:
-	obstack_printf (pool, "%*s", indent * 2, "");
-	deref = emit_base_fetch (pool, byte_size, target, false, *input);
-	obstack_printf (pool, "\n");
-	break;
-
-      default:
-	/* Could handle this generating call to memcpy equivalent.  */
-	error (2, 0, _("fetch is larger than base integer types"));
-	break;
-      }
-
-  struct location *loc = new_synthetic_loc (pool, *input, deref);
-  loc->type = loc_final;
-  (*input)->next = loc;
-  *input = loc;
-}
-
-void
-c_translate_addressof (struct obstack *pool, int indent,
-		       Dwarf_Addr dwbias __attribute__ ((unused)),
-		       Dwarf_Die *die,
-		       Dwarf_Attribute *typeattr  __attribute__ ((unused)),
-		       struct location **input, const char *target)
-{
-  ++indent;
-
-  if (dwarf_hasattr_integrate (die, DW_AT_bit_offset))
-    error (2, 0, _("cannot take the address of a bit field"));
-
-  switch ((*input)->type)
-    {
-    case loc_address:
-      obstack_printf (pool, "%*s%s = addr;\n", indent * 2, "", target);
-      (*input)->next = new_synthetic_loc (pool, *input, false);
-      (*input)->next->type = loc_final;
-      break;
-
-    case loc_register:
-      error (2, 0, _("cannot take address of object in register"));
-      break;
-    case loc_noncontiguous:
-      error (2, 0, _("cannot take address of noncontiguous object"));
-      break;
-
-    default:
-      abort();
-      break;
-    }
-}
-
-
-/* Determine the element stride of an array type.  */
-static Dwarf_Word
-array_stride (Dwarf_Die *typedie)
-{
-  Dwarf_Attribute attr_mem;
-  if (dwarf_attr_integrate (typedie, DW_AT_stride_size, &attr_mem) != NULL)
-    {
-      Dwarf_Word stride;
-      if (dwarf_formudata (&attr_mem, &stride) == 0)
-	return stride;
-      error (2, 0, _("cannot get stride_size attribute array type %s: %s"),
-	     dwarf_diename_integrate (typedie) ?: "<anonymous>",
-	     dwarf_errmsg (-1));
-    }
-
-  Dwarf_Die die_mem;
-  if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL
-      || dwarf_formref_die (&attr_mem, &die_mem) == NULL)
-    error (2, 0, _("cannot get element type of array type %s: %s"),
-	   dwarf_diename_integrate (typedie) ?: "<anonymous>",
-	   dwarf_errmsg (-1));
-
-  if (dwarf_attr_integrate (&die_mem, DW_AT_byte_size, &attr_mem) != NULL)
-    {
-      Dwarf_Word stride;
-      if (dwarf_formudata (&attr_mem, &stride) == 0)
-	return stride;
-      error (2, 0,
-	     _("cannot get byte_size attribute for array element type %s: %s"),
-	     dwarf_diename_integrate (&die_mem) ?: "<anonymous>",
-	     dwarf_errmsg (-1));
-    }
-
-  error (2, 0, _("confused about array element size"));
-  return 0;
-}
-
-void
-c_translate_array (struct obstack *pool, int indent,
-		   Dwarf_Addr dwbias __attribute__ ((unused)),
-		   Dwarf_Die *typedie, struct location **input,
-		   const char *idx, Dwarf_Word const_idx)
-{
-  ++indent;
-
-  Dwarf_Word stride = array_stride (typedie);
-
-  struct location *loc = *input;
-  while (loc->type == loc_noncontiguous)
-    {
-      if (idx != NULL)
-	error (2, 0, _("cannot dynamically index noncontiguous array"));
-      else
-	{
-	  Dwarf_Word offset = const_idx * stride;
-	  struct location *piece = loc->pieces;
-	  while (piece != NULL && offset >= piece->byte_size)
-	    {
-	      offset -= piece->byte_size;
-	      piece = piece->next;
-	    }
-	  if (piece == NULL)
-	    error (2, 0, _("constant index is outside noncontiguous array"));
-	  if (offset % stride != 0)
-	    error (2, 0, _("noncontiguous array splits elements"));
-	  const_idx = offset / stride;
-	  loc = piece;
-	}
-    }
-
-  switch (loc->type)
-    {
-    case loc_address:
-      ++indent;
-      if (idx != NULL)
-	obstack_printf (pool, "%*saddr += %s * " UFORMAT ";\n",
-			indent * 2, "", idx, stride);
-      else
-	obstack_printf (pool, "%*saddr += " UFORMAT " * " UFORMAT ";\n",
-			indent * 2, "", const_idx, stride);
-      loc = new_synthetic_loc (pool, loc, false);
-      break;
-
-    case loc_register:
-      error (2, 0, _("cannot index array stored in a register"));
-      break;
-
-    default:
-      abort();
-      break;
-    }
-
-  (*input)->next = loc;
-  *input = (*input)->next;
-}
-
-
-/* Emitting C code for finalized fragments.  */
-
-
-#define emit(fmt, ...) fprintf (out, fmt, ## __VA_ARGS__)
-
-/* Open a block with a comment giving the original DWARF expression.  */
-static void
-emit_header (FILE *out, struct location *loc, unsigned int hindent)
-{
-  if (loc->ops == NULL)
-    emit ("%*s{ // synthesized\n", hindent * 2, "");
-  else
-    {
-      emit ("%*s{ // DWARF expression:", hindent * 2, "");
-      for (size_t i = 0; i < loc->nops; ++i)
-	{
-	  emit (" %#x", loc->ops[i].atom);
-	  if (loc->ops[i].number2 == 0)
-	    {
-	      if (loc->ops[i].number != 0)
-		emit ("(%" PRId64 ")", loc->ops[i].number);
-	    }
-	  else
-	    emit ("(%" PRId64 ",%" PRId64 ")",
-		  loc->ops[i].number, loc->ops[i].number2);
-	}
-      emit ("\n");
-    }
-}
-
-/* Emit a code fragment to assign the target variable to a register value.  */
-static void
-emit_loc_register (FILE *out, struct location *loc, unsigned int indent,
-		   const char *target)
-{
-  assert (loc->type == loc_register);
-
-  emit ("%*s%s = fetch_register (%u);\n",
-	indent * 2, "", target, loc->regno);
-}
-
-/* Emit a code fragment to assign the target variable to an address.  */
-static void
-emit_loc_address (FILE *out, struct location *loc, unsigned int indent,
-		  const char *target)
-{
-  assert (loc->type == loc_address);
-
-  if (loc->address.stack_depth == 0)
-    /* Synthetic program.  */
-    emit ("%s", loc->address.program);
-  else
-    {
-      emit ("%*s%s " STACKFMT, (indent + 1) * 2, "", STACK_TYPE, 0);
-      for (unsigned int i = 1; i < loc->address.stack_depth; ++i)
-	emit (", " STACKFMT, i);
-      emit (";\n");
-
-      emit ("%s%*s%s = " STACKFMT ";\n", loc->address.program,
-	    (indent + 1) * 2, "", target, 0);
-    }
-}
-
-/* Emit a code fragment to declare the target variable and
-   assign it to an address-sized value.  */
-static void
-emit_loc_value (FILE *out, struct location *loc, unsigned int indent,
-		const char *target, bool declare)
-{
-  if (declare)
-    emit ("%*s%s %s;\n", indent * 2, "", STACK_TYPE, target);
-
-  emit_header (out, loc, indent);
-
-  switch (loc->type)
-    {
-    default:
-      abort ();
-      break;
-
-    case loc_register:
-      emit_loc_register (out, loc, indent, target);
-      break;
-
-    case loc_address:
-      if (loc->address.frame_base != NULL)
-	emit_loc_value (out, loc->address.frame_base, indent,
-			"frame_base", true);
-      emit_loc_address (out, loc, indent, target);
-      break;
-    }
-
-  emit ("%*s}\n", indent * 2, "");
-}
-
-bool
-c_emit_location (FILE *out, struct location *loc, int indent)
-{
-  emit ("%*s{\n", indent * 2, "");
-
-  bool deref = false;
-  for (bool declare_addr = true; loc->next != NULL; loc = loc->next)
-    switch (loc->type)
-      {
-      case loc_address:
-	/* Emit the program fragment to calculate the address.  */
-	emit_loc_value (out, loc, indent + 1, "addr", declare_addr);
-	declare_addr = false;
-	deref = deref || loc->address.used_deref;
-	break;
-
-      case loc_register:
-      case loc_noncontiguous:
-	/* These don't produce any code directly.
-	   The next address/final record incorporates the value.  */
-	break;
-
-      case loc_final:		/* Should be last in chain!  */
-      default:
-	abort ();
-	break;
-      }
-
-  if (loc->type != loc_final)	/* Unfinished chain.  */
-    abort ();
-
-  emit ("%s%*s}\n", loc->address.program, indent * 2, "");
-
-  return deref;
-}
-
-#undef emit
diff --git a/libdwfl/loc2c.h b/libdwfl/loc2c.h
deleted file mode 100644
index 15d8928..0000000
--- a/libdwfl/loc2c.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <libdw.h>
-
-struct obstack;			/* Use <obstack.h> */
-struct location;		/* Opaque */
-
-
-/* Translate a C fragment for the location expression, using *INPUT
-   as the starting location, begin from scratch if *INPUT is null.
-   If DW_OP_fbreg is used, it may have a subfragment computing from
-   the FB_ATTR location expression.
-
-   On errors, exit and never return (XXX ?).  On success, return the
-   first fragment created, which is also chained onto (*INPUT)->next.
-   *INPUT is then updated with the new tail of that chain.
-   *USED_DEREF is set to true iff the "deref" runtime operation
-   was used, otherwise it is not modified.  */
-struct location *c_translate_location (struct obstack *, int indent,
-				       Dwarf_Addr bias,
-				       Dwarf_Attribute *loc_attr,
-				       Dwarf_Addr address,
-				       struct location **input,
-				       Dwarf_Attribute *fb_attr);
-
-/* Translate a fragment to dereference the given pointer type,
-   where *INPUT is the location of the pointer with that type.  */
-void c_translate_pointer (struct obstack *pool, int indent,
-			  Dwarf_Addr dwbias, Dwarf_Die *typedie,
-			  struct location **input);
-
-/* Translate a fragment to index an array (turning the location
-   of the array into the location of an element).  If IDX is non-null,
-   it's a string of C code to emit in the fragment as the array index.
-   If the index is a known constant, IDX should be null and CONST_IDX
-   is used instead (this case can handle local arrays in registers).  */
-void c_translate_array (struct obstack *pool, int indent,
-			Dwarf_Addr dwbias, Dwarf_Die *typedie,
-			struct location **input,
-			const char *idx, Dwarf_Word const_idx);
-
-/* Translate a fragment to compute the address of the input location
-   and assign it to the variable TARGET.  This doesn't really do anything
-   (it always emits "TARGET = addr;"), but it will barf if the location
-   is a register or noncontiguous object.  */
-void c_translate_addressof (struct obstack *pool, int indent,
-			    Dwarf_Addr dwbias, Dwarf_Die *die,
-			    Dwarf_Attribute *typeattr,
-			    struct location **input, const char *target);
-
-/* Translate a fragment to fetch the value of variable or member DIE
-   at the *INPUT location and store it in variable TARGET.
-   This handles base integer types and bit fields.  */
-void c_translate_fetch (struct obstack *pool, int indent,
-			Dwarf_Addr dwbias __attribute__ ((unused)),
-			Dwarf_Die *die, Dwarf_Attribute *typeattr,
-			struct location **input, const char *target);
-
-/* Emit the C fragment built up at LOC (i.e., the return value from the
-   first c_translate_location call made).  INDENT should match that
-   passed to c_translate_* previously.
-
-   Writes complete lines of C99, code forming a complete C block, to STREAM.
-   Return value is true iff that code uses the `deref' runtime macros.  */
-bool c_emit_location (FILE *stream, struct location *loc, int indent);
diff --git a/libdwfl/test2.c b/libdwfl/test2.c
deleted file mode 100644
index 4c1e7ad..0000000
--- a/libdwfl/test2.c
+++ /dev/null
@@ -1,268 +0,0 @@
-#include <config.h>
-#include <assert.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <stdlib.h>
-#include <string.h>
-#include <error.h>
-#include <locale.h>
-#include <argp.h>
-#include <libdwfl.h>
-#include <dwarf.h>
-#include "../libdw/libdwP.h"
-#include <obstack.h>
-
-#include "loc2c.h"
-
-static const char *
-dwarf_diename_integrate (Dwarf_Die *die)
-{
-  Dwarf_Attribute attr_mem;
-  return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
-}
-
-
-
-static void
-handle_variable (Dwarf_Die *scopes, int nscopes, int out,
-		 Dwarf_Addr cubias, Dwarf_Die *vardie, Dwarf_Addr pc,
-		 char **fields)
-{
-#define obstack_chunk_alloc malloc
-#define obstack_chunk_free free
-  struct obstack pool;
-  obstack_init (&pool);
-
-   /* Figure out the appropriate frame base for accessing this variable.
-     XXX not handling nested functions
-     XXX inlines botched
-  */
-  Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
-  for (int inner = 0; inner < nscopes; ++inner)
-    {
-      switch (dwarf_tag (&scopes[inner]))
-	{
-	default:
-	  continue;
-	case DW_TAG_subprogram:
-	case DW_TAG_entry_point:
-	case DW_TAG_inlined_subroutine:	/* XXX */
-	  if (inner >= out)
-	    fb_attr = dwarf_attr_integrate (&scopes[inner],
-					    DW_AT_frame_base,
-					    &fb_attr_mem);
-	  break;
-	}
-      break;
-    }
-
-  Dwarf_Attribute attr_mem;
-
-  if (dwarf_attr_integrate (vardie, DW_AT_location, &attr_mem) == NULL)
-    error (2, 0, _("cannot get location of variable: %s"),
-	   dwarf_errmsg (-1));
-
-#define FIELD "addr"
-#define emit(fmt, ...) printf ("  addr = " fmt "\n", ## __VA_ARGS__)
-
-  struct location *head, *tail = NULL;
-  head = c_translate_location (&pool, 1, cubias, &attr_mem, pc,
-			       &tail, fb_attr);
-
-  if (dwarf_attr_integrate (vardie, DW_AT_type, &attr_mem) == NULL)
-    error (2, 0, _("cannot get type of variable: %s"),
-	   dwarf_errmsg (-1));
-
-  Dwarf_Die die_mem, *die = vardie;
-  while (*fields != NULL)
-    {
-      die = dwarf_formref_die (&attr_mem, &die_mem);
-
-      const int typetag = dwarf_tag (die);
-      switch (typetag)
-	{
-	case DW_TAG_typedef:
-	  /* Just iterate on the referent type.  */
-	  break;
-
-	case DW_TAG_pointer_type:
-	  if (**fields == '+')
-	    goto subscript;
-	  /* A "" field means explicit pointer dereference and we consume it.
-	     Otherwise the next field implicitly gets the dereference.  */
-	  if (**fields == '\0')
-	    ++fields;
-	  c_translate_pointer (&pool, 1, cubias, die, &tail);
-	  break;
-
-	case DW_TAG_array_type:
-	  if (**fields == '+')
-	    {
-	    subscript:;
-	      char *endp = *fields + 1;
-	      uintmax_t idx = strtoumax (*fields + 1, &endp, 0);
-	      if (endp == NULL || endp == *fields || *endp != '\0')
-		c_translate_array (&pool, 1, cubias, die, &tail,
-				   *fields + 1, 0);
-	      else
-		c_translate_array (&pool, 1, cubias, die, &tail,
-				   NULL, idx);
-	      ++fields;
-	    }
-	  else
-	    error (2, 0, _("bad field for array type: %s"), *fields);
-	  break;
-
-	case DW_TAG_structure_type:
-	case DW_TAG_union_type:
-	  switch (dwarf_child (die, &die_mem))
-	    {
-	    case 1:		/* No children.  */
-	      error (2, 0, _("empty struct %s"),
-		     dwarf_diename_integrate (die) ?: "<anonymous>");
-	      break;
-	    case -1:		/* Error.  */
-	    default:		/* Shouldn't happen */
-	      error (2, 0, _("%s %s: %s"),
-		     typetag == DW_TAG_union_type ? "union" : "struct",
-		     dwarf_diename_integrate (die) ?: "<anonymous>",
-		     dwarf_errmsg (-1));
-	      break;
-
-	    case 0:
-	      break;
-	    }
-	  while (dwarf_tag (die) != DW_TAG_member
-		 || ({ const char *member = dwarf_diename_integrate (die);
-		       member == NULL || strcmp (member, *fields); }))
-	    if (dwarf_siblingof (die, &die_mem) != 0)
-	      error (2, 0, _("field name %s not found"), *fields);
-
-	  if (dwarf_attr_integrate (die, DW_AT_data_member_location,
-				    &attr_mem) == NULL)
-	    {
-	      /* Union members don't usually have a location,
-		 but just use the containing union's location.  */
-	      if (typetag != DW_TAG_union_type)
-		error (2, 0, _("no location for field %s: %s"),
-		       *fields, dwarf_errmsg (-1));
-	    }
-	  else
-	    c_translate_location (&pool, 1, cubias, &attr_mem, pc,
-				  &tail, NULL);
-	  ++fields;
-	  break;
-
-	case DW_TAG_base_type:
-	  error (2, 0, _("field %s vs base type %s"),
-		 *fields, dwarf_diename_integrate (die) ?: "<anonymous type>");
-	  break;
-
-	case -1:
-	  error (2, 0, _("cannot find type: %s"), dwarf_errmsg (-1));
-	  break;
-
-	default:
-	  error (2, 0, _("%s: unexpected type tag %#x"),
-		 dwarf_diename_integrate (die) ?: "<anonymous type>",
-		 dwarf_tag (die));
-	  break;
-	}
-
-      /* Now iterate on the type in DIE's attribute.  */
-      if (dwarf_attr_integrate (die, DW_AT_type, &attr_mem) == NULL)
-	error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
-    }
-
-  c_translate_fetch (&pool, 1, cubias, die, &attr_mem, &tail, "value");
-
-  printf ("#define PROBEADDR %#" PRIx64 "ULL\n", pc);
-  puts ("static void print_value(struct pt_regs *regs)\n"
-	"{\n"
-	"  intptr_t value;");
-
-  bool deref = c_emit_location (stdout, head, 1);
-
-  puts ("  printk (\" ---> %ld\\n\", (unsigned long) value);\n"
-	"  return;");
-
-  if (deref)
-    puts ("\n"
-	  " deref_fault:\n"
-	  "  printk (\" => BAD FETCH\\n\");");
-
-  puts ("}");
-}
-
-int
-main (int argc, char **argv)
-{
-  /* We use no threads here which can interfere with handling a stream.  */
-  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
-
-  /* Set locale.  */
-  (void) setlocale (LC_ALL, "");
-
-  Dwfl *dwfl = NULL;
-  int argi;
-  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &argi, &dwfl);
-  assert (dwfl != NULL);
-
-  if (argi == argc)
-    error (2, 0, "need address argument");
-
-  char *endp;
-  uintmax_t pc = strtoumax (argv[argi], &endp, 0);
-  if (endp == argv[argi])
-    error (2, 0, "bad address argument");
-
-  Dwarf_Addr cubias;
-  Dwarf_Die *cudie = dwfl_addrdie (dwfl, pc, &cubias);
-  if (cudie == NULL)
-    error (EXIT_FAILURE, 0, "dwfl_addrdie: %s", dwfl_errmsg (-1));
-
-  Dwarf_Die *scopes;
-  int n = dwarf_getscopes (cudie, pc - cubias, &scopes);
-  if (n < 0)
-    error (EXIT_FAILURE, 0, "dwarf_getscopes: %s", dwarf_errmsg (-1));
-  else if (n == 0)
-    error (EXIT_FAILURE, 0, "%#" PRIx64 ": not in any scope\n", pc);
-
-  if (++argi == argc)
-    error (2, 0, "need variable arguments");
-
-  char *spec = argv[argi++];
-
-  int lineno = 0, colno = 0, shadow = 0;
-  char *at = strchr (spec, '@');
-  if (at != NULL)
-    {
-      *at++ = '\0';
-      if (sscanf (at, "%*[^:]:%i:%i", &lineno, &colno) < 1)
-	lineno = 0;
-    }
-  else
-    {
-      int len;
-      if (sscanf (spec, "%*[^+]%n+%i", &len, &shadow) == 2)
-	spec[len] = '\0';
-    }
-
-  Dwarf_Die vardie;
-  int out = dwarf_getscopevar (scopes, n, spec, shadow, at, lineno, colno,
-			       &vardie);
-  if (out == -2)
-    error (0, 0, "no match for %s (+%d, %s:%d:%d)",
-	   spec, shadow, at, lineno, colno);
-  else if (out < 0)
-    error (0, 0, "dwarf_getscopevar: %s (+%d, %s:%d:%d): %s",
-	   spec, shadow, at, lineno, colno, dwarf_errmsg (-1));
-  else
-    handle_variable (scopes, n, out, cubias, &vardie, pc, &argv[argi]);
-
-  dwfl_end (dwfl);
-
-  return 0;
-}