[debian-users 00674] Re: [debian-devel 00351] executable に libm をリンクしなくても数学関数が呼び出せる理由を知りたい。

Yosuke Otsuki y.otsuki30 @ gmail.com
2020年 8月 17日 (月) 01:24:10 JST


OGT 様、Yoshino 様

謎が解けました。ありがとうございました。

On Mon, Aug 17, 2020 at 1:00 AM YOSHINO Yoshihito <yy.y.ja.jp @ gmail.com>
wrote:

> よしのです
> -O0 でもコンパイル時に計算してるらしい
>
> $ echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst
> double d = sqrt(4.0);\nprintf(\"\%lf\\\\n\", d);}" | env
> SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -c -o without_libm.o -xc
> -
> $ echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst
> double d = 2.0;\nprintf(\"\%lf\\\\n\", d);}" | env
> SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -c -o without_libm_2.o
> -xc -
> $ diff -qs without_libm.o without_libm_2.o
> ファイル without_libm.o と without_libm_2.o は同一です
> $
>
> $ echo -e "#include<math.h>\n#include<stdlib.h>\n#include<stdio.h>\nint
> main(int argc, char **argv){\nif (argc < 2) exit(1);\nconst double d =
> sqrt(strtod(argv[1], NULL));\nprintf(\"\%lf\\\\n\", d);}" | env
> SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -o without_libm -xc -
> /usr/bin/ld: /tmp/ccPLXWsj.o: in function `main':
> :(.text+0x38): undefined reference to `sqrt'
> collect2: error: ld returned 1 exit status
> $ echo -e "#include<math.h>\n#include<stdlib.h>\n#include<stdio.h>\nint
> main(int argc, char **argv){\nif (argc < 2) exit(1);\nconst double d =
> sqrt(strtod(argv[1], NULL));\nprintf(\"\%lf\\\\n\", d);}" | env
> SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -o with_libm -xc - -lm
> $ ./with_libm 4.0
> 2.000000
> $ ./with_libm 9.0
> 3.000000
> $
>
> --
> YOSHINO Yoshihito <yy.y.ja.jp @ gmail.com>
>
> On Sun, Aug 16, 2020 at 10:57 PM Yosuke Otsuki <y.otsuki30 @ gmail.com>
> wrote:
> >
> > Debian User と Debian 開発者の皆様
> >
> > お世話になっております。オオツキです。
> > 自分で調査してみましたがわからなかったので、ご存知の方がいらっしゃれば教えていただきたいです。
> >
> > まず、以下の bash script を実行すると、私の環境ではスクリプトに続くようになりました。
> > * run.sh
> > #!/bin/bash
> >
> > dpkg -l | grep gcc
> > dpkg -l | grep binutils
> >
> > echo "=================================="
> > echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst double
> d = sqrt(4.0);\nprintf(\"\%lf\", d);}" > main.c
> > gcc -o without_libm main.c
> > ldd without_libm
> > readelf -a without_libm | grep libm
> > ./without_libm
> > echo "-----------------------------------"
> > gcc -o with_libm main.c -lm
> > ldd with_libm
> > readelf -a with_libm | grep libm
> > ./without_libm
> >
> > * 実行結果
> > + dpkg -l
> > + grep gcc
> > ii  gcc                                  4:8.3.0-1
>      amd64        GNU C compiler
> > ii  gcc-8                                8.3.0-6
>      amd64        GNU C compiler
> > ii  gcc-8-base:amd64                     8.3.0-6
>      amd64        GCC, the GNU Compiler Collection (base package)
> > ii  gccgo-8                              8.3.0-6
>      amd64        GNU Go compiler
> > ii  gccgo-go                             2:1.11~1
>     amd64        Go programming language -- gccgo
> > ii  libgcc-8-dev:amd64                   8.3.0-6
>      amd64        GCC support library (development files)
> > ii  libgcc1:amd64                        1:8.3.0-6
>      amd64        GCC support library
> > ii  linux-compiler-gcc-8-x86             4.19.118-2+deb10u1
>     amd64        Compiler for Linux on x86 (meta-package)
> > + dpkg -l
> > + grep binutils
> > ii  binutils                             2.31.1-16
>      amd64        GNU assembler, linker and binary utilities
> > ii  binutils-common:amd64                2.31.1-16
>      amd64        Common files for the GNU assembler, linker and binary
> utilities
> > ii  binutils-x86-64-linux-gnu            2.31.1-16
>      amd64        GNU binary utilities, for x86-64-linux-gnu target
> > ii  libbinutils:amd64                    2.31.1-16
>      amd64        GNU binary utilities (private shared library)
> > + echo ==================================
> > ==================================
> > + echo -e '#include<math.h>\n#include<stdio.h>\nint main(){\nconst
> double d = sqrt(4.0);\nprintf("\%lf", d);}'
> > + gcc -o without_libm main.c
> > + ldd without_libm
> > linux-vdso.so.1 (0x00007ffc85995000)
> > libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02236d9000)
> > /lib64/ld-linux-x86-64.so.2 (0x00007f02238b7000)
> > + grep libm
> > + readelf -a without_libm
> > + ./without_libm
> > 2.000000+ echo -----------------------------------
> > -----------------------------------
> > + gcc -o with_libm main.c -lm
> > + ldd with_libm
> > linux-vdso.so.1 (0x00007ffec8def000)
> > libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb5a8ff8000)
> > libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb5a8e37000)
> > /lib64/ld-linux-x86-64.so.2 (0x00007fb5a9198000)
> > + grep libm
> > + readelf -a with_libm
> >  0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
> > + ./without_libm
> > 2.000000
> >
> > libm から数学関数の sqrt() を読んでいます。
> >
> > 以前は、libm を明示的にリンクしないと、リンク時にエラーだったと記憶しているのですが、使用した環境ではこのオプションが不要でした。
> > おそらく、自動的に libm がリンクされているのだろうと考えて名前解決がどうなっているのか見てみたところ、オプションを与えない場合
> dyanmic section に libm がありませんでした。
> > libm のリンクを明示的にしない場合、どのようにして sqrt() が呼び出されているのでしょうか?
> >
> > よろしくおねがいします。
> > _______________________________________________
> > debian-devel mailing list
> > debian-devel @ debian.or.jp
> > https://lists.debian.or.jp/mailman/listinfo/debian-devel
>
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <https://lists.debian.or.jp/pipermail/debian-users/attachments/20200817/5986637f/attachment-0001.html>


debian-users メーリングリストの案内