avr-llvm / clang

[MERGED UPSTREAM] Clang frontend supporting AVR
Other
11 stars 1 forks source link

Weakly undefined symbols #9

Open dylanmckay opened 9 years ago

dylanmckay commented 9 years ago

Note: Migrated from here.

Weakly defined symbols like so (taken from Arduino):

// this next line disables the entire HardwareSerial.cpp, 
// this is so I can support Attiny series and any other chip without a uart
#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)

// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
// but we can refer to it weakly so we don't pull in the entire
// HardwareSerial instance if the user doesn't also refer to it.
#if defined(HAVE_HWSERIAL0)
  void serialEvent() __attribute__((weak));
  bool Serial0_available() __attribute__((weak));
#endif

#if defined(HAVE_HWSERIAL1)
  void serialEvent1() __attribute__((weak));
  bool Serial1_available() __attribute__((weak));
#endif

#if defined(HAVE_HWSERIAL2)
  void serialEvent2() __attribute__((weak));
  bool Serial2_available() __attribute__((weak));
#endif

#if defined(HAVE_HWSERIAL3)
  void serialEvent3() __attribute__((weak));
  bool Serial3_available() __attribute__((weak));
#endif

Are failing during the link stage due to undefined references to the weak symbols (by GNU's avr-ld). Weak symbols have the property that if they are not defined, they are set to null instead. It makes no sense for a weak undefined symbol, thus this error must lay with clang or llvm not placing the weak attribute in the ELF object file.

4ntoine commented 9 years ago
MBA-Anton:bin asmirnov$ ./clang -v
clang version 3.8.0 (https://github.com/avr-llvm/clang.git 3b2c949e21022c841c80fca5e79d1f1387cd012c) (llvm/llvm.git 47a798c880f7baaf6b80b99e8653a22a28efc025)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
4ntoine commented 9 years ago

Here is HardwareSerial.cpp and HardwareSerial.ll (just to check if weak is absent in ll): https://gist.github.com/4ntoine/f00d0651bdda6744e41e.

I've used

MBA-Anton:bin asmirnov$ ./clang -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/variants/standard -I/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include --target=avr /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp -o /tmp/arduino_test1/HardwareSerial.cpp.o

to get .ll from .cpp (just like original Arduino IDE does, except i've replaced -o /tmp/arduino_test1/HardwareSerial.cpp.o with -S -emit-llvm -o /tmp/arduino_test1/HardwareSerial.ll).

I'm able to find weak in .ll: define weak void @_Z14serialEventRunv() #0 {

4ntoine commented 9 years ago

also i can see some 'extern_weak' attributes:

; Function Attrs: optsize
declare extern_weak void @_Z11serialEventv() #0
dylanmckay commented 9 years ago

This means that this is not a clang problem, but an LLVM problem.

4ntoine commented 9 years ago

http://stackoverflow.com/questions/32879801/does-llvm-clang-support-weak-attribute

dylanmckay commented 9 years ago

LLVM does support weak linkage here. Function signatures can also be annotated with weak and so LLVM does support it.

The problem must be deeper.

4ntoine commented 9 years ago

as you can see in SO question, i've tried Apple's LLVM/Clang and non-avr sources and it can't link. I believe it's a bug, but i've asked the question to both cfe-users@ and cfe-dev@ maillists.