bebbo / binutils-gdb

Unofficial mirror of sourceware binutils-gdb repository. Updated daily.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git
GNU General Public License v2.0
3 stars 3 forks source link

bsr out of range not reported by assembler or linker #10

Closed skeetor closed 4 years ago

skeetor commented 4 years ago

I have a repo at https://github.com/skeetor/amiga-utils. In the file https://github.com/skeetor/amiga-utils/blob/master/utilslib/AmigaUtils/src/SystemTakeover.s there is the line "jsr WaitRaster". Oriignaly this was a "bsr WaitRaster". I when I compile and link that the symbol "WaitRaster" is accepted without any error, but when I run the binary, it crashes, because the "bsr" instruction points to some invalid address. It looks as if the function "WaitRaster" which is in a separate module, may be out of range, but in this case I would expect an error from the linker. Replacing that with "jsr" instead, fixes the problem.

A discussion can be found here: http://eab.abime.net/showthread.php?p=1366266#post1366266

bebbo commented 4 years ago

Your recipe is not fully correct.

First a chmod u+x tools/* is needed (you could store these flags in git)

Then I used:

git clone https://github.com/skeetor/amiga-utils
cd amiga-utils
export PATH=$PWD/tools:$PATH
. amiga-env
cd utilslib
cmake . -B build-release
...

that's where I'm stuck now:

Determining if the C compiler works failed with the following output:
Change Dir: /home/stefan/amiga-gcc/tickets/agc143/amiga-utils/utilslib/build-release/CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/make" "cmTC_7710f/fast"
/usr/bin/make -f CMakeFiles/cmTC_7710f.dir/build.make CMakeFiles/cmTC_7710f.dir/build
make[1]: Entering directory '/home/stefan/amiga-gcc/tickets/agc143/amiga-utils/utilslib/build-release/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_7710f.dir/testCCompiler.c.o
/opt/amiga/bin/m68k-amigaos-gcc   -g    -o CMakeFiles/cmTC_7710f.dir/testCCompiler.c.o   -c /home/stefan/amiga-gcc/tickets/agc143/amiga-utils/utilslib/build-release/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_7710f
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7710f.dir/link.txt --verbose=1
/opt/amiga/bin/m68k-amigaos-gcc -g     -rdynamic CMakeFiles/cmTC_7710f.dir/testCCompiler.c.o  -o cmTC_7710f 
m68k-amigaos-gcc: error: unrecognized command line option '-rdynamic'
make[1]: *** [CMakeFiles/cmTC_7710f.dir/build.make:87: cmTC_7710f] Error 1
make[1]: Leaving directory '/home/stefan/amiga-gcc/tickets/agc143/amiga-utils/utilslib/build-release/CMakeFiles/CMakeTmp'
make: *** [Makefile:121: cmTC_7710f/fast] Error 2

=> fix your cmake stuff.

bebbo commented 4 years ago

But coming back to your issue:

I guess that the assembler you are using generates code for the 68020 which allows relativ calls (32 bit offset) aka bsr which is a bsr.l in that case.

Such code won't run on 68000 since it's an invalid instruction (or some funky bsr.w with a bogus offset).

skeetor commented 4 years ago

Thanks for the feedback. I look into this issue with 68020 code generation. Strange that the cmake stuff doesn't work, I will take a look at it, as it should work. Works on my system exactly as described (but isn't that always the case? :D).

BTW: Which OS are you using? So far I only used it with MSYS so I have to check if there is a difference if you use Linux.

skeetor commented 4 years ago

Regarding, the possibility of creating 68020 code, this shouldn't be the case, because in that source file is a "movec" instruction which only exists on 68010+. So at least the assembling is limited to 68000 only, as I got an error about that, and had to fix it. So could it be, that the linker thinks it targets 68020 code and I need an additional option to limit the linker as well? How would I do that?

bebbo commented 4 years ago

BTW: Which OS are you using? So far I only used it with MSYS so I have to check if there is a difference if you use Linux.

I am using WSL (windows subsystem for linux) running ubuntu plus VcXSrv so I can open xterm and other gui apps (e.g. Eclipse) from Windows. It's way faster than msys/cygwin. With both way mapped drives (/mnt/c -> C: /mnt/d -> D: and U: -> ubuntu's /) it's working good here.

bebbo commented 4 years ago

Regarding, the possibility of creating 68020 code, this shouldn't be the case, because in that source file is a "movec" instruction which only exists on 68010+. So at least the assembling is limited to 68000 only, as I got an error about that, and had to fix it. So could it be, that the linker thinks it targets 68020 code and I need an additional option to limit the linker as well? How would I do that?

It's maybe a real linker issue - but without reproducing all is guessing - futile guessing...

skeetor commented 4 years ago

I updated my repo, so building should now work. I tested it under Debian 8. Also created screenshots from the binary with "bsr" (left) and "jsr" (right). BSR_Bug-vs-JSR

When I build the VasmOnly project, this works, but in this case, vlink is used as the linker, and it seems to do it correct, as this project works with bsr as well.

bebbo commented 4 years ago

I can build it now - now I need an example to create an executable. No?

skeetor commented 4 years ago

In utilslib is the SystemTakeover.s where the jsr WaitRaster is. If you change that to bsr instead, then build and install it. After that you can build any of the sample projects like Vasm*. If you build VasmOnly then vlink is used where the bsr instruction is correct. if you build VasmGcc or VasmGccLib then it will be wrong as it uses the gcc linker.

bebbo commented 4 years ago

Ok, I'm getting closer:

code should (EDIT: MUST) be in section .text and data in section .data and bss in section .bss

skeetor commented 4 years ago

Do you mean that the segments are not properly set up? Can this cause this issue?

bebbo commented 4 years ago

and please use

#include <proto/exec.h>

instead of

#include <inline/exec.h>
bebbo commented 4 years ago

and if you don't use exceptions/rtti but utilize g++ always add -fno-exceptions -fno-rtti.

skeetor commented 4 years ago

I added a "section .text" statement but this makes no difference. I tried to put the WaitRaster in a different "section code" and only then I get the expected error: bin/VASMGcc.exe: code reloc for WaitRaster is out of range: 00000000

When they are both in .text, then it doesn't make a difference. No error but wrong address. I also tried to put the data into ".data" but then I also get relocation errors. I probably could fix them by not using relative addressing modes. Would this mean that this program can cause problems on other OSes (like 3.X) if they have MMU and 68020+, if the data is not in a writable segment?

The updated code is in branch "develop".

bebbo commented 4 years ago

for vasm it's:

    section .text,code
    section .data,data

(and guess it was section .data,bss)

bebbo commented 4 years ago

Would this mean that this program can cause problems on other OSes (like 3.X) if they have MMU and 68020+, if the data is not in a writable segment?

wild guess: you can still write into the code segement - but I consider it bad style, writing into the code segment. And if you plan to create resident programs for the Amiga, it's a no go.

skeetor commented 4 years ago

Updated, but no difference. :)

skeetor commented 4 years ago

wild guess: you can still write into the code segement - but I consider it bad style, writing into the code segment. And if you plan to create resident programs for the Amiga, it's a no go.

Yes, you are right. I will change that, but that's not related to this issue.

bebbo commented 4 years ago

here the bsr is working - but the program dies in clockToTimeStr

bebbo commented 4 years ago

here the bsr is working - but the program dies in clockToTimeStr

LOL, ok - that's the call to WaitRaster ...

skeetor commented 4 years ago

I updated the segments now according to your suggestions. :)

skeetor commented 4 years ago

I guess the address the bsr will point to, might be a bit "random" as it probably depends on where the overflow will point to (assuming that it uses a wrong instruction which might overflow on 68000).

bebbo commented 4 years ago

it's not random - plus it's a vasm issue. I'll post to your thread.

skeetor commented 4 years ago

Thanks for your analysis! Not sure how I shall proceed. I can keep in mind that I shouldn't use bsr for external symbols, or I could start using AS instead. I guess I will also post this on vasm project and see what they make of it.

bebbo commented 4 years ago

strlen should be:

strlen:
    move.l  a0,d0

.loop
    tst.b   (a0)+
    bne     .loop

    sub.l   a0,d0
    not.l   d0
    rts
bebbo commented 4 years ago

please test

skeetor commented 4 years ago

What do I need to update for this? Recomplie my amigaos suite?

bebbo commented 4 years ago
make update -j
make binutils -j6

should be sufficient, since there should be no code using pcrel jumps to other object files. (no warrants)

skeetor commented 4 years ago

Looks good now! :D I get a relocation error now when I try to use "bsr.s" and when I just use "bsr" it's pointing now to the correct address.

Cool! Thanks!