Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: linking with avr-gcc failed #149

Open
jonahbron opened this issue Jul 14, 2019 · 36 comments
Open

Error: linking with avr-gcc failed #149

jonahbron opened this issue Jul 14, 2019 · 36 comments

Comments

@jonahbron
Copy link

@jonahbron jonahbron commented Jul 14, 2019

I'm working on a program that uses @Rahix's avr-hal and the w5500 driver crate. However when compiling, I get this error:

$ export RUST_TARGET_PATH="/home/jonah/Projects/smart-plug/"
$ export RUSTUP_TOOLCHAIN=avr-toolchain
$ export XARGO_RUST_SRC="/home/jonah/Projects/rust/src"
$ xargo build --target avr-atmega328p --release
error: linking with `avr-gcc` failed: exit code: 1
  |
  = note: "avr-gcc" "-Os" "-mmcu=atmega328p" "-L" "/home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib" "/home/jonah/Projects/smart-plug/target/avr-atmega328p/release/deps/smart_plug-c760f2efbebaee9b.smart_plug.17dox426-cgu.0.rcgu.o" "-o" "/home/jonah/Projects/smart-plug/target/avr-atmega328p/release/deps/smart_plug-c760f2efbebaee9b.elf" "-Wl,--gc-sections" "-L" "/home/jonah/Projects/smart-plug/target/avr-atmega328p/release/deps" "-L" "/home/jonah/Projects/smart-plug/target/release/deps" "-L" "/home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib" "-Wl,--start-group" "-Wl,--end-group" "-Wl,-Bstatic" "/home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib" "-Wl,-Bdynamic" "-Wl,--gc-sections"
  = note: /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_24':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x35c): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_26':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x37c): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_51':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x7ee): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_65':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x924): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_89':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xbde): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_101':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xcfc): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB4_103':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xd22): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB12_17':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x2df6): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB12_23':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x2e52): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x2e64): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB18_17':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x5e84): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB18_23':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x5ee0): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x5ef4): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB24_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x89c2): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB24_12':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x89dc): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB25_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x8aa6): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB26_8':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x8bfc): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB30_8':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x9210): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB30_10':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x921a): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB31_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x92da): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB32_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x940e): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB36_76':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xa2f0): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB36_78':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xa352): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB39_46':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc024): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc044): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc056): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc070): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB39_75':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc526): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB39_78':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xc5a6): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB48_3':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xdebc): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB62_53':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0xfd98): undefined reference to `__divmodti4'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB64_49':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1091e): undefined reference to `__divmodti4'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB74_6':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11b7a): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11b8c): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11ba2): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB74_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11bb4): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB75_6':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11c50): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11c60): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11c76): undefined reference to `__ashrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB75_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11c88): undefined reference to `__ashrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB76_6':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11d5e): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11d6e): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11d84): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB76_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x11d96): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB83_21':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x12dc2): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x12dd6): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB84_21':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x134a4): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x134c2): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB85_24':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x13bda): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x13bf6): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB90_93':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x15668): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `_$LT$i32$u20$as$u20$compiler_builtins..int..Int$GT$::wrapping_shl::h538766759685e63f':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x18eba): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB148_9':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1aa00): undefined reference to `__divmodti4'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB149_9':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1ac50): undefined reference to `__divmodti4'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `_$LT$u32$u20$as$u20$compiler_builtins..int..WideInt$GT$::wide_shift_left::h2260981b3eb5ef04':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b7fa): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b814): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b83a): undefined reference to `__ashlsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB169_3':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b8e0): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b8f8): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b914): undefined reference to `__ashlsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b942): undefined reference to `__lshrsi3'
          /home/jonah/.xargo/lib/rustlib/avr-atmega328p/lib/libcompiler_builtins-9a1ff32ee7e2d645.rlib(compiler_builtins-9a1ff32ee7e2d645.compiler_builtins.d7w6r55k-cgu.0.rcgu.o): In function `LBB169_7':
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b984): undefined reference to `__lshrsi3'
          compiler_builtins.d7w6r55k-cgu.0:(.progmem.data+0x1b99c): undefined reference to `__ashlsi3'
          collect2: error: ld returned 1 exit status
          

error: aborting due to previous error

Because these clearly aren't normal Rust compiler errors, it seems like this might be a bug with the Rust compiler itself. Does anything obvious stand out as a problem here? Could there be a problem with my setup? I just updated and re-compiled avr-rust today to make sure. Note that this error only occurs if I invoke the receive method of w5500 in my application. Full application code can be found here:

https://github.com/jonahbron/smart-plug/tree/c9f8994

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 15, 2019

This error often occurs if your program size overflows the flash size. Are you building in release or debug mode?

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 16, 2019

Sorry, should have read more carefully ... It seems you are already building in release mode, so the compiler is doing its best to optimize out everything it can. Somewhere along the call-graph you are pulling in code which bloats the binary so much that it no longer fits into flash. A common candidate for this is core::fmt.

I'm not sure what the best way is to find out where this issue comes from. Personally, I'd use one of these:

  1. Try commenting out parts until you find the one responsible. In this case, the code you linked contains a few references to core::fmt, they might be good candidates.
  2. Try building with rustc --emit=obj and analyze the symbol sizes with nm --print-size --size-sort.
@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

Ah, that seems like a good place to start, thank you @Rahix . Would it be appropriate to alter the compiler so that it can catch that sort of problem and provide a clearer error message?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

@Rahix Do you know if there's a way to alter the target descriptor to trick it into thinking there's more space? At least it would let me confirm that it's a size constraint issue.

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 16, 2019

Would it be appropriate to alter the compiler so that it can catch that sort of problem and provide a clearer error message?

Not really possible as final sizes are only known at link time.

Do you know if there's a way to alter the target descriptor to trick it into thinking there's more space?

You could write your own linker script, but I don't think the effort is worth it. Try compiling with --emit=obj, you'll see pretty quickly where the bloat comes from.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

@Rahix I'm having trouble figuring how how to follow your instructions. Currently my command to compile is

xargo build --target avr-atmega328p --release

So I tried altering it to be

xargo rustc --target avr-atmega328p --release -- --emit=obj

But it ends up giving the same error. It seems like nm is expecting some sort of file, but I don't know where to find the file supposedly being output by emit=obj.

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 16, 2019

It should be an object file (.o), somewhere in target/avr-atmega328p/release. It should still be emitted, even if you get the error during linking.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

Thanks so much for your help @Rahix . I find the file and got the output.

00000000 00000001 B DEVICE_PERIPHERALS
0000119c 00000002 r rust_begin_unwind
00000000 00000002 r __unnamed_3
00000008 00000002 r _ZN4core3ptr18real_drop_in_place17h671565532a8ec42eE
0000000a 00000002 r _ZN4core3ptr18real_drop_in_place17h84aaf412b5654cb2E
00000000 00000004 r _ZN112_$LT$embedded_hal..digital..v1_compat..OldOutputPin$LT$T$GT$$u20$as$u20$embedded_hal..digital..v1..OutputPin$GT$7set_low17ha964da085e52de99E
00000004 00000004 r _ZN112_$LT$embedded_hal..digital..v1_compat..OldOutputPin$LT$T$GT$$u20$as$u20$embedded_hal..digital..v1..OutputPin$GT$8set_high17h53da3a0de33410acE
000011a6 00000008 r _ZN4core9panicking5panic17h5dbe8e19a91fe7ddE
0000119e 00000008 r _ZN4core9panicking9panic_fmt17h88f68b20b00f166eE
00000000 0000000a d __unnamed_1
00000000 0000000a d __unnamed_2
00001190 0000000c r _ZN84_$LT$atmega328p_hal..spi..Spi$u20$as$u20$embedded_hal..spi..FullDuplex$LT$u8$GT$$GT$4read17h7ffa6261298b29e9E
00000000 00000019 r switch.table._ZN5w55008Register12control_byte17h997a9dab34649aa0E
00001120 00000070 r _ZN84_$LT$atmega328p_hal..spi..Spi$u20$as$u20$embedded_hal..spi..FullDuplex$LT$u8$GT$$GT$4send17hfd5c80352a5cc8d5E
0000000c 00000252 r _ZN5w550020ActiveW5500$LT$E$GT$8write_to17h03ad5119f6a62654E
0000025e 00000258 r _ZN5w550020ActiveW5500$LT$E$GT$9read_from17h90d8084f962a2233E
000004b6 00000c6a R main

Based on some some searching, it sounds like the second column is the size of each object in hex. They sum up to ~4.5Kb The big things are w5500's write_to and read_from methods, and (assumedly) my program's main. Is it possible to explore the contents of those functions with this method to determine what their size is caused by?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

Something I've found is that those two functions contain the only references to the dependency crate "BigEndian".

https://github.com/kellerkindt/w5500/blob/master/src/lib.rs#L247

It's possible that this dependency is too large. Will need to investigate further.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 16, 2019

Apparently the ATMega328P has 32Kb of program memory. So it seems super weird that 4.5Kb would be too much...

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 17, 2019

Hm. Try nm -u to see undefined symbols in that object file. You might also want try not unwrapping the result, because that will pull in core::fmt. Instead, you can .unwrap_or_else(|_| panic!());

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 17, 2019

@Rahix I made the unwrap change you suggested (and pushed up to the repo), and tried nm -u. It only had these items:

         U abort
         U __do_clear_bss
         U __do_copy_data
         U memset

Even if I add print-size, the output remains the same.

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 17, 2019

Sorry, I really don't have the time right now to look into this in more detail ... I am pretty confident it has something to do with formatting of u64/i64/u128/i128. Whether that's code-size or some missing intrinsics in compiler-builtins I am not sure. You'll probably be best off if you try removing everything fmt related from that crate you are using. If that is not enough, look at panic related stuff. One other thing which might be relevant is enums with values, because they use a u64 as the discriminant internally. Good luck! Feel free to still post whatever you can dig up, maybe someone else has ideas ...

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 17, 2019

Thanks a lot for your input @Rahix . I'll start ripping the crate apart and see what I can get to compile.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 18, 2019

By commenting bits out one at a time, I finally narrowed the difference between successful compilation and failure down to the invocation to my SPI implementation... 😬 . Which is very odd since I can run a simple example if I call the SPI library directly. Still digging.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 18, 2019

I've been at it for a few hours, and I've distilled this down to the most simple POC that I can make demonstrate the problem.

https://github.com/jonahbron/smart-plug/tree/error-demo

The program here is very simple. The w5500 code is pulled into main.rs and mangled down to about 30 lines. There are two main.rs files. One is main.rs, and if you compile it with make, it will produce the linker error. If you instead swap out the code from main2.rs, the code will compile and link successfully. It only changes 3 lines, and all they do is improve the use of generics. That's all it takes for it to suddenly compile just fine. Here's the diff:

36,37c36,37
< pub struct W5500<'c, E> {
<     pub spi: &'c mut dyn FullDuplex<u8, Error = E>,
---
> pub struct W5500<'c, E, S: FullDuplex<u8, Error = E>> {
>     pub spi: &'c mut S,
40c40
< impl<E> W5500<'_, E> {
---
> impl<E, S: FullDuplex<u8, Error = E>> W5500<'_, E, S> {

Also, the error only appears if I call the receive method twice (line 18).

    // Removing one of these lines will get rid if the linker error
    w5500.receive(&mut buffer[..]);
    w5500.receive(&mut buffer[..]);

Unless someone has any more thoughts @Rahix @dylanmckay , I don't see how this couldn't be a bug with the compiler. I'm going to try improving the generics on the full, original w5500 crate to see if that helps the issue.

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Jul 18, 2019

Oh wow, the driver is using a trait object? Trait objects need type IDs which are also u64 IIRC. So this is likely the cause. Is there any particular reason the driver needs dynamic dispatch?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 18, 2019

@Rahix I doubt it, seems like a mistake by the dev. However I do see that all of the enums have this in front of them:

#[repr(u8)]

I'm guessing that prevents the need for u64 for discrimination.
https://doc.rust-lang.org/reference/type-layout.html#primitive-representations

I'll try to refactor out that trait object tonight. Hopefully that resolves the issue.

Would it make sense for the compiler to error over this, so it doesn't make it to the linker and fail?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 18, 2019

Thanks for your direction @Rahix ! Getting rid of those trait objects has fixed compilation. Still need to do a real test, but I've opened a PR:

kellerkindt/w5500#7

@dylanmckay I'd still like to know if you consider this something that could be turned into a more explicit error.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 20, 2019

So apparently I had a false positive. Even after my fix, I'm still getting the same compilation errors if if I call the blocking_send or receive methods from my application. I'm going to work on narrowing it down to the smallest possible reproduction.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 20, 2019

It seems like this might be related to the usage of dynamic integers of type u16. There are lots of constant integers of type u16, but I'm guessing that the compiler isn't making a fuss because it knows they're actually less than 256.

Could this be the case? Are u16 types entirely unsupported?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 20, 2019

Further testing doesn't seem to indicate this is a problem with u16. I've found two lines that I can tweak that allows the program to compile:

--- a/src/lib.rs
+++ b/src/lib.rs
@@ -385,7 +385,7 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> Udp<E> for (&mut
 
             w5500.read_from(
                 socket.rx_register_at(read_pointer + 8),
-                &mut destination[..data_length],
+                &mut destination[..42],
             )?;
 
             // self.read_from(socket.register_at(0x00_0C), &mut ip.address)?;
@@ -441,7 +441,7 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> Udp<E> for (&mut
             )?;
         }
 
-        let data_length = data.len() as u16;
+        let data_length = data.len() as u8;
         {
             let data_length = data_length.to_be_bytes();

That data_length variable in the first one of type usize. Rustc will complain if I try to change it to u8 or something else.

error[E0277]: the type `[u8]` cannot be indexed by `core::ops::RangeTo<u8>`
   --> /home/jonah/Projects/w5500/src/lib.rs:388:22
    |
388 |                 &mut destination[..{data_length as u8}],
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `core::slice::SliceIndex<[u8]>` is not implemented for `core::ops::RangeTo<u8>`
    = note: required because of the requirements on the impl of `core::ops::Index<core::ops::RangeTo<u8>>` for `[u8]`

Changing it to a literal number (which I assume is coerced to usize) is the only thing that fixes it. 42 is the greatest integer that it accepts, which is extremely weird. I'd expect it to be a power of 2. 43 for example will produce the same linker error.

The second item in the diff doesn't suffer at all from changing u16 to u8.

I feel very lost right now, and it seems as though there are several layers of understanding that I'm lacking, given how confused I am by how these changes impact the linker. Any advice is welcome.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Jul 31, 2019

I've made some progress! I got it to compile with a call to receive if I reduce the size of the slice I pass in (the destination variable in the diff above) to 16 bytes in length. This gets a simple program to compile without modifying the library. Not sure if I can reduce this to a more simple example, but I will try.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Aug 1, 2019

After spending about 3.5 hours and poring over hundreds of lines of code, I've been able to reduce the error demo down to 15 lines. I'm really hoping this sample is small enough for someone to be able to tell me what the problem with the code is, allow them to fix a bug in the compiler that makes this not work. I don't fully understand this code, I just know it's a direct simplification of the full version, and produces the same error.

Full project: https://github.com/jonahbron/smart-plug/blob/error-demo-2/src/main.rs

Source code:

#![no_std]
#![no_main]
#![feature(asm)]
extern crate panic_halt;
#[no_mangle]
extern fn main() -> () {
    let mem = unsafe {
        &*{ 76 as *const vcell::VolatileCell<u8> }
    };
    let len = mem.get() as usize;
    // If you change this 17 to 16, the error goes away
    for _ in &mut [0u8; 17][..len] {
        mem.get();
    }
}

Compiling this in the project repo with make will produce the error previously commented.

Fortunately for my application, a 16-byte packet length is perfectly fine. But I think there would be a lot of value for other people if this problem was sorted out, whether it's in avr-rust, svd2rust, avr-hal, avr-device, or w5500.

@Rahix @dylanmckay

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Sep 19, 2019

Found a lead. I googled that missing function in the error, and got this result:

https://stackoverflow.com/questions/29222673/math-symbols-missing-from-avr-libgcc

Apparently those functions have been removed and replaced with something else. I guess the next step is to figure out what exactly is generating them (surely the compiler?) and update that code.

@iiian

This comment has been minimized.

Copy link

@iiian iiian commented Sep 20, 2019

The symbols you're missing are:

__ashlsi3
__lshrsi3
__divmodti4
__ashrsi3

one option that you have is to visit https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/lm32/_ashlsi3.S

and pull their assembly files.

If you're curious about what these functions are: http://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html

Given the documentation on them, it seems like you're going to have a hard time getting away with just removing them, since you're in an embedded context which I could certainly believe doesn't have "hardware support for arithmetic operations on some modes"

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Sep 20, 2019

It looks like this is a known issue in LLVM that's being tracked here:

avr-llvm/llvm#163

Seems like this problem has been around a while, and got merged upstream into LLVM. It's even mentioned in the RFC.

@dylanmckay Is there any light at the end of this tunnel? I see the activity on this repo has slowed since June.

@TimNN Pinging you as well in case you're still involved in this project. Based on this comment you made last year, it sounds like you understand this problem. Did you make any progress in fixing it, or is there any direction you could offer to me in fixing it? While your description in the solution of the problem seems simple, I'm worried there might be more to it based on @dylanmckay's older comment here:

avr-llvm/llvm#163 (comment)

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Sep 21, 2019

Based on a review of libgcc, it appears that the functions mentioned in this error are present and supported. I'm no pro, but it looks to me like a couple things need to happen:

  1. Add support for them in LLVM's compiler-rt (maybe here)
  2. Add support for them in Rust's compiler-builtins (maybe here)

Maybe there are other steps, but based on my research so far it seems like that would fix the error.

@Rahix

This comment has been minimized.

Copy link

@Rahix Rahix commented Oct 1, 2019

Both projects don't yet have any AVR related code which might make it hard to convince upstream to merge those changes ... I suggest forking compiler-builtins and adding AVR-specific intrinsics. You can then instruct xargo to build using your fork with a Xargo.toml like

[dependencies.core]
stage = 0

[dependencies.compiler_builtins]
stage = 1
git = "https://your.fork/"
rev = "git-hash"

if I remember correctly.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Oct 5, 2019

Thank you @Rahix. What advice can you give around how to add those intrinsics? This is all new to me, I know nothing.

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Oct 5, 2019

@Rahix I thought the base AVR work had been already merged into upstream LLVM?

@jonahbron

This comment has been minimized.

Copy link
Author

@jonahbron jonahbron commented Oct 23, 2019

@Rahix I'm seeing some mysterious behavior in my attempt to add the missing symbols. As soon as I pull in compiler-builtins (without making any changes), the errors disappear. However, the parts of the code that produced that linker error do not behave as expected. Specifically, it seems that my driver is unable to communicate with the W5500 chip. How could this be, when compiler-builtins does not appear to provide these symbols?

@dylanmckay

This comment has been minimized.

Copy link
Member

@dylanmckay dylanmckay commented Nov 26, 2019

@Rahix I thought the base AVR work had been already merged into upstream LLVM?

We haven't yet enabled AVR support in compiler-rt - it is possible to get most of it for free by letting compiler-rt fall back to the target independent C-only rtcall implementations, although the biggest prickle is a couple register allocation special cases inherited from avr-gcc for arithmetic routines like mul, div, mod, would require hand-rolled AVR asm to match the GNU AVRf libgcc ABI.

@rodrigorc

This comment has been minimized.

Copy link

@rodrigorc rodrigorc commented Nov 26, 2019

, although the biggest prickle is a couple register allocation special cases inherited from avr-gcc for arithmetic routines like mul, div, mod, would require hand-rolled AVR asm to match the GNU AVRf libgcc ABI.

I've sent a few weeks ago a patch to LLVM that implements what I think is a full GCC ABI compatible calling convention, but I'm afraid it fell through the mailing-list cracks 😢. Maybe it can help with these issues?

@dylanmckay

This comment has been minimized.

Copy link
Member

@dylanmckay dylanmckay commented Nov 26, 2019

I noticed that - great work! I spotted your patch a couple days ago, I've started the first round of review.

I suspect it will help (especially with your removal one of one of libgcc special cases), but I feel like we'll still have to hand-roll a couple routines in compiler-rt to get them ABI compatible, as we won't get that with the generic C implementation AFAIK.

Perhaps the best solution w.r.t. avr-libgcc compatibility is to eschew being compatible with the custom ABI routines and instead lower them to AVR instructions directly in the backend, removing the dependency on the rtlib for this.

@rodrigorc

This comment has been minimized.

Copy link

@rodrigorc rodrigorc commented Nov 26, 2019

I noticed that - great work! I spotted your patch a couple days ago, I've started the first round of review.

Oh, true, I hadn't notice, great! I'll review and rebase in a couple of days.

I suspect it will help (especially with your removal one of one of libgcc special cases), but I feel like we'll still have to hand-roll a couple routines in compiler-rt to get them ABI compatible, as we won't get that with the generic C implementation AFAIK.

What I've done is to add this to my Xargo.toml:

[dependencies.compiler_builtins]
path = "./cbi"

And then in ./cbi I created an empty crate named compiler_builtins with #![no_core]. That solved all likers errors for me, but I'm not exactly sure why I didn't even need to define a single function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.