0

次のように、インライン アセンブリを使用して sys_unlink を呼び出そうとしています。

 int sys_unlink(const char *filename) {

    int ret;

    __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));

    return ret;

}

しかし、それは機能しません。常に -14 を返します。

私はアセンブリについてあまり知らないので、このコードが正しいかどうか知りたいです。

4

2 に答える 2

3

このコードは、x86 (32 ビット) プロセスに対してのみ正しいものです。x86-64 プロセスに対して正しいシステムコール番号を使用していません。ハードコーディングされた の代わりに__NR_unlinkfromを使用します。asm/unistd.h10

#include <asm/unistd.h>

int sys_unlink(const char *filename)
{
    int ret;

    asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
    return ret;
}

32 ビット プロセスをコンパイルしている場合-14でありEFAULT、渡すファイル名に問題があることを示しています。どのように呼んでいますか?

于 2011-01-01T03:24:02.187 に答える
3

これを Linux の単一プラットフォームに限定して動作させることはできないと思います: Linux が syscall を作成する最新の方法は、カーネルによって提供され、VDSO 経由でリンクされたスタブを使用することです。リンクしている libc でさえ、システム コール規則が何であるかを知りません (知る必要はありません)。VDSO から参照を取得するだけです。直後に隠されている魔法のパラメーターを介して VDSO への参照を取得し、environ他の動的ライブラリと同様に扱います。カーネルは、CPU の機能に基づいてシステム コール規則を選択します。

これらの VDSO シンボルにアクセスするのは難しいことを (私がやろうとしたので!) たまたま知っています。glibc はそれら (またはそれらへの有用なハンドル) をエクスポートしません。私が見た唯一の実行可能な方法は、自分自身/proc/self/mapsを調べて VDSO を見つけ、dl関数を使用してそれを取得することでした (glibc セットアップ作業の一部を繰り返します)。

于 2011-01-01T03:47:46.857 に答える