gas - MIPS/ELF/DWARF probs

Gary Funck gary@Intrepid.COM
Tue Feb 14 14:31:00 GMT 1995


Our company is working with the NYU GNAT team; we hope to develop
DWARF-based debugging support for Ada programs compiled by gnat
(GNU Ada Translator) and then debugged by gdb.  Paul Hilfinger
of Berkeley ( is working on making
gdb Ada-aware.  We've been lurking on the gas2 list for a while now;
this is our first posting to this group.  We hope the following
message is "on topic", and look forward to your comments/help.


We are targetting SGI's IRIX 5.x operating system, and have configured
gcc-2.6.2 to generate DWARF, and to use the GNU assembler
(binutils-2.5.2).  Although, IRIX 5.x tools still use the "MIPS
Debug" format (a derivative of the Third Eye dbx-like debugging
format), their debugger knows how to debug either MDEBUG or DWARF.
We eventually plan to target IRIX 6.x, which uses DWARF info.
directly.  Thus, IRIX 5.x seemed a reasonable starting point for

We've run into (what we think are) a few gas bugs/problems. Please
find them dsscribed below.  As you'll see, the problems came up
when we tried to build objc (Objective C) using the boostrapped xgcc.
We built Objective C by mistake, however, we believe that the
same gas problems will come up whether/not we're building objc.

The problems are described below:

When copiling objc/hash.c

We end up with the following code:

	.4byte	0x4
	.align	2
	.globl	hash_delete

The align directive gets an assertion failure in the procedure,
mips_align in config/tc-mips.c:

/* Align the current frag to a given power of two.  The MIPS assembler
   also automatically adjusts any preceding label.  */

static void
mips_align (to, fill, label)
     int to;
     int fill;
     symbolS *label;
  mips_emit_delays ();
  frag_align (to, fill);
  record_alignment (now_seg, to);
  /* obj-elf.c doesn't communicate with these routines, yet it
   * overrides ".previous", ".2byte",  etc.  They should clear,
   * but do not know how to clear, insn_label, which is passed
   * in as "label" to this routine.  For now, we remove the
   * ability to align the previous label.
  if (label != NULL)
      assert (S_GET_SEGMENT (label) == now_seg);
      label->sy_frag = frag_now;
      S_SET_VALUE (label, (valueT) frag_now_fix ());

The check for (label != NULL) above passes, and the assertion that
follows fails.  The 'label' formal parameter is in fact the current
instruction's label:

/* Symbol labelling the current insn.  */
static symbolS *insn_label;

Normally, this insn_label variable is reset to NULL by assembler
statements which generate code/data.  By "normally", we mean that
tc-mips.c does the right thing.  However, the file config/obj-elf.c
"overrides" tc-mips.c's handling of operations such as ".previous",

  {"comm", obj_elf_common, 0},
  {"ident", obj_elf_ident, 0},
  {"local", obj_elf_local, 0},
  {"previous", obj_elf_previous, 0},
  {"section", obj_elf_section, 0},
  {"size", obj_elf_size, 0},
  {"type", obj_elf_type, 0},
  {"version", obj_elf_version, 0},
  {"weak", obj_elf_weak, 0},

/* These are used for stabs-in-elf configurations.  */
  {"line", obj_elf_line, 0},

  /* These are used for dwarf. */
  {"2byte", cons, 2},
  {"4byte", cons, 4},
  {"8byte", cons, 8},

  /* We need to trap the section changing calls to handle .previous.  */
  {"data", obj_elf_data, 0},
  {"text", obj_elf_text, 0},

One thing that obj-elf.c does _not_ do, however is to reset tc-mips.c's
idea of the current instruction label.  So when the .align opcode
comes along, it is not overridden, and it in turn checks for
the insn_label, which now has a different section, than the section
resulting from popping to the previous section via the ".previous" opcode.

For now, we just removed the check in mips_align(), which forces
alignment on the prior label.  It seems there is also the question
as to whether ".previous" must remember the previous label or not
as well as the question of how obj-elf.c should communicate with

The second problem has to do with the fact that the DWARF code
generation may generate code along the following lines (line
3256 in objc/Object.s):

        .section        .debug
        .4byte  .L_D193_e-.L_D193
        .2byte  0x14
        .2byte  0x12
        .4byte  .L_D198
        .2byte  0x38
        .asciiz "_i_Object__free"
        .2byte  0x83
        .2byte  .L_t193_e-.L_t193

That last ".2byte" pseudo-op has a foward reference to L_t193_e, and
this is apparently handled as a "fixup" in gas.  The relocation value
is given as "BFD_RELOC_16" ... even though this value will in fact
be absolute and not relocatable (it is the difference of two reloacatable

The procedure "md_apply_fix" in config/mips/tc-mips.c is supposed to
handle fixups, however, it does not have an entry in its case
statement for items with BFD_RELOC_16, so the default case alternative
is executed, and this triggers an internal error.

Earlier in the handling of this ".2byte" directive, we ran
into the following assertion, at the very beginning of
mips_apply_fix() which fails:

  assert (fixP->fx_size == 4);

To work around these problems, we made following patches to tc-mips.c:

*** targ-cpu.c.orig	Sun Feb 12 20:51:25 1995
--- targ-cpu.c	Sun Feb 12 21:29:50 1995
*************** md_apply_fix (fixP, valueP)
*** 5312 ****
--- 5313,5319 ----
+ #if 0
+   /*
+    * DWARF support may define something like:
+    *   .2byte L1-L2
+    * which is handled as a fix up.  The check below incorrectly bounces
+    * that construct.
+    */
*************** md_apply_fix (fixP, valueP)
*** 5313 ****
--- 5321 ----
+ #endif
*************** md_apply_fix (fixP, valueP)
*** 5336 ****
--- 5345,5353 ----
+ #if 1
+     case BFD_RELOC_16:
+       /* nothing to do - but better not be relocatable.
+        * Sixteen bit fixups are generated by the DWARF support.
+        */
+       assert(!fixP->fx_pcrel);
+       break;
+ #endif
*************** mips_align (to, fill, label)
*** 5585 ****
--- 5603,5609 ----
+ #if 0
+   /* obj-elf.c doesn't communicate with these routines, yet it
+    * overrides ".previous", ".2byte",  etc.  They should clear,
+    * but do not know how to clear, insn_label, which is passed
+    * in as "label" to this routine.  For now, we remove the
+    * ability to align the previous label.
+    */
*************** mips_align (to, fill, label)
*** 5591 ****
--- 5616 ----
+ #endif

We view the patches above are really just temporary workarounds.

Has anyone seen and/or fixed these problems?

|  Gary Funck
|  Intrepid Technology Inc., Mountain View CA (415) 964-8135

More information about the Gas2 mailing list