[comp.os.minix] bcc, goto and address out of bound

root@petruz.sublink.ORG (root) (03/21/91)

I got some pieces of code with many , really many , goto's ... it seems
that bcc gets lost with them , It produces a good assembler output but
"as" tells me that there is an address out of bound :-(
 
I used also -j option for As , all works fine ... 'till crash !
 
 ... what can I do ? ( please don't tell me to clean goto's ... I can't ! )
 
        HELP me ... please 

 
-- 
   Pietro Caselli                      | 
   internet: zaphod@petruz.sublink.org |      IF YOU MEET THE BUDDHA 
   Fidonet : 2:332/401.10              |       ON THE ROAD,KILL HIM. 
   Mail    : V. Pietro Mattiolo, 4     |
             40139 Bologna ITALY       | 

-- 
   Pietro Caselli                      | 
   internet: zaphod@petruz.sublink.org |      IF YOU MEET THE BUDDHA 
   Fidonet : 2:332/401.10              |       ON THE ROAD,KILL HIM. 
   Mail    : V. Pietro Mattiolo, 4     |
             40139 Bologna ITALY       | 

paradis@acestes.UUCP (Jim Paradis) (03/29/91)

In article <159@petruz.sublink.ORG> root@petruz.sublink.ORG (root) writes:

>I got some pieces of code with many , really many , goto's ... it seems
>that bcc gets lost with them , It produces a good assembler output but
>"as" tells me that there is an address out of bound :-(
> 
>I used also -j option for As , all works fine ... 'till crash !
> 
> ... what can I do ? ( please don't tell me to clean goto's ... I can't ! )

Ah yes... turns out this is a bug in Bruce's compiler 8-(  You see, there 
are two flavors of conditional jump instructions on the 386; byte displacement 
and longword displacement.  The byte displacement opcodes are of the form 7x, 
where x codes for the condition you're branching on.  The longword displacement
instructions use two-byte opcodes: 0f 8x.  Thing is, the "x" is the same
in both cases, so you can see how it would be really easy to implement
the "-j" flag in the compiler; take the original jump instruction, add
0x10, and paste "0f" in front.

The bug is that this does NOT work for the UNconditional relative jump
instruction, but the assembler tries this trick anyway.  The unconditional
relative jump byte displacement opcode is "eb"; apply the above trick
to it and you get 0f fb.  This is an illegal instruction, and your program
crashes.

How to get around this?  The easiest way would be to switch compilers
until Bruce can come up with a bug fix.  Next easiest would be to port
mdb (so you can look at the core dump) and a binary editor (so you can
fix the problem).  Where the core dump says the illegal instruction
occurred, see if you have the offending "0f fb" sequence there.  If 
you do, then replace it with "90 e9".  The 90 is a nop, and the e9
is the correct opcode for a longword-relative jump.  Since jumps are
relative to the start of the instruction FOLLOWING the jump, you don't
have to play games with the jump offset.

Or you could just get rid of the goto's 8-) 8-) 8-)  [sorry, couldn't
resist!]

Have fun!

-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"

evans@syd.dit.CSIRO.AU (Bruce.Evans) (04/03/91)

In article <168@acestes.UUCP> paradis@acestes.UUCP (Jim Paradis) writes:
>In article <159@petruz.sublink.ORG> root@petruz.sublink.ORG (root) writes:
>
>>I got some pieces of code with many , really many , goto's ... it seems
>>that bcc gets lost with them , It produces a good assembler output but
>>"as" tells me that there is an address out of bound :-(
>> 
>>I used also -j option for As , all works fine ... 'till crash !
>> 
>> ... what can I do ? ( please don't tell me to clean goto's ... I can't ! )
>
>Ah yes... turns out this is a bug in Bruce's compiler 8-(  You see, there 
>...
>The bug is that this does NOT work for the UNconditional relative jump
>instruction, but the assembler tries this trick anyway.  The unconditional
>relative jump byte displacement opcode is "eb"; apply the above trick
>to it and you get 0f fb.  This is an illegal instruction, and your program
>crashes.

The "address out of bounds" bug is in the compiler. It gets the lengths of
instructions slightly wrong. I have fixed at least one wrong length.

The other bug is really in the assembler. "loop" instructions also have the
bug. 32-bit offsets are not even legal for loops.

The bug has not caused much trouble because no compilers generate "loop"
and the -j flag is used mostly by my port of gcc, which outputs "jmp"
instead of "j". The bug does not affect "jmp" (or the old equivalent
"br"). I have not fixed it, but for other reasons I recently changed the
meaning of "jmp" to "jmp short" and made bcc output "jmp" instructions, so
the buggy "j" case is not exposed.

Instead of the -j flag, the -w flag (i.e. cc -C-w) might help. It causes
all jumps to be output as long in the first place. Unfortunately it also
forces an assembly error if the first bug occurred. It's relatively easy
to get around this by editing the assembler file.
-- 
Bruce Evans		evans@syd.dit.csiro.au