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

Why is .symtab so huge on riscv? #1036

Open
xnox opened this issue Mar 9, 2022 · 13 comments
Open

Why is .symtab so huge on riscv? #1036

xnox opened this issue Mar 9, 2022 · 13 comments

Comments

@xnox
Copy link

xnox commented Mar 9, 2022

Most binaries compiled on riscv have .symtab that is 2x-3x larger than on any other architecture. Is that normal and intentional, or is something wrong with my toolchain?

For example you can see that even in Scrt1.o, where on riscv64 there are alsmost 3 times as many symbols defined.

# readelf -W -S /usr/*/lib/Scrt1.o | grep -e symtab -e File:
File: /usr/aarch64-linux-gnu/lib/Scrt1.o
  [10] .symtab           SYMTAB          0000000000000000 0000e8 000150 18     11   7  8
File: /usr/riscv64-linux-gnu/lib/Scrt1.o
  [13] .symtab           SYMTAB          0000000000000000 000108 0002e8 18     14  24  8
File: /usr/x86_64-linux-gnu/lib/Scrt1.o
  [11] .symtab           SYMTAB          0000000000000000 0000f0 0000f0 18     12   3  8

# readelf -s /usr/*/lib/Scrt1.o                                  

File: /usr/aarch64-linux-gnu/lib/Scrt1.o

Symbol table '.symtab' contains 14 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 .text
     2: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 $d
     3: 0000000000000000    32 OBJECT  LOCAL  DEFAULT    1 __abi_tag
     4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    2 $x
     5: 0000000000000014     0 NOTYPE  LOCAL  DEFAULT    5 $d
     6: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    4 $d
     7: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND abort
     8: 0000000000000000    52 FUNC    GLOBAL DEFAULT    2 _start
     9: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND main
    10: 0000000000000000     0 NOTYPE  WEAK   DEFAULT    7 data_start
    11: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 _IO_stdin_used
    12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_start_main
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    7 __data_start

File: /usr/riscv64-linux-gnu/lib/Scrt1.o

Symbol table '.symtab' contains 31 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000    32 OBJECT  LOCAL  DEFAULT    1 __abi_tag
     2: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    2 $x
     3: 000000000000002c     0 NOTYPE  LOCAL  DEFAULT    2 load_gp
     4: 000000000000000c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
     5: 000000000000002c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
     6: 0000000000000002     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
     7: 000000000000000a     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
     8: 000000000000000c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
     9: 0000000000000014     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    10: 0000000000000016     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    11: 0000000000000018     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    12: 000000000000001c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    13: 000000000000001e     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    14: 0000000000000020     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    15: 0000000000000022     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    16: 000000000000002a     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    17: 000000000000002c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    18: 0000000000000034     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    19: 0000000000000036     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    20: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    21: 0000000000000036     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    22: 0000000000000002     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    23: 000000000000002c     0 NOTYPE  LOCAL  DEFAULT    2 .L0 
    24: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __global_pointer$
    25: 0000000000000002    42 FUNC    GLOBAL DEFAULT    2 _start
    26: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND main
    27: 0000000000000000     0 NOTYPE  WEAK   DEFAULT    7 data_start
    28: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 _IO_stdin_used
    29: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_start_main
    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    7 __data_start

File: /usr/x86_64-linux-gnu/lib/Scrt1.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 .text
     2: 0000000000000000    32 OBJECT  LOCAL  DEFAULT    2 __abi_tag
     3: 0000000000000000    38 FUNC    GLOBAL DEFAULT    3 _start
     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND main
     5: 0000000000000000     0 NOTYPE  WEAK   DEFAULT    8 data_start
     6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
     7: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    5 _IO_stdin_used
     8: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_start_main
     9: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    8 __data_start

This is further exaggerated for trivial hello-world binaries, and appears to become exponentially worse for linux kernel code and modules.

As an example see btrfs.ko module on x86_64 and riscv64:

$ du -h btrfs.ko.*
76M	btrfs.ko.riscv64
42M	btrfs.ko.x86_64

$ strip --strip-debug btrfs.ko.x86_64
$ riscv64-linux-gnu-strip --strip-debug btrfs.ko.riscv64 

$ du -h btrfs.ko.*
17M	btrfs.ko.riscv64
2.8M	btrfs.ko.x86_64

$ strip --strip-debug --discard-locals btrfs.ko.x86_64
$ riscv64-linux-gnu-strip --strip-debug --discard-locals btrfs.ko.riscv64

$ du -h btrfs.ko.*
4.2M	btrfs.ko.riscv64
2.8M	btrfs.ko.x86_64

I can understand that there are architectural differences and optimisations and more compact code on one arch versus the other, but it is unexpected to me that unstripped btrfs.ko with similar configuration of the kernel is 2x big on riscv64, that stripped module is 6x as big, and that locals take up 4x of the binary, and even then overall the binary is still 1.5x as big.

Is all of the above as expected and intentional that riscv64 toolchains emit a lot of .L* symbols in the symtab?

Or is my toolchain somehow miss configured?

@aswaterman
Copy link
Collaborator

This is due, at least in part, to the fact that RISC-V doesn’t compute branch targets until link time, to facilitate aggressive linker relaxation. By contrast, x86 and ARMv8 assemblers compute branch targets at assembly time, so don’t need to carry around some of those symbols.

Ordinarily, this only bloats the intermediate build artifacts (and static libraries), not linked executables.

@xnox
Copy link
Author

xnox commented Mar 9, 2022

That's very interesting, but even for trivial linked binaries the symtab has large difference in size, and has very weird contents.

$ echo 'void main(){};' > main.c

$ gcc -c -o x86_64.o ./main.c
$ riscv64-linux-gnu-gcc -c -o riscv64.o ./main.c
$ gcc -o x86_64 ./x86_64.o
$ riscv64-linux-gnu-gcc -o riscv64 ./riscv64.o

$ readelf --syms ./x86_64.o ./x86_64 ./riscv64.o ./riscv64 | grep -e symtab -e File:
File: ./x86_64.o
Symbol table '.symtab' contains 4 entries:
File: ./x86_64
Symbol table '.symtab' contains 35 entries:
File: ./riscv64.o
Symbol table '.symtab' contains 8 entries:
File: ./riscv64
Symbol table '.symtab' contains 61 entries:

Not sure how we go from 8 to 61 entries from intermediate build artifacts to a linked executable.

$ readelf --syms ./x86_64.o ./x86_64 ./riscv64.o ./riscv64

File: ./x86_64.o

Symbol table '.symtab' contains 4 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 .text
     3: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 main

File: ./x86_64

Symbol table '.dynsym' contains 6 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _[...]@GLIBC_2.34 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
     5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND [...]@GLIBC_2.2.5 (3)

Symbol table '.symtab' contains 35 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
     2: 000000000000038c    32 OBJECT  LOCAL  DEFAULT    4 __abi_tag
     3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
     4: 0000000000001070     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
     5: 00000000000010a0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
     6: 00000000000010e0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
     7: 0000000000004010     1 OBJECT  LOCAL  DEFAULT   24 completed.0
     8: 0000000000003df8     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtor[...]
     9: 0000000000001120     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
    10: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_in[...]
    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    12: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    13: 00000000000020c0     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    14: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    15: 0000000000003e00     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
    16: 0000000000002004     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
    17: 0000000000003fc0     0 OBJECT  LOCAL  DEFAULT   22 _GLOBAL_OFFSET_TABLE_
    18: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_mai[...]
    19: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
    20: 0000000000004000     0 NOTYPE  WEAK   DEFAULT   23 data_start
    21: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   23 _edata
    22: 0000000000001134     0 FUNC    GLOBAL HIDDEN    15 _fini
    23: 0000000000004000     0 NOTYPE  GLOBAL DEFAULT   23 __data_start
    24: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    25: 0000000000004008     0 OBJECT  GLOBAL HIDDEN    23 __dso_handle
    26: 0000000000002000     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
    27: 0000000000004018     0 NOTYPE  GLOBAL DEFAULT   24 _end
    28: 0000000000001040    38 FUNC    GLOBAL DEFAULT   14 _start
    29: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   24 __bss_start
    30: 0000000000001129    11 FUNC    GLOBAL DEFAULT   14 main
    31: 0000000000004010     0 OBJECT  GLOBAL HIDDEN    23 __TMC_END__
    32: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
    33: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@G[...]
    34: 0000000000001000     0 FUNC    GLOBAL HIDDEN    11 _init

File: ./riscv64.o

Symbol table '.symtab' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.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    5 .note.GNU-stack
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 .comment
     7: 0000000000000000    14 FUNC    GLOBAL DEFAULT    1 main

File: ./riscv64

Symbol table '.dynsym' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000530     0 SECTION LOCAL  DEFAULT   12 .text
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _[...]@GLIBC_2.34 (2)
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
     4: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND _[...]@GLIBC_2.27 (3)
     5: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
     6: 00000000000005e8    14 FUNC    GLOBAL DEFAULT   12 main

Symbol table '.symtab' contains 61 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000238     0 SECTION LOCAL  DEFAULT    1 .interp
     2: 000000000000025c     0 SECTION LOCAL  DEFAULT    2 .note.gnu.build-id
     3: 0000000000000280     0 SECTION LOCAL  DEFAULT    3 .note.ABI-tag
     4: 00000000000002a0     0 SECTION LOCAL  DEFAULT    4 .gnu.hash
     5: 00000000000002c8     0 SECTION LOCAL  DEFAULT    5 .dynsym
     6: 0000000000000370     0 SECTION LOCAL  DEFAULT    6 .dynstr
     7: 00000000000003e8     0 SECTION LOCAL  DEFAULT    7 .gnu.version
     8: 00000000000003f8     0 SECTION LOCAL  DEFAULT    8 .gnu.version_r
     9: 0000000000000428     0 SECTION LOCAL  DEFAULT    9 .rela.dyn
    10: 00000000000004e8     0 SECTION LOCAL  DEFAULT   10 .rela.plt
    11: 0000000000000500     0 SECTION LOCAL  DEFAULT   11 .plt
    12: 0000000000000530     0 SECTION LOCAL  DEFAULT   12 .text
    13: 00000000000005f8     0 SECTION LOCAL  DEFAULT   13 .eh_frame_hdr
    14: 0000000000000610     0 SECTION LOCAL  DEFAULT   14 .eh_frame
    15: 0000000000001df8     0 SECTION LOCAL  DEFAULT   15 .preinit_array
    16: 0000000000001e00     0 SECTION LOCAL  DEFAULT   16 .init_array
    17: 0000000000001e08     0 SECTION LOCAL  DEFAULT   17 .fini_array
    18: 0000000000001e10     0 SECTION LOCAL  DEFAULT   18 .dynamic
    19: 0000000000002000     0 SECTION LOCAL  DEFAULT   19 .data
    20: 0000000000002008     0 SECTION LOCAL  DEFAULT   20 .got
    21: 0000000000002048     0 SECTION LOCAL  DEFAULT   21 .sdata
    22: 000000000000204c     0 SECTION LOCAL  DEFAULT   22 .bss
    23: 0000000000000000     0 SECTION LOCAL  DEFAULT   23 .comment
    24: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
    25: 0000000000000280    32 OBJECT  LOCAL  DEFAULT    3 __abi_tag
    26: 0000000000000552     0 NOTYPE  LOCAL  DEFAULT   12 load_gp
    27: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    28: 000000000000055e     0 FUNC    LOCAL  DEFAULT   12 deregister_tm_clones
    29: 0000000000000580     0 FUNC    LOCAL  DEFAULT   12 register_tm_clones
    30: 00000000000005ac     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
    31: 000000000000204c     1 OBJECT  LOCAL  DEFAULT   22 completed.0
    32: 0000000000001e08     0 OBJECT  LOCAL  DEFAULT   17 __do_global_dtor[...]
    33: 00000000000005e6     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    34: 0000000000001e00     0 OBJECT  LOCAL  DEFAULT   16 __frame_dummy_in[...]
    35: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    36: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    37: 0000000000000638     0 OBJECT  LOCAL  DEFAULT   14 __FRAME_END__
    38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    39: 0000000000000500     0 OBJECT  LOCAL  DEFAULT  ABS _PROCEDURE_LINKA[...]
    40: 0000000000001e10     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
    41: 00000000000005f8     0 NOTYPE  LOCAL  DEFAULT   13 __GNU_EH_FRAME_HDR
    42: 0000000000002020     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
    43: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_mai[...]
    44: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
    45: 0000000000002000     0 NOTYPE  WEAK   DEFAULT   19 data_start
    46: 0000000000002050     0 NOTYPE  GLOBAL DEFAULT   22 __BSS_END__
    47: 000000000000204c     0 NOTYPE  GLOBAL DEFAULT   21 _edata
    48: 0000000000002048     0 NOTYPE  GLOBAL DEFAULT   21 __SDATA_BEGIN__
    49: 0000000000002000     0 NOTYPE  GLOBAL DEFAULT   19 __DATA_BEGIN__
    50: 0000000000002000     0 NOTYPE  GLOBAL DEFAULT   19 __data_start
    51: 0000000000002000     0 OBJECT  GLOBAL HIDDEN    19 __dso_handle
    52: 0000000000002048     4 OBJECT  GLOBAL DEFAULT   21 _IO_stdin_used
    53: 0000000000002050     0 NOTYPE  GLOBAL DEFAULT   22 _end
    54: 0000000000000530    34 FUNC    GLOBAL DEFAULT   12 _start
    55: 0000000000002800     0 NOTYPE  GLOBAL DEFAULT  ABS __global_pointer$
    56: 000000000000204c     0 NOTYPE  GLOBAL DEFAULT   22 __bss_start
    57: 00000000000005e8    14 FUNC    GLOBAL DEFAULT   12 main
    58: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@G[...]
    59: 0000000000002008     0 OBJECT  GLOBAL HIDDEN    20 __TMC_END__
    60: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]

Why does .symtab start with Scrt1.o on x86_64, but has like the entire contents of all the sections that come before .symtab, at the start of .symtab prior to its Scrt1.o on riscv64? What purpose do they have?

Going from 4->34 and 8->60 entries looks odd still.

At the moment I am experimenting with using --discard-locals on the kernel modules .ko builds, but that feels extremely awkward. Or is that appropriate?

@aswaterman
Copy link
Collaborator

Yeah, my earlier response only addresses the various .L0 labels. I can't speak to the other differences.

I did notice that --discard-all (which discards more local symbols than --discard-locals) cuts down the symbol table size substantially and still produces working binaries. But I have no idea what the other ramifications are.

@xnox
Copy link
Author

xnox commented Mar 10, 2022

This issue was brought up briefly on the RISC-V GNU Toolchain Biweekly Sync-up. It was pointed out that there probably is room to improve toolchain to emit less things under -mno-relax (?!) during binary builds. Whilst toolchain is being fixed, there might be an option to submit patch to the kernel to --discard-all or --discard-locals when installing stripped modules, if that helps.

@jim-wilson
Copy link
Collaborator

RISC-V is the only target that gets relaxation correct. I have a meta bug in binutils that describes relaxation related bugs with all other targets. This unfortunately results in a lot of extra symbols and relocations for RISC-V. Most of these other targets that use relaxation aren't linux capable targets though, they are almost all embedded only targets. Some of the issues are obscure, but they need to work for a linux toolchain, so RISC-V has to get them right.

There is a known problem with GNU as that we still emit extra symbols and relocations when -mno-relax is used. Kernel modules are compiled -mno-relax. So fixing this would help reduce the symtab size.

@andreas-schwab
Copy link

Only x86 defines TARGET_KEEP_UNUSED_SECTION_SYMBOLS to false so far, because doing so is known to break valid use cases.

@xnox
Copy link
Author

xnox commented Oct 13, 2022

I didn't find an existing gcc bugzilla bug report for this, so i have now opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107251

@TommyMurphyTM1234
Copy link
Collaborator

Hi @xnox - thanks a lot for logging the GCC bug upstream.

@Nelson1225
Copy link

Is all of the above as expected and intentional that riscv64 toolchains emit a lot of .L* symbols in the symtab?

Those .L0 are possible used to make %pcrel_lo linked to the correct %pcrel_hi. If so, then -mno-relax cannot remove them, otherwise relocation will fail.

@xnox
Copy link
Author

xnox commented Nov 8, 2022

Is all of the above as expected and intentional that riscv64 toolchains emit a lot of .L* symbols in the symtab?

Those .L0 are possible used to make %pcrel_lo linked to the correct %pcrel_hi. If so, then -mno-relax cannot remove them, otherwise relocation will fail.

What should I do to check about assertion? So far I have not seen issues with stripping those from kernel modules, but have not tried the same with userspace binaries yet.

@mtvec
Copy link

mtvec commented Mar 3, 2023

I've noticed that another source of .L0 symbols are relocations in .eh_frame. For example, this file:

f:
    .cfi_startproc
    nop
    .cfi_endproc

Produces the following relocations:

Relocation section '.rela.eh_frame' at offset 0x1b8 contains 3 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000001c  000500000039 R_RISCV_32_PCREL  0000000000000000 .L0  + 0
000000000020  000700000023 R_RISCV_ADD32     0000000000000002 .L0  + 0
000000000020  000500000027 R_RISCV_SUB32     0000000000000000 .L0  + 0

And this adds 2 .L0 symbols:

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
...
     5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 .L0
...
     7: 0000000000000002     0 NOTYPE  LOCAL  DEFAULT    1 .L0
...

The same code on x86 and aarch64 produces a similar relocation but uses section-relative relocation. For example for aarch64:

Relocation section '.rela.eh_frame' at offset 0x140 contains 1 entry:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000001c  000100000105 R_AARCH64_PREL32  0000000000000000 .text + 0

Is this something that could be done on riscv as well?

@andreas-schwab
Copy link

Due to relaxation you do not know the final offset from the section anchor.

@xnox
Copy link
Author

xnox commented Mar 4, 2023

I am very naive and don't understand things.

When i strip locals from my linux kernel modules, they still load and work. What functionality am I missing, or how come they still work? Similarly in userspace as well. Should a linux distribution default to strip-locals on the final linked binaries, libraries, kernel modules if the tool-chain only needs them in the interim and not at runtime? Because I currently strip locals in riscv kernels in Ubuntu itself.

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

No branches or pull requests

7 participants