This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Problem in expand_builtin_dwarf_reg_size()


A make bootstrap of egcs snapshot 19990307 for pc532-netbsd:

   GNU C version egcs-2.93.11 19990307 (gcc2 ss-980929 experimental) (pc532-netbsd) compiled by GNU C version egcs-2.90.27 980315 (egcs-1.0.2 release)

fails with:

   in ../../egcs-19990307/gcc/dwarf2out.c:657: Internal compiler error in function expand_builtin_dwarf_reg_size
Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.

Looking at expand_builtin_dwarf_reg_size it appears to make
unwarranted assumptions.

The failure is on the test:

	  int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
	  int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end);
	  ...
	  if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg)
	    abort ();

DWARF_FRAME_REGNUM defaults to DBX_REGISTER_NUMBER and this particular
test assumes that first gcc internal register number in a range has
the lowest DBX register number and similarly for the highest register
in the range.  This is unwarranted.

Ranges are constructed by noticing if the size of reg_raw_mode
changes. But on this machine, the reg_raw_mode sizes are all the
same. Should they be? This architecture has some fp registers which
are used in pairs for double precision, but it also has registers
which are double precision only. For consistency these are also
considered as pairs of single precision registers, but the odd
numbered registers are never valid. I believe this scheme is also used
for mips.

I experimented with starting a new range such that a continous range
in internal register number space always maps contiguously to the
DWARF_FRAME_REGNUM space. This is achieved by starting a new range if
a non continuity is noticed:

ie change

      if (size != last_size)

to 

      if (size != last_size
	  || (i > 0 && DWARF_FRAME_REGNUM(i) - DWARF_FRAME_REGNUM(i -1) != 1))

The compiler then aborts at

	  if (end >= last_end)
	    abort ();

which seems to be a test to make sure each range starts above the end
of the previous range. Whilst overlapping ranges shouldn't happen, there
is no reason ranges in DWARF_FRAME_REGNUM space should be ordered.
I guess the ranges could be sorted on the .beg field before they
are used.

DBX_REGISTER_NUMBER can be pretty weird. Typically it is based on the
order registers are stored by the kernel when it saves context.  But
it can be any order agreed by the compiler and the debuggers. It may
include registers such as floating point status registers which gcc
knows nothing about. The order doesn't really matter so long as dbx
(or gdb) and gcc agree.

For this machine, every range ends up with a size of 4 and if that is
correct (it doesn't *seem* right for the double precision registers)
the correct behaviour could  be achieved more simply by having a
special case for a single range. This would not solve the general
case however.

I don't understand this DWARF stuff. The os config file for this
machine (ns32k/netbsd.h) has

/* Until they use ELF or something that handles dwarf2 unwinds
   and initialization stuff better.  */
#define DWARF2_UNWIND_INFO 0

We basically use DBX for debugging. I'm not sure why we would want
DWARF2_UNWIND_INFO defined but not defined to be 1. Does it give extra
info for debugging exceptions?

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]