freemint / m68k-atari-mint-binutils-gdb

Fork of sourceware's binutils-gdb with support for the m68k-atari-mint target.
https://github.com/freemint/m68k-atari-mint-binutils-gdb/wiki
GNU General Public License v2.0
11 stars 4 forks source link

binutils 2.42 unable to compile itself for m68k #12

Closed mikrosk closed 6 months ago

mikrosk commented 6 months ago

Similarly to https://github.com/freemint/m68k-atari-mint-gcc/issues/41 I have discovered that I'm unable to build native mintelf binutils. It fails on:

/bin/sh ./libtool  --tag=CC   --mode=link m68k-atari-mintelf-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Wwrite-strings -I../../downloads/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf/gas/../zlib  -O2 -fomit-frame-pointer       -o as-new app.o as.o atof-generic.o codeview.o compress-debug.o cond.o depend.o dwarf2dbg.o dw2gencfi.o ecoff.o ehopt.o expr.o flonum-copy.o flonum-konst.o flonum-mult.o frags.o gen-sframe.o ginsn.o hash.o input-file.o input-scrub.o listing.o literal.o macro.o messages.o output-file.o read.o remap.o sb.o scfidw2gen.o scfi.o sframe-opt.o stabs.o subsegs.o symbols.o write.o config/tc-m68k.o config/obj-elf.o config/atof-ieee.o config/m68k-parse.o ../opcodes/libopcodes.la ../bfd/libbfd.la ../libiberty/libiberty.a   -L./../zlib -lz  
libtool: link: m68k-atari-mintelf-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Wwrite-strings -I../../downloads/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf/gas/../zlib -O2 -fomit-frame-pointer -o as-new app.o as.o atof-generic.o codeview.o compress-debug.o cond.o depend.o dwarf2dbg.o dw2gencfi.o ecoff.o ehopt.o expr.o flonum-copy.o flonum-konst.o flonum-mult.o frags.o gen-sframe.o ginsn.o hash.o input-file.o input-scrub.o listing.o literal.o macro.o messages.o output-file.o read.o remap.o sb.o scfidw2gen.o scfi.o sframe-opt.o stabs.o subsegs.o symbols.o write.o config/tc-m68k.o config/obj-elf.o config/atof-ieee.o config/m68k-parse.o  ../opcodes/.libs/libopcodes.a ../bfd/.libs/libbfd.a -L/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari/zlib /home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari/libsframe/.libs/libsframe.a ../libiberty/libiberty.a -lz
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o): in function `bfd_get_error':
bfd.c:(.text+0x54): undefined reference to `__m68k_read_tp'
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o): in function `_bfd_clear_error_data':
bfd.c:(.text+0x68): undefined reference to `__m68k_read_tp'
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o): in function `bfd_asprintf':
bfd.c:(.text+0x8e): undefined reference to `__m68k_read_tp'
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o): in function `bfd_errmsg':
bfd.c:(.text+0x12a): undefined reference to `__m68k_read_tp'
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o): in function `bfd_perror':
bfd.c:(.text+0x19a): undefined reference to `__m68k_read_tp'
/home/mikro/gnu-tools/m68000/lib/gcc/m68k-atari-mintelf/13.2.0/../../../../m68k-atari-mintelf/bin/ld: ../bfd/.libs/libbfd.a(bfd.o):bfd.c:(.text+0x1d6): more undefined references to `__m68k_read_tp' follow
collect2: error: ld returned 1 exit status
make[6]: *** [Makefile:1313: as-new] Error 1
make[6]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari/gas'
make[5]: *** [Makefile:1695: all-recursive] Error 1
make[5]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari/gas'
make[4]: *** [Makefile:1032: all] Error 2
make[4]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari/gas'
make[3]: *** [Makefile:5514: all-gas] Error 2
make[3]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari'
make[2]: *** [Makefile:1031: all] Error 2
make[2]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-binutils-gdb-binutils-2_42-mintelf-m68000-atari'
make[1]: *** [Makefile:331: binutils-2.42-m68000-atari.ok] Error 2
make[1]: Leaving directory '/home/mikro/atari/compilers/m68k-atari-mint-build'

So it fails on compiling as. ./configure flags are nothing special: --target=m68k-atari-mintelf --host=m68k-atari-mintelf --disable-nls --prefix=/usr --disable-gdb --disable-libdecnumber --disable-readline --disable-sim so perhaps nobody has tried it yet?

Changelog.git contains an interesting entry:

2023-05-26  Alan Modra  <amodra@gmail.com>

    PR22263 ld test
    A number of targets that I test regularly fail the "Build pr22263-1"
    test for various reasons.

    arm-linux-gnueabi: "undefined reference to `__aeabi_read_tp'"
    ia64-linux-gnu: "Explicit stops are ignored in auto mode"
    m68k-linux-gnu: "undefined reference to `__m68k_read_tp'"       <------------- hmm...
    microblaze-linux-gnu: "undefined reference to `__tls_get_addr'"
    nios2-linux-gnu, s390-linux-gnu and sh4-linux-gnu have a tprel reloc in .got
    riscv64-linux-gnu has a dynamic relocation in text

    So only riscv really fails the pr.  The rest fail due to test issues
    or lack of a linker optimisation.  Lack of an optimisation isn't
    really a fail, but it's worth keeping the test to ensure those
    optimisations don't regress.  The xfail targets may not be an
    exhaustive list.  This just tidies test results for those for which I
    have cross compilers installed.

        PR 22263
        * testsuite/ld-elf/tls.exp: Split pr22263 test into two parts,
        one to check for -z text errors, the other to check tprel
        linker optimisation.  Supply needed symbols and assembler flags.
        xfail the linker optimisation on targets known to fail.
mikrosk commented 6 months ago

Interestingly the same error is printed when (cross-)compiling libstd++v3 for all flavours (m68000, m68020-60, m5475):

onfigure:54029: checking whether the target supports thread-local storage
configure:54043: /home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-gcc-gcc-13-mintelf-m68000-cross-final/./gcc/xgcc -B/home/mikro/atari/compilers/m68k-atari-mint-build/m68k-atari-mint-gcc-gcc-13-mintelf-m68000-cross-final/./gcc/ -B/home/mikro/gnu-tools/m68000/m68k-atari-mintelf/bin/ -B/home/mikro/gnu-tools/m68000/m68k-atari-mintelf/lib/ -isystem /home/mikro/gnu-tools/m68000/m68k-atari-mintelf/include -isystem /home/mikro/gnu-tools/m68000/m68k-atari-mintelf/sys-include    -o conftest -O2 -fomit-frame-pointer   conftest.c  >&5
/home/mikro/gnu-tools/m68000/m68k-atari-mintelf/bin/ld: /tmp/ccvEoxXY.o: in function `main':
conftest.c:(.text.startup+0xa): undefined reference to `__m68k_read_tp'
vinriviere commented 6 months ago

FYI, in my initial mintelf work I focused on the new PRG/ELF file format produced with a cross-compiler. Compiling newer binutils for the MiNT host is a completely new challenge - never tried by me.

mikrosk commented 6 months ago

@vinriviere can you perhaps check whether you see the error in libstd++v3's config.log? (that happened during cross-compilation)

th-otto commented 6 months ago

I've already built binutils 2.42 for m68k (see http://tho-otto.de/crossmint.php#binutils) so i think that is an issue with your cross-compiler.

That m68k_read_tp issue sounds familiar to me. That has something to do with variables being declared as __thread local. I've also fixed that in gcc: https://github.com/th-otto/m68k-atari-mint-gcc/commit/9ce1d8d4b98f4686515ffc2e7db5b948a783e377

Edit: you can check that with something like this:

__thread int a; int b; int main() { return a = b; }

It should emit library calls to emutls_get_address, not m68k_read_tp. That is suboptimal when you really don't have threads, but works, because emutls_get_address is part of libgcc.a

mikrosk commented 6 months ago

I've also fixed that in gcc: https://github.com/th-otto/m68k-atari-mint-gcc/commit/9ce1d8d4b98f4686515ffc2e7db5b948a783e377

I think that's the crucial difference here. ;) Since the libstdc++v3 test also fails on some thread-local storage stuff, I'd say this is it. I'll test tonight.

mikrosk commented 6 months ago

That indeed fixed both libstdc++-v3 and native binutils build. Thanks!

vinriviere commented 6 months ago

Edit: you can check that with something like this:

__thread int a; int b; int main() { return a = b; }

I also do have the issue.

Interestingly the same error is printed when (cross-)compiling libstd++v3 for all flavours (m68000, m68020-60, m5475):

Any idea why I don't have trouble when compiling libstd++v3? This can be seen in the gcc build log I've already posted.

checking whether the target supports thread-local storage... no

mikrosk commented 6 months ago

But that's the outcome of the problem. ;) If you checked config.log, you'd see the error. Fixed libstdc++-v3 says "yes" there.

vinriviere commented 6 months ago

Ah! But our MiNT kernel (or even TOS) doesn't support real thread-local storage. So I would say that "no" is more accurate, isn't it?

th-otto commented 6 months ago

The problem is that libstdc++v3 then does not declare the thread_local keyword, and that causes other packages fail to compile (gdb amongst others IIRC)

mikrosk commented 6 months ago

I'm wondering whether --disable-threads and/or --disable-tls do not affect this behaviour? I'm compiling with the former but maybe the latter would remove the need for Thorsten's patch?

th-otto commented 6 months ago

--disable-tls might work too, haven't checked that. OTOH, the patch just adds 3 lines...

Edit, no that would be different. It would not compile emutls support into libgcc, and then give the same problem: using thread would result into a call to m68k_read_tp, and the c++ thread_local keyword won't be defined.

mikrosk commented 6 months ago

--disable-tls might work too, haven't checked that. OTOH, the patch just adds 3 lines...

And it indeed works. It's not about number of lines but about what's the most proper approach: now our target, as the sole one, required tricking the assembler into an empty operation. Using the right switch makes the toolchain not assuming the presence of __m68k_read_tp and avoiding the problem altogether.

Plus if someone in the future comes and implements some sort of threading model into atari/mint, it will be much easier to spot one switch in ./configure than a buried commit tricking the assembler to ignore it.

Edit, no that would be different. It would not compile emutls support into libgcc, and then give the same problem: using thread would result into a call to m68k_read_tp, and the c++ thread_local keyword won't be defined.

It seems you didn't tried it, I did. And your example works, no compiler/linker errors. libstdc++-v3 returns OK, native binutils compiles, too.

So I'm resetting our branch to Vincent's which included the 13.3 merge and your new mint-atomic.c, i.e. basically what I would do, too.

@vinriviere you may want to add --disable-threads --disable-tls to your scripts.

th-otto commented 6 months ago

It's not about number of lines but about what's the most proper approach:

Its your opinion that this is "more proper". In my opinion, it should be the source that should make sure the code produces the correct results, just like is done there in autoconf for a lot of other targets. And my approach works even if someone does not add --disable-tls in the script, like vincent.