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

ld.bfd --gc-sections not working properly in LoongArch #40

Closed
jiegec opened this issue Jan 25, 2024 · 13 comments
Closed

ld.bfd --gc-sections not working properly in LoongArch #40

jiegec opened this issue Jan 25, 2024 · 13 comments

Comments

@jiegec
Copy link

jiegec commented Jan 25, 2024

Consider the following code (taken from u-boot-loongson):

// in a.c
extern void led_default_state();

int board_late_init(void) {
        led_default_state();
}

void spl_board_init(void) {
}

// in main.c
extern void spl_board_init();
int main() {
        spl_board_init();
}

Compile and link with -ffunctions-sections -fdata-sections -fno-plt:

gcc -c a.c -o a.o -fdata-sections -ffunction-sections -fno-plt
gcc -c main.c -o main.o -fdata-sections -ffunction-sections -fno-plt
gcc -Wl,--print-gc-sections -Wl,--gc-sections a.o main.o -o main

Output on loongarch:

/usr/bin/ld: removing unused section '.rodata.cst4' in file '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/usr/bin/ld: a.o: in function `board_late_init':
a.c:(.text.board_late_init+0x10): undefined reference to `led_default_state'
/usr/bin/ld: a.c:(.text.board_late_init+0x14): undefined reference to `led_default_state'
collect2: error: ld returned 1 exit status

Output on amd64:

/usr/bin/ld: removing unused section '.rodata.cst4' in file '/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o'
/usr/bin/ld: removing unused section '.data' in file '/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o'
/usr/bin/ld: removing unused section '.text.board_late_init' in file 'a.o'

You can see that .text.board_late_init is not properly GC-ed. If -fno-plt is removed, it works.

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

I have added some _bfd_error_handler calls to binutils and here is the output:

/buildroots/jiegec/prefix/binutils-gdb/bin/ld: In bfd_elf_gc_sections
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: keeping '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: keeping '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.note.ABI-tag' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.note.ABI-tag' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.main' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.note.gnu.build-id' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.note.gnu.build-id' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.fini_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.fini_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.fini_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.tm_clone_table' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.bss' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.bss' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.bss' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.sdata' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.sdata' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.sdata' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.sdata' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.sdata' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/libc.so.6'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.init_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.init_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.init_array' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtbeginS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.eh_frame' from 'main.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: marking gc '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in bfd_elf_gc_mark '.eh_frame' from '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/crtendS.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: removing unused section '.rodata.cst4' in file '/usr/lib/gcc/loongarch64-aosc-linux-gnu/13.2.0/../../../Scrt1.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: a.o: in function `board_late_init':
a.c:(.text.board_late_init+0x10): undefined reference to `led_default_state'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: a.c:(.text.board_late_init+0x14): undefined reference to `led_default_state'

It somehow marked .text.board_late_init for keeping from GC-ed.

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

Possible bug:

/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_fdes '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in mark_entry '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_reloc '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_rsec, r_symndx = '11', sec '.eh_frame'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_reloc '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_rsec, r_symndx = '12', sec '.eh_frame'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_reloc '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_rsec, r_symndx = '11', sec '.eh_frame'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.spl_board_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_reloc '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark_rsec, r_symndx = '8', sec '.eh_frame'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook '.eh_frame' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in loongarch_elf_gc_mark_hook return '.text.board_late_init' from 'a.o'
/buildroots/jiegec/prefix/binutils-gdb/bin/ld: in _bfd_elf_gc_mark '.text.board_late_init' from 'a.o'

When marking spl_board_init, it locates eh_frame FDE entry for board_late_init.

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

The extra relocations of R_LARCH_ADD6 and R_LARCH_SUB6 are weird:


Relocation section '.rela.text.board_late_init' at offset 0x320 contains 4 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000010  00110000004b R_LARCH_GOT_PC_HI 0000000000000000 led_default_state + 0
000000000010  000000000064 R_LARCH_RELAX                        0
000000000014  00110000004c R_LARCH_GOT_PC_LO 0000000000000000 led_default_state + 0
000000000014  000000000064 R_LARCH_RELAX                        0

Relocation section '.rela.eh_frame' at offset 0x380 contains 8 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000001c  000600000063 R_LARCH_32_PCREL  0000000000000000 L0^A + 0
000000000020  000900000032 R_LARCH_ADD32     0000000000000034 L0^A + 0
000000000020  000600000037 R_LARCH_SUB32     0000000000000000 L0^A + 0
000000000040  000b00000063 R_LARCH_32_PCREL  0000000000000000 L0^A + 0
000000000044  000c00000032 R_LARCH_ADD32     000000000000001c L0^A + 0
000000000044  000b00000037 R_LARCH_SUB32     0000000000000000 L0^A + 0
000000000031  000800000069 R_LARCH_ADD6      0000000000000028 L0^A + 0
000000000031  00070000006a R_LARCH_SUB6      0000000000000010 L0^A + 0
Symbol table '.symtab' contains 19 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 .text
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 .data
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 .bss
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 .text.board_late_init
     6: 0000000000000000     0 NOTYPE  LOCAL  HIDDEN     4 L0^A
     7: 0000000000000010     0 NOTYPE  LOCAL  HIDDEN     4 L0^A
     8: 0000000000000028     0 NOTYPE  LOCAL  HIDDEN     4 L0^A
     9: 0000000000000034     0 NOTYPE  LOCAL  HIDDEN     4 L0^A
    10: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 .text.spl_board_init
    11: 0000000000000000     0 NOTYPE  LOCAL  HIDDEN     6 L0^A
    12: 000000000000001c     0 NOTYPE  LOCAL  HIDDEN     6 L0^A
    13: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 .note.GNU-stack
    14: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 .comment
    15: 0000000000000000     0 SECTION LOCAL  DEFAULT    9 .eh_frame
    16: 0000000000000000    52 FUNC    GLOBAL DEFAULT    4 board_late_init
    17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND led_default_state
    18: 0000000000000000    28 FUNC    GLOBAL DEFAULT    6 spl_board_init

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

I found the bug: the relocations are not in-ordered: R_LARCH_ADD6 and R_LARCH_SUB6 appear after the ones for spl_board_init, and the code in binutils assumes the order:

  /* FIXME: octets_per_byte.  */
  for (cookie->rel = cookie->rels + ent->reloc_index;
       cookie->rel < cookie->relend
	 && cookie->rel->r_offset < ent->offset + ent->size;
       cookie->rel++)
    if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
      return false;

It only checks if cookie->rel->r_offset < ent->offset + ent->size, not cookie->rel->r_offset >= ent->offset (cookie->rel->r_offset is 49, ent->offset is 56, ent->size is 32).

R_LARCH_ADD6 is generated for DW_CFA_advance_loc, which is in turn used for relaxation.

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

Possible solutions:

  1. Ensure the relocation offsets to be monotonic: best
  2. Disable linker relaxation: sad
  3. Handle the out of order case in mark_entry: might not handle all cases

@xry111
Copy link
Member

xry111 commented Jan 25, 2024

If you know how to fix it please send a patch to binutils@sourceware.org (with a DCO Signed-Off-By:) ASAP. The release of 2.42 is imminent.

@jiegec
Copy link
Author

jiegec commented Jan 25, 2024

On the contrary, the order is correct in RISC-V:

Relocation section '.rela.text.board_late_init' at offset 0x3b0 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000008  001400000013 R_RISCV_CALL_PLT  0000000000000000 led_default_state + 0
000000000008  000000000033 R_RISCV_RELAX                        0

Relocation section '.rela.eh_frame' at offset 0x3e0 contains 8 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000001c  000600000039 R_RISCV_32_PCREL  0000000000000000 .L0  + 0
000000000020  000a00000023 R_RISCV_ADD32     000000000000001c .L0  + 0
000000000020  000600000027 R_RISCV_SUB32     0000000000000000 .L0  + 0
000000000031  000900000035 R_RISCV_SET6      0000000000000016 .L0  + 0
000000000031  000800000034 R_RISCV_SUB6      0000000000000008 .L0  + 0
000000000044  000c00000039 R_RISCV_32_PCREL  0000000000000000 .L0  + 0
000000000048  000e00000023 R_RISCV_ADD32     000000000000000e .L0  + 0
000000000048  000c00000027 R_RISCV_SUB32     0000000000000000 .L0  + 0

@xry111
Copy link
Member

xry111 commented Feb 1, 2024

https://sourceware.org/pipermail/binutils/2024-February/132266.html

Pity: it seems the thought to test the Binutils pre-release with GCC trunk has never occurred to anyone (including myself) or we'll catch this much earlier!

@cloudspurs
Copy link

Possible solutions:

  1. Ensure the relocation offsets to be monotonic: best
  2. Disable linker relaxation: sad
  3. Handle the out of order case in mark_entry: might not handle all cases

What version of your binutils? This bug has been fixed by Jinyang He on master branch(commit id: 7c93730fe50c22129e751d8479e64bc970b75aac). I will backport it to binutils 2.41 branch (binutils-2_41-branch).

@jiegec
Copy link
Author

jiegec commented Feb 3, 2024

Possible solutions:

  1. Ensure the relocation offsets to be monotonic: best
  2. Disable linker relaxation: sad
  3. Handle the out of order case in mark_entry: might not handle all cases

What version of your binutils? This bug has been fixed by Jinyang He on master branch(commit id: 7c93730fe50c22129e751d8479e64bc970b75aac). I will backport it to binutils 2.41 branch (binutils-2_41-branch).

I was using binutils 2.41. And I confirm that binutils 2.42 fixes the issue.

@jiegec jiegec closed this as completed Feb 3, 2024
@xry111
Copy link
Member

xry111 commented Feb 3, 2024

Hmm, but in Binutils 2.42 several tests in the test suite for -Wl,--gc-sections still fail with GCC 14. Then they might be different problems...

@cloudspurs
Copy link

Hmm, but in Binutils 2.42 several tests in the test suite for -Wl,--gc-sections still fail with GCC 14. Then they might be different problems...

I will take a look today.

@cloudspurs
Copy link

cloudspurs commented Feb 5, 2024

Hmm, but in Binutils 2.42 several tests in the test suite for -Wl,--gc-sections still fail with GCC 14. Then they might be different problems...

I will take a look today.

These errors are caused by R_LARCH_ALIGN or mismatched error message. But, it may be fixed after Spring Festival.

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

No branches or pull requests

4 participants