This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
broken code in iosys.c
- From: "King, Steven R" <steven dot r dot king at intel dot com>
- To: "ecos-discuss at ecos dot sourceware dot org" <ecos-discuss at ecos dot sourceware dot org>
- Date: Tue, 5 Apr 2011 17:36:02 -0700
- Subject: [ECOS] broken code in iosys.c
Hello,
The cyg_io_init call in packages/common/io/v3_0/src/iosys.c depends on undefined compiler behavior and break in practice. There are problems start here:
void
cyg_io_init(void)
{
static int _init = false;
cyg_devtab_entry_t *t;
if (_init) return;
for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) {
The trouble is in the "t != &__DEVTAB_END__" check.
First problem:
The compiler is certainly allowed to assume that two different identifiers cannot have the same address. C guarantees this. So, the output binary does not need to check the t != condition on first entry into the loop. In other words, the loop can *always* iterate at least once, despite the intent of the "t!=" check. We found this the hard way by entering the loop with an empty table and faulting on a null.
Second problem:
Writing code that depends on relative location of two different identifiers in the data segment is dodgy. This code specifically assumes that 't' will roll off the array and immediately point to __DEVTAB_END__. Some serious linker sorcery to guarantee that, and this approach requires that the table have at least one entry, which is not always going to happen.
I hope this is useful.
Regards,
-steve
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss