Help tracking down "HardwareSerial" gcc 4.5.x/mega

20 posts / 0 new
Last post
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Aw; someone else found the same problem about 2 weeks ago...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, if you're going to post a patch to GCC, please use the -u switch when generating the patch. It makes it easier to read. ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got a private email along the lines of "great, this is fixed now, right?" Lest anyone else be similarly confused:

NO, this is still an open problem.

It's now gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45263 (which as of today, is still "unassigned" and "unconfirmed"; it has two "amateur" patches but no official attention.)

There is currently NO version of gcc that correctly supports (c++ only?) programs larger than 80k. Older versions cannot access the class initializer table at all if it its beyond the 64k limit, and newer versions access it "wrong" under some (common) circumstances...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And the other bad news:

I don't think I believe that the fix implemented for 29141 actually fixes all cases of the bug, even not counting that it has bad code in the piece it does implement. The fix for 29141 allows the table of constructors created by the compiler to be at a location beyond the first 64k, but the constructor function addresses IN that table seem to still be only 16 bits long. It looks like the linker only produces a 16bit table, and then the code that walks through the table hardwires a zero into the upper 8 bits for the called constructor as well. This is beyond me; since I'm not even aware of how gcc handles "far" addresses on big AVRs. (You might be able to work around this by making sure the .o files containing constructors occur in the first 64k of flash.)

The good news is that I think it ought to be possible to "fix" older versions of the compiler by using linker switches (or a linker script) to make sure that the table of constructor addresses (the .ctors and .dtors segments from .o files) is put into flash at the beginning of the flash .text segment instead of at the end. This would theoretically allow an updated Arduino IDE or Makefile to work around the bug without needing a patched compiler. (OTOH, linker scripts seem even more like Black Magic than AVR Assembler. I can't figure out how to actually do this, or even if it's really possible. And link wizards out there?)

As explanation, the pseudocode looks like this:

code_t * constructor_table[] = {serial_constructor_func, ethernet_constructor_func, ...};
init() {
   :
  function_ptr_t *entry = &constructor_table[0];
  while (entry < END_OF(constructor_table)) {
     function_ptr func = *entry;
     envokeFunction(func);
     entry += sizeof(code_t *);
  }
  :
}

So, 29141 fixed things so that function_ptr_t is now 24 bits, and fixed "envokeFunction()" to handle a 24bit pointer, but it 1) used a register that the constructors could trash, and 2) did NOT increase the size of "code_t *"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just duplicated this entire process and got to the same point. Anyone taken a further look at this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The fix for 29141 allows the table of constructors created by the compiler to be at a location beyond the first 64k, but the constructor function addresses IN that table seem to still be only 16 bits long.

I can't tell whether this is a bug or not. there are "hints" that all call destinations >64k are handled by a "trampoline" area in the low 64k, in which case things could be OK.

But I can't find any summary of just how >64k AVRs are supposed to be supported :-(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a hint: Most of the GCC developers for the AVR port don't come to AVR Freaks on a regular basis. If you are going to be involved in working on AVR GCC, then I suggest that you subscribe to the avr-gcc-list mailing list and/or the avr-libc-dev mailing list for the avr-libc project. All of the AVR GCC developers are subscribed to those mailing lists and you're likely to get better feedback than posting a thread here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually the bug with clobbering R20 when calling __tablejump_elpm__ from __do_global_ctors has now been fixed in the GNU mainline v4.6.1. (BUG # 45263, New Revision: 174427, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45263) My question is, since Atmel is still shipping 4.5.1, how do I get this fix into my libgcc.a? And where do I get it? Or do I have to assemble it myself?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Or do I have to assemble it myself?

Yes.

 

Pages