circle icon indicating copy to clipboard operation
circle copied to clipboard

Using Circle fails to link (and often crashes compiling) with `-m32`

Open johnsonjh opened this issue 1 year ago • 2 comments

On a Fedora 38 system, I'm unable to link for 32-bit (-m32) using Circle as the compiler driver:

$ circle -m32 x.cc
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libstdc++.a when searching for -lstdc++
/usr/bin/ld: cannot find -lstdc++: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib64//libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib64//libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libgcc_s.so when searching for -lgcc_s
/usr/bin/ld: cannot find -lgcc_s: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libgcc_s.so when searching for -lgcc_s
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/13/libgcc_eh.a when searching for -lgcc_eh
/usr/bin/ld: cannot find -lgcc_eh: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib64//libc.so when searching for -lc
/usr/bin/ld: skipping incompatible /usr/lib64//libc.a when searching for -lc
error: linker failed with exit code 1

The following might be useful to debug this:

  • Linker invocation via G++ (working):

    /usr/libexec/gcc/x86_64-redhat-linux/13/collect2 -fno-lto --build-id --no-add-needed
    --eh-frame-hdr --hash-style=gnu -m elf_i386 -dynamic-linker /lib/ld-linux.so.2
    /usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib/crt1.o
    /usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib/crti.o
    /usr/lib/gcc/x86_64-redhat-linux/13/32/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/13/32
    -L/usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib -L/lib/../lib -L/usr/lib/../lib
    -L/usr/lib/gcc/x86_64-redhat-linux/13
    -L/usr/lib/gcc/x86_64-redhat-linux/13/../../.. /tmp/ccYhoDb4.o -lstdc++ -lm -lgcc_s -lgcc
    -lc -lgcc_s -lgcc  /usr/lib/gcc/x86_64-redhat-linux/13/32/crtend.o 
    /usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib/crtn.o
    
  • Linker invocation via Clang++ (working):

    "/usr/bin/ld" --hash-style=gnu --build-id --eh-frame-hdr -m elf_i386 -dynamic-linker
    /lib/ld-linux.so.2 -o a.out /lib/crt1.o /lib/crti.o
    /usr/bin/../lib/gcc/x86_64-redhat-linux/13/32/crtbegin.o
    -L/usr/bin/../lib/gcc/x86_64-redhat-linux/13/32 -L/lib -L/usr/lib /tmp/x-24ca10.o -lstdc++
    -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
    /usr/bin/../lib/gcc/x86_64-redhat-linux/13/32/crtend.o /lib/crtn.o
    
  • Linker invocation via Circle (not working):

    /usr/bin/ld --build-id --eh-frame-hdr -m elf_i386 -dynamic-linker /lib64/ld-linux-x86-64.so.2
    -o x /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/13/crtbegin.o
    -L/usr/local/lib64/ -L/usr/local/lib/ -L/usr/lib64/ -L/usr/lib/
    -L/usr/lib/gcc/x86_64-redhat-linux/13 /tmp/circle-tmp-dir-cbI8oc/x.o -lstdc++ -lm
    --start-group -lgcc_s -lgcc -lgcc_eh -lc --end-group
    /usr/lib/gcc/x86_64-redhat-linux/13/crtend.o /usr/lib64/crtn.o
    

Linking is possible with an object build with circle -m32 using the linker directly, or using g++ (or clang++0 to invoke the linker:

$ circle -m32 -o x.o x.cc
$ file x.o
x.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ g++ -m32 -o a.out x.o
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked,
       interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, not stripped
$

johnsonjh avatar Sep 13 '23 20:09 johnsonjh

Also, for some other non-trivial code, I can't even compile with -m32 (and I'm unable to try with LLVM/libc++; see #188):

circle -MMD -std=c++20 -Wall -Wextra  -Iinclude -fPIC -O3 -DNDEBUG -D_FORTIFY_SOURCE=2 -m32 -DSIR_NO_STD_FORMAT=1 -Iinclude -c -o build/obj/tests/tests++.o tests/tests++.cc
error: /usr/include/c++/13/compare:558:54
... included from /usr/include/c++/13/bits/stl_pair.h:65:11
... included from /usr/include/c++/13/bits/stl_algobase.h:64:10
... included from /usr/include/c++/13/algorithm:60:10
... included from include/sir.hh:34:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
sizes of destination and source types in bitcast must match
  destination type is unsigned long with size 8
  source type is const volatile void* with size 4
      auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt); 
                                                     ^

declaration: /usr/include/c++/13/bits/ranges_cmp.h:129:12
during parsing of __x initializer
      auto __x = reinterpret_cast<__UINTPTR_TYPE__>( 
           ^
  error: /usr/include/c++/13/bits/ranges_cmp.h:130:9
  ... included from /usr/include/c++/13/bits/iterator_concepts.h:38:10
  ... included from /usr/include/c++/13/bits/stl_iterator_base_types.h:71:11
  ... included from /usr/include/c++/13/bits/stl_algobase.h:65:10
  ... included from /usr/include/c++/13/algorithm:60:10
  ... included from include/sir.hh:34:11
  ... included from tests/tests++.hh:29:11
  ... included from tests/tests++.cc:26:10
  sizes of destination and source types in bitcast must match
    destination type is unsigned long with size 8
    source type is const volatile void* with size 4
          static_cast<const volatile void*>(std::forward<_Tp>(__t))); 
          ^

error: /usr/include/c++/13/bits/align.h:66:53
... included from /usr/include/c++/13/memory:74:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
sizes of destination and source types in bitcast must match
  destination type is unsigned long with size 8
  source type is void* with size 4
  typedef uintptr_t = unsigned long declared at /usr/include/stdint.h:90:27
  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr); 
                                                    ^

error: /usr/include/c++/13/bits/align.h:67:27
... included from /usr/include/c++/13/memory:74:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
object __intptr has placeholder type
  const auto __aligned = (__intptr - 1u + __align) & -__align; 
                          ^

error: /usr/include/c++/13/bits/align.h:68:23
... included from /usr/include/c++/13/memory:74:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
object __aligned has placeholder type
  const auto __diff = __aligned - __intptr; 
                      ^

error: /usr/include/c++/13/bits/align.h:69:7
... included from /usr/include/c++/13/memory:74:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
object __diff has placeholder type
  if (__diff > (__space - __size)) 
      ^

error: /usr/include/c++/13/system_error:168:38
... included from /usr/include/c++/13/bits/ios_base.h:46:11
... included from /usr/include/c++/13/ios:44:10
... included from /usr/include/c++/13/ostream:40:10
... included from /usr/include/c++/13/bits/unique_ptr.h:42:12
... included from /usr/include/c++/13/memory:78:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
cannot convert void to std::strong_ordering
  std::strong_ordering declared at /usr/include/c++/13/compare:256:3
    { return std::compare_three_way()(this, &__rhs); } 
                                     ^

error: /usr/include/c++/13/bits/locale_facets.tcc:1210:40
... included from /usr/include/c++/13/bits/locale_facets.h:2687:11
... included from /usr/include/c++/13/bits/basic_ios.h:37:10
... included from /usr/include/c++/13/ios:46:10
... included from /usr/include/c++/13/ostream:40:10
... included from /usr/include/c++/13/bits/unique_ptr.h:42:12
... included from /usr/include/c++/13/memory:78:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
sizes of destination and source types in bitcast must match
  destination type is unsigned long with size 8
  source type is const void* with size 4
  typedef _UIntPtrType = unsigned long declared at /usr/include/c++/13/bits/locale_facets.tcc:1207:46
        reinterpret_cast<_UIntPtrType>(__v)); 
                                       ^

error: /usr/include/c++/13/bits/atomic_wait.h:255:27
... included from /usr/include/c++/13/bits/atomic_base.h:42:10
... included from /usr/include/c++/13/bits/shared_ptr_atomic.h:33:10
... included from /usr/include/c++/13/memory:81:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
sizes of destination and source types in bitcast must match
  destination type is unsigned long with size 8
  source type is const void* with size 4
  typedef uintptr_t = unsigned long declared at /usr/include/stdint.h:90:27
  auto __key = (uintptr_t(__addr) >> 2) % __ct; 
                          ^

error: /usr/include/c++/13/bits/atomic_wait.h:256:14
... included from /usr/include/c++/13/bits/atomic_base.h:42:10
... included from /usr/include/c++/13/bits/shared_ptr_atomic.h:33:10
... included from /usr/include/c++/13/memory:81:12
... included from include/sir.hh:36:11
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
object __key has placeholder type
  return __w[__key]; 
             ^

error: /usr/include/boost/smart_ptr/detail/spinlock_pool.hpp:47:58
... included from /usr/include/boost/smart_ptr/shared_ptr.hpp:29:10
... included from /usr/include/boost/shared_ptr.hpp:17:10
... included from /usr/include/boost/format/alt_sstream.hpp:22:10
... included from /usr/include/boost/format/internals.hpp:24:10
... included from /usr/include/boost/format.hpp:38:10
... included from include/sir.hh:46:12
... included from tests/tests++.hh:29:11
... included from tests/tests++.cc:26:10
sizes of destination and source types in bitcast must match
  destination type is unsigned long with size 8
  source type is const void* with size 4
  typedef std::size_t = unsigned long declared at /usr/include/c++/13/x86_64-redhat-linux/bits/c++config.h:2593:27
        std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; 
                                                         ^

error: translation aborted; too many errors

johnsonjh avatar Sep 13 '23 20:09 johnsonjh

... and if I avoid Boost but keep -m32 Circle crashes compiling:

Segmentation fault (core dumped)

Here's the backtrace:

#0  0x0000000000442537 in slab::allocator_t::alloc(unsigned long) ()
#1  0x00000000006d4e56 in ip::object_store_t::alloc_decl(sema::decl_object_t*, sema::context_t&, bool) ()
#2  0x00000000006dc005 in ip::interpret_t::create_object(sema::decl_object_t*, sema::arg_expr_t*) ()
#3  0x00000000006dd968 in ip::inject_object(sema::decl_object_t*, sema::context_t&) ()
#4  0x0000000000533906 in sema::stmt_builder_t::object_init(sema::decl_object_t*, std::unique_ptr<sema::arg_t, std::default_delete<sema::arg_t> >, source_loc_t, bool) ()
#5  0x0000000000533c9f in sema::stmt_builder_t::decl_init(sema::decl_t*, std::unique_ptr<sema::arg_t, std::default_delete<sema::arg_t> >, source_loc_t) ()
#6  0x0000000000852113 in fe::decl_builder_t::declare_objectlike(fe::decl_builder_t::parse_t&, fe::range_t&, bool&) ()
#7  0x000000000084e628 in fe::decl_builder_t::process_declaration(fe::decl_builder_t::parse_t&, fe::range_t&, bool) ()
#8  0x000000000084cbdc in fe::decl_builder_t::regular_declarations(fe::range_t, bool) ()
#9  0x00000000008480ca in fe::decl_builder_t::parse(fe::range_t, bool) ()
#10 0x000000000085b3cc in fe::grammar_t::simple_declaration(fe::range_t, bool, llvm::SmallVector<std::unique_ptr<sema::template_header_t, std::default_delete<sema::template_header_t> >, 1u>*) ()
#11 0x000000000085bd6a in fe::grammar_t::declaration_statement(fe::range_t, bool, llvm::SmallVector<std::unique_ptr<sema::template_header_t, std::default_delete<sema::template_header_t> >, 1u>*) ()
#12 0x0000000000837cd5 in fe::grammar_t::generic_statement(fe::range_t, meta_prefix_t) ()
#13 0x00000000008379aa in fe::grammar_t::statement(fe::syntax_stmt_t*) ()
#14 0x000000000083770d in fe::grammar_t::statements(llvm::SmallVector<std::unique_ptr<fe::syntax_stmt_t, std::default_delete<fe::syntax_stmt_t> >, 2u>&) ()
#15 0x0000000000844b32 in fe::grammar_t::namespace_definition(fe::syntax_ns_t*) ()
#16 0x00000000008386a7 in fe::grammar_t::resolved_statement(fe::syntax_stmt_t*) ()
#17 0x00000000008379da in fe::grammar_t::statement(fe::syntax_stmt_t*) ()
#18 0x000000000083770d in fe::grammar_t::statements(llvm::SmallVector<std::unique_ptr<fe::syntax_stmt_t, std::default_delete<fe::syntax_stmt_t> >, 2u>&) ()
#19 0x0000000000844b32 in fe::grammar_t::namespace_definition(fe::syntax_ns_t*) ()
#20 0x00000000008386a7 in fe::grammar_t::resolved_statement(fe::syntax_stmt_t*) ()
#21 0x00000000008379da in fe::grammar_t::statement(fe::syntax_stmt_t*) ()
#22 0x000000000083770d in fe::grammar_t::statements(llvm::SmallVector<std::unique_ptr<fe::syntax_stmt_t, std::default_delete<fe::syntax_stmt_t> >, 2u>&) ()
#23 0x0000000000844b32 in fe::grammar_t::namespace_definition(fe::syntax_ns_t*) ()
#24 0x00000000008386a7 in fe::grammar_t::resolved_statement(fe::syntax_stmt_t*) ()
#25 0x0000000000837a38 in fe::grammar_t::statement(fe::syntax_stmt_t*) ()
#26 0x000000000083770d in fe::grammar_t::statements(llvm::SmallVector<std::unique_ptr<fe::syntax_stmt_t, std::default_delete<fe::syntax_stmt_t> >, 2u>&) ()
#27 0x0000000000844b32 in fe::grammar_t::namespace_definition(fe::syntax_ns_t*) ()
#28 0x00000000008386a7 in fe::grammar_t::resolved_statement(fe::syntax_stmt_t*) ()
#29 0x0000000000837a38 in fe::grammar_t::statement(fe::syntax_stmt_t*) ()
#30 0x000000000083770d in fe::grammar_t::statements(llvm::SmallVector<std::unique_ptr<fe::syntax_stmt_t, std::default_delete<fe::syntax_stmt_t> >, 2u>&) ()
#31 0x00000000004473e1 in main ()

This all works with 64-bit.

johnsonjh avatar Sep 13 '23 20:09 johnsonjh