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