This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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