russellallen / self

Making the world safe for objects
http://selflanguage.org
707 stars 76 forks source link

Fix first send desc has wrong lookup type #115

Closed leeduhem closed 7 years ago

leeduhem commented 7 years ago

When compiled with g++ 6.3.1, the generated Self could not start successfully, I got the following error:

first_sendDesc() has wrong lookup type

After the above error, it looks like fatal_handler is in a infinite loop, will call itself until the stack is overflowed eventually. Therefore the first commit tries to stop fatal_handler enters that infinite loop.

The reason that the first_sendDesc got a wrong lookup type is that for the following i386 assembler language code:

.global label jmp label

g++ 6.3.1 generated a 2-byte jmp instruction, instead of a 5-byte instruction, as required by the definition of lookupType_offset in vm/src/i386/lookup/sendDesc_i386.hh. So the second commit adds three nop instructions to pad.

russellallen commented 7 years ago

Just tried and this is the same for gcc++ 5.4. Thanks for the diagnostic! That's really helpful. We should aim for a fix that works for earlier gcc and also cmake I think?

leeduhem commented 7 years ago

We should aim for a fix that works for earlier gcc and also cmake I think?

By "cmake", did you mean clang?

I tested the changes with clang++ 3.8.1, also works. I also planned to test them with earlier g++ and clang++, but I have some problems to set up a working 32-bit Ubuntu docker image.

Admittedly, it's a little ugly and unreliable to pad jmp instruction with nop like this. I have tried to search a more elegant and reliable solution such as the old one, but cannot find any.

russellallen commented 7 years ago

Sorry, yes I did mean clang. If you pull the latest from the 'dev' branch, the 'release/buildLinuxVM.sh' script has a 32 bit Ubuntu 14:04 image docker image link if that helps?

leeduhem commented 7 years ago

If you pull the latest from the 'dev' branch, the 'release/buildLinuxVM.sh' script has a 32 bit Ubuntu 14:04 image docker image link if that helps?

Actually, yes. Now I managed to set up a working 32-bit Ubuntu 14.04 docker container.

I have tested the changes with gcc 4.8.4 and clang 3.4, works in both cases. I guess that's because they are using the same assembler: GNU as 2.24.

russellallen commented 7 years ago

Turns out Tobias was the one who introduced the .globals solution: https://blog.selflanguage.org/2012/07/02/assembler-woes/

Based on his writeup and your work, the nop-nop-nop-nop solution would seem workable, if a bit ugly as you say :)

Otherwise, Eric Grant made a comment suggesting a macro:

clang:
.macro jmp32
.byte   0xe9
.long   $0 – (.+4)
.endmacro

Linux/gcc:
.macro jmp32 label
.byte   0xe9
.long   \label – (.+4)
.endm

Use in your code on any platform:
jmp32   contNLR
krono commented 7 years ago

This sounds cumbersome but reasonable. Maybe we can re-activate the clang integrated assembler again after that (see bottom of referred blog post).

This could obsolete

leeduhem commented 7 years ago

Turns out Tobias was the one who introduced the .globals solution: https://blog.selflanguage.org/2012/07/02/assembler-woes/

Interesting article to read, thank you.

Eric Grant made a comment suggesting a macro:

This macro looks better than the padding nops.

russellallen commented 7 years ago

I've merged into new branch to work on this.