On Sat, Nov 06, 2021 at 03:20:03PM +0100, Sebastien Marie wrote:
> Hi,
> 
> aja@ shows me some problems with x11/gnome/librsvg update (the port is
> Rust based), and I finally tracked the problem inside nm(1).
> 
> I will not speak of Rust anymore, and will use only C for the example.
> 
> When an object is compiled using -ffunction-sections, the
> compiler/linker will use one section per function (if I correctly
> understood the usual purpose, it is to be able to easily discard
> unused sections/functions at linking time).
> 
> $ cat test.c
> #include <stdio.h>
> 
> void
> test_fn(void)
> {
>       printf("test_fn()\n");
> }
> 
> $ cc -Wall -c test.c -ffunction-sections
> $ readelf --sections test.o | grep -A1 test_fn
>   [ 3] .text.test_fn     PROGBITS         0000000000000000  00000040
>        0000000000000040  0000000000000000  AX       0     0     16
> $ readelf -s test.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 test.c
>      2: 0000000000000000    11 OBJECT  LOCAL  DEFAULT    7 .L.str
>      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
>      4: 0000000000000000    24 FUNC    WEAK   HIDDEN     6 
> __llvm_retpoline_r11
>      5: 0000000000000000     8 OBJECT  WEAK   HIDDEN     9 __retguard_759
>      6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
>      7: 0000000000000000    64 FUNC    GLOBAL DEFAULT    3 test_fn
>                                          
> 
> The problem is nm(1) doesn't recognize the test_fn type as a TEXT function:
> 
> $ nm test.o
> 00000000 d .L.str
> 00000000 W __llvm_retpoline_r11
> 00000000 W __retguard_759
>          U printf
> 00000000 F test.c
> 00000000 ? test_fn
> 
> test_fn symbol should be 'T', but it is reported as '?'.
> 
> 
> llvm-nm(1) is working correctly (but we don't have it in base):
> 
> $ llvm-nm test.o
> 0000000000000000 r .L.str
> 0000000000000000 W __llvm_retpoline_r11
> 0000000000000000 V __retguard_759
>                  U printf
> 0000000000000000 T test_fn
>                
> 
> 
> The following diff makes nm(1) to properly mark the function 'T', by
> recognize ".text.*" sections:
> 
> diff cecccd4b3c548875286ca2b010c95cbce6c0e359 /home/semarie/repos/openbsd/src
> blob - 5aeef7a01a7cbff029299cfc5562cfcec085347f
> file + usr.bin/nm/elf.c
> --- usr.bin/nm/elf.c
> +++ usr.bin/nm/elf.c
> @@ -274,6 +274,8 @@ elf_shn2type(Elf_Ehdr *eh, u_int shn, const char *sn)
>                       return (-1);
>               else if (!strcmp(sn, ELF_TEXT))
>                       return (N_TEXT);
> +             else if (!strncmp(sn, ".text.", 6))
> +                     return (N_TEXT);
>               else if (!strcmp(sn, ELF_RODATA))
>                       return (N_SIZE);
>               else if (!strcmp(sn, ELF_OPENBSDRANDOMDATA))
> @@ -355,6 +357,7 @@ elf2nlist(Elf_Sym *sym, Elf_Ehdr *eh, Elf_Shdr *shdr, 
>               } else if (sn != NULL && *sn != 0 &&
>                   strcmp(sn, ELF_INIT) &&
>                   strcmp(sn, ELF_TEXT) &&
> +                 strncmp(sn, ".text.", 6) &&
>                   strcmp(sn, ELF_FINI))       /* XXX GNU compat */
>                       np->nl.n_other = '?';
>               break;
> 
> The change on elf_shn2type() isn't strictly necessary for my use-case,
> but it (should) makes .text.* support better (recognize N_TEXT for
> STT_NOTYPE, STT_OBJECT, STT_TLS).
> 
> 
> After, nm(1) properly recognize the symbol:
> 
> $ /usr/obj/usr.bin/nm/nm test.o
> 00000000 d .L.str
> 00000000 W __llvm_retpoline_r11
> 00000000 W __retguard_759
>          U printf
> 00000000 F test.c
> 00000000 T test_fn
> 
> and it makes libtool(1) happy (LT/Archive.pm: get_symbollist
> function), and it makes librsvg build happy (which is playing with
> symbols at build time), and it should makes aja@ happy too.
> 
> Comments or OK ?

You made me happy :-)

-- 
Antoine

Reply via email to