Diferența dintre stegulețele linkerului (Unix, Linux, Kernel Linux, Gcc, Linker, G++)

Jaya Kommuru a intrebat.

Adăugam suport pentru timp de execuție c++ și excepții în kernelul Linux. Pentru aceasta, trebuie să furnizez propriul meu lib/gcc și lib/libstdc++în loc de bibliotecile standard furnizate de compilator.

Așadar, sunt confuz în ceea ce privește steagurile care trebuie trecute către linker. Într-un Makefile de nivel superior al unui kernel normal, LD = $(CROSS_COMPILE)ld care permite nucleului să utilizeze bibliotecile standard și fișierele de pornire implicite. Pentru kernelul meu folosesc LD = $(CROSS_COMPILE)ld -nostdlib -nodefaultlibs -nostartfiles așa cum se spune într-o documentație. Ceea ce am înțeles din documentația gcc este că trecerea -nostdlib către linker este aceea de a trece atât -nodefaultlibs -nostartfiles. Care este de fapt diferența dintre aceste stegulețe?

1 răspunsuri
Stephen Kitt

Aceste stegulețe sunt definite în fișierele de specificații ale GCC, așa că cel mai bun mod de a determina diferențele dintre ele este să te uiți acolo:

gcc -dumpspecs

Partea relevantă este link_command definiție. Aceasta arată că -nostdlib, -nodefaultlibs și -nostartfiles au următorul impact:

  • %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} – aceasta adaugă libgcc, libpthread, libc, libieee după cum este necesar, utilizând un macro și lib și libgcc șiruri de specificații;
  • %{!nostdlib:%{!nostartfiles:%S}} – aceasta adaugă startfile spec string, , care specifică fișierele obiect care trebuie adăugate pentru a gestiona pornirea (crti.o etc.)
  • %{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end} %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}} – se adaugă verificarea tabelelor virtuale folosind libvtv
  • %{!nostdlib:%{!nodefaultlibs:%{mmpx:%{fcheck-pointer-bounds: %{static:--whole-archive -lmpx --no-whole-archive %:include(libmpx.spec)%(link_libmpx)} %{!static:%{static-libmpx:-Bstatic --whole-archive} %{!static-libmpx:--push-state --no-as-needed} -lmpx %{!static-libmpx:--pop-state} %{static-libmpx:--no-whole-archive -Bdynamic %:include(libmpx.spec)%(link_libmpx)}}}}%{mmpx:%{fcheck-pointer-bounds:%{!fno-chkp-use-wrappers: %{static:-lmpxwrappers} %{!static:%{static-libmpxwrappers:-Bstatic} -lmpxwrappers %{static-libmpxwrappers: -Bdynamic}}}}}}} – aceasta se ocupă de libmpx
  • %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address): %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)} %{static:%ecannot specify -static with -fsanitize=address}} %{%:sanitize(thread): %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)} %{static:%ecannot specify -static with -fsanitize=thread}} %{%:sanitize(undefined):%{static-libubsan:-Bstatic} -lubsan %{static-libubsan:-Bdynamic} %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}} %{%:sanitize(leak): %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}}}} – gestionează diferitele opțiuni de igienizare
  • %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} – adaugă opțiunile de protecție a stivei și repetă secvența de legătură C (ale cărei biblioteci au fost deja specificate la început)
  • %{!nostdlib:%{!nostartfiles:%E}} – se adaugă opțiunea endfile șirul spec, care specifică fișierele obiect care trebuie adăugate pentru a gestiona resturile (crtfastmath.o, crtend.o etc.)

După cum ați înțeles din documentație, -nostdlib este un supraansamblu de -nodefaultlibs și -nostartfiles. De asemenea, dezactivează verificarea tabelelor virtuale.

Așadar, -nostdlib este suficient pentru a dezactiva toate caracteristicile aferente; -nodefaultlibs și -nostartfiles nu adăugați nimic la aceasta. (Dar nu strică să le menționați și pe acestea).

Comentarii

  • OK, am înțeles. Dar nu pot să înțeleg de ce se produce o nealiniere a segmentelor de încărcare ale vmlinux atunci când linia LD = $(CROSS_COMPILE)ld -nostdlib este schimbată în LD = $(CROSS_COMPILE)ld -nostdlib -nodefaultlibs -nostartfiles. În loc să se alinieze la un mutiplu de 2MB, se aliniază la 1KB sau ceva de genul ăsta. –  > Por Jaya Kommuru.