7

私は strcmp bash ビルトインを書いています。正常にコンパイルされますが、有効にしようとすると、次のようになります。

$ enable -f ./strcmp strcmp
bash: enable: cannot open shared object ./strcmp: ./strcmp: only ET_DYN and ET_EXEC can be loaded

私のビルトインの大きな部分:

strcmp_builtin (list)
WORD_LIST *list;

char *strcmp_doc[] = {
    (char *)NULL
};

struct builtin strcmp_struct = {
    "strcmp", /* builtin name */
    strcmp_builtin, /* function implementing the builtin */
    BUILTIN_ENABLED, /* initial flags for builtin */
    strcmp_doc, /* array of long documentation strings. */
    "strcmp 'string 1' 'string 2'", /* usage synopsis; becomes short_doc */
    0 /* reserved for internal use */
};

コンパイル行 (展開された make ファイルから):

~/bash-4.2/examples/loadables $ gcc -fPIC -DHAVE_CONFIG_H -DSHELL \
-g -O2 -I. -I.. -I../.. -I../../lib -I../../builtins -I../../include \
-I~/bash-4.2 -I~/bash-4.2/lib -I~/bash-4.2/builtins  -c \
-o strcmp strcmp.c

ET_DYN と ET_EXEC をグーグルで検索しましたが、このような質問へのリンクしか見つかりませんでした。

4

3 に答える 3

10

-cフラグに気づきましたか?それはそれがリンクするのを妨げています。-shared@shrが述べたように、それをに置き換えます

于 2011-08-31T04:48:29.017 に答える
7

私の特定の質問 (ET_DYN および ET_EXEC) への回答と、@stanparker の回答が正しい理由の拡張について少しフォローアップします。

ET_DYN と ET_EXEC は ELF 実行可能型です。ELF ヘッダーには、1 つのフィールドElf32_Half e_type、またはElf64_Half e_type複数の ET_* 列挙型がある可能性があります。ETは「実行可能タイプ」、EXEC実行可能およびDYN動的であると推測しています。これはすべて、発行されたアーティファクトが実際にはいかなる種類の実行可能オブジェクトでもないことを示すのに十分なはずであり、GCC フラグを詳しく調べることを奨励する必要がありました。(ELF ヘッダーの詳細については、http://www.sco.com/developers/gabi/1998-04-29/ch4.eheader.html )

リンクしていないことがわかったので、-c フラグを削除しましょう。次に、2 番目のエラー (今回はコンパイルのどこか) が発生します。

$ gcc [...] -o strcmp.o strcmp.c
/usr/lib/gcc/i686-redhat-linux/4.6.0/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/ccaiMtdc.o: In function `strcmp_builtin':
~/bash-4.2/examples/loadables/strcmp.c:32: undefined reference to `make_builtin_argv'
collect2: ld returned 1 exit status

ここには実際には 2 つのエラーがあります。1 つ目は「main への未定義参照」、2 つ目は「make_builtin_argv への未定義参照」(bash 内部関数) です。最後の行は、リンク中に GCC が停止していることを示しています。関数 _start は、glibc によって定義された共通のエントリ ポイントであり、それ自体が実際にプログラム内で main を呼び出します。この時点では、実行可能ファイルではなく、共有ライブラリを作成しています。-sharedコマンドラインに追加すると、完全にコンパイルできます。

では、make が「正しい」コマンド ラインを表示しなかったのはなぜでしょうか。Makefile.in はソース ファイルを動的にテストしないので、手動で .c および .o ターゲットを追加してから、./configure を再実行する必要がありました。そうすることで、

$ make strcmp 
gcc [...] -c -o strcmp.o strcmp.c
gcc -shared -Wl,-soname,strcmp  -L./lib/termcap  -o strcmp strcmp.o 

それは機能しますか?

$ enable -f ./strcmp strcmp
$ strcmp "hi" "ho"
$ echo $?
2
$ strcmp "hi" "ha"
$ echo $?
1
$ strcmp "hi" "hi"
$ echo $?
0

それが私が期待していることなので、うまくいくようです。

とにかく、私がこれを書いているポイントは、私が個人的に GCC と C コンパイル全般でめちゃくちゃになったのはこれが初めてではないということです。誰かが一般的にこれらの問題を抱えているのを見たのはこれが初めてではありません. C コンパイルを成功させるには膨大な量の作業が必要であり、各フェーズが重要です。ですから、GCC (cc、ld、elf ライブラリ) が何をしていたか、あちこちの小さな文字がなぜ重要なのか、全体的な発見プロセスを思い出すためにこれを書いています。私はそれが他のどこにもタイプアップされているのを見たことがないので、ここに私が持っているものがあります.

PS。このビルトインに興味がある方は、私のサイトhttp://davidsouther.com/2011/08/bash-strcmp-builtin/にあります。

于 2011-08-31T14:46:52.503 に答える
2

I'm not sure, but... Ever tried gcc -shared ?

于 2011-08-31T04:38:30.677 に答える