o = 0;
if(r->sym)
o += symaddr(r->sym);
- o += r->add - (s->value + r->off + r->siz);
+ // NOTE: The (int32) cast on the next line works around a bug in Plan 9's 8c
+ // compiler. The expression s->value + r->off + r->siz is int32 + int32 +
+ // uchar, and Plan 9 8c incorrectly treats the expression as type uint32
+ // instead of int32, causing incorrect values when sign extended for adding
+ // to o. The bug only occurs on Plan 9, because this C program is compiled by
+ // the standard host compiler (gcc on most other systems).
+ o += r->add - (s->value + r->off + (int32)r->siz);
break;
case D_SIZE:
o = r->sym->size + r->add;