BartmanAbyss / vscode-amiga-debug

One-stop Visual Studio Code Extension to compile, debug and profile Amiga C/C++ programs compiled by the bundled gcc 12.2 with the bundled WinUAE/FS-UAE.
GNU General Public License v3.0
303 stars 38 forks source link

Linker not always capable of resolving xref in vasm results #230

Closed Slamy closed 1 year ago

Slamy commented 1 year ago

With the keyword xref I'm usually able to reference symbols external to my module. With something like INCBIN(player, "player610.6.no_cia.bin") this works and the linker is happy. But with a global variable defined in C or a function it is an undefined symbol.

I've prepared a minimal example in a fork of the project: https://github.com/BartmanAbyss/vscode-amiga-debug/compare/master...Slamy:vscode-amiga-debug:feature/broken

Compiling main.c
Assembling support/depacker_doynax_vasm.asm
Linking out/a.elf
/home/andre/.vscode/extensions/bartmanabyss.amiga-debug-1.7.2/bin/linux/opt/bin/../lib/gcc/m68k-amiga-elf/13.1.0/../../../../m68k-amiga-elf/bin/ld: obj/depacker_doynax_vasm.o: in function `_doynaxdepack_vasm':
/home/andre/GIT/vscode-amiga-debug/template/support/depacker_doynax_vasm.asm:57: undefined reference to `HerpDerp'
collect2: fatal error: ld returned 1 exit status
compilation terminated.
make: *** [Makefile:50: out/a.elf] Fehler 1

It confuses me because the object files clearly contain what should be needed for linking. But sadly I'm not an expert concerning the elf format. Maybe some attributes aren't right.

m68k-amiga-elf-objdump obj/main.o -t | grep HerpDerp
00000000 l    d  .gnu.lto_HerpDerp.32.61a8a30afa56d6bb  00000000 .gnu.lto_HerpDerp.32.61a8a30afa56d6bb
00000468 g     F .text  00000002 HerpDerp

m68k-amiga-elf-objdump obj/depacker_doynax_vasm.o -t | grep HerpDerp
00000000         *UND*  00000000 HerpDerp

I have the feeling that this relates to the GNU part of this project as I have a vanilla m68k-elf-gcc around which is happy with the vasm output. At least it links...

BartmanAbyss commented 1 year ago

This is just a side-effect of LTO/-fwhole-program: (see also [https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html]) Just put __attribute__((externally_visible)) in front of void HerpDerp() and it will work fine. However be careful and read the link above to avoid any strange duplication behavior.

Slamy commented 1 year ago

This solved the issue and I do have to admit that I wasn't aware of the effect of '-fwhole-program'. Still two things bother me:

  1. How can we avoid having people fall into the same trap? It will happen eventually.
  2. Why is the effect not observable via 'm68k-amiga-elf-objdump'? I would have understood the whole problem if the symbol was absent from the object file. Still this isn't the case. Maybe I'm missing the whole picture. I'm by far no compiler/linker expert.
BartmanAbyss commented 1 year ago
  1. I thought about that as well, but I'm not sure.. This was the first time this ever came up.
  2. Thing is, with LTO the object files aren't standard. They contain only intermediate code representation. The actual compiling is done during the linking step. This is what enables the huge benefits of LTO (project-wide code visibility for inlining, optimizing, etc.)