問題タブ [abi]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
1701 参照

c - amd64ABIのva_listへのポインター

Linux amd64(x86_64)での可変個引数関数について懸念があります。

私の例はLinuxi386(ia32)で正常にビルドおよび動作しますが、Linux amd64用にビルドすると、GCCは次のようなエラーを生成します。

ここに例があります:

C11ドラフトISO / IEC 9899:2011)によると

オブジェクトapは、引数として別の関数に渡すことができます。その関数がパラメーターapを使用してva_argマクロを呼び出す場合、呼び出し元の関数のapの値は不確定であり、apをさらに参照する前にva_endマクロに渡される必要があります。

しかし、後者は追加します

va_listへのポインターを作成し、そのポインターを別の関数に渡すことは許可されています。この場合、元の関数は、他の関数が戻った後、元のリストをさらに使用できます。

ここでAMD64ABIが標準と見なされて間違っているかどうかは、私にはわかりません。

vtest()最初の呼び出しでポインターを使用するように関数を変更すると問題は解決しますが、内部関数で機能しないものが実際に外部関数で機能するのは間違っていると感じます。

AMD64 ABIの動作が標準に一致している場合、誰かがどこかを見つけることができれば。stdargの使用に関する(同じ)問題を他のABIに提供してくれる人のための追加のポイント。

よろしく

0 投票する
1 に答える
1239 参照

gcc - GCC と LLVM の互換性

私はクロスプラットフォームのプロジェクトに取り組んでおり、OS X では Cocoa ウィンドウを作成するため、clang/llvm で 1 つのセクションをビルドする必要があり、プロジェクトの残りの部分は GCC でビルドされます。これは、メインの実行可能ファイルにリンクされている静的ライブラリにコンパイルされます。例えば

CMake を使用して makefile を生成しています。コンパイラ フラグなどのいくつかの異なるセットを試しましたが-fPIC、値が 1835455280、1746993968、1648001840 のように出力されます。2 つのコンパイラはバイナリ互換ではないのでしょうか? 関数を無効にすると、問題なく動作します。

0 投票する
2 に答える
1345 参照

visual-studio-2010 - MS Visual C++ で LLP64 の代わりに LP64 を使用する方法

GCC や Intel C++ などの別のコンパイラを使用できることはわかっていますが、さまざまな理由で VC++ を使用したいと考えていLP64ます。LLP64

Microsoft ヘッダーなどとの互換性に関する要件はなく、ランタイム ライブラリとして LIBC を既に使用しています。

0 投票する
0 に答える
544 参照

android - Android 4.0.3(MIUI ROM)でネイティブライブラリが読み込まれない

顧客から連絡がありました。AndroidROMをAndroid4.0.3と同等のMIUIに更新すると、私のAndroidアプリが壊れました。LogCatの関連行は次のとおりです。

言うまでもなく、このアプリはアップグレード前に機能していました。したがって、ネイティブライブラリが魔法のように失われることはありませんでした。Android 4.0.3が以前のバージョンのネイティブライブラリの読み込みを拒否する理由はありますか?ライブラリはx86用に構築されていますarmeabi(ただし、そうではありませんarmeabi-v7a)。クラッシュレポートには次の行が含まれています。

だからarmeabiサポートされるべきですよね?

おそらく関連情報:ここ。しかし、バグの状況は、私がここで得たものの逆です。

0 投票する
2 に答える
701 参照

c++ - 列挙型と列挙型クラスのリンク互換性

列挙型クラスを使用するC++11APIがあるとします。

ここで、このAPIを使用したいとしますが、C++11コンパイラーを持っていません。だから私:

  • 列挙api.hpp型クラスを変更して、通常の列挙型に変更します。
  • api.hpp変更されたものを含み、APIを通常どおりに使用するコードコードを記述します(例:呼び出しf)。
  • このコードをC++11以外のコンパイラでコンパイルし、C ++ 11コンパイラでコンパイルされたAPI実装にリンクします(変更されていないものを使用api.hpp)。

これはGCCで機能するようですが、一般的には安全ですか、それとも私は火遊びをしていますか(ODR違反など)?

2つのコンパイラがリンク互換であると仮定すると、問題となるのはenumクラスとenumクラスだけです。

0 投票する
2 に答える
387 参照

c++ - スタンドアロン クラスで public 非仮想メソッドを並べ替えると、ABI が壊れますか?

スタンドアロン クラスでオーバーロードされたパブリックで非仮想の非インライン メソッドの順序を変更すると、ABI が壊れますか?

前:

後:

ありがとう!

0 投票する
1 に答える
2403 参照

c++ - vtablesとこのポインタ

私はvtablesとvpointersの内部動作についてもう少し学ぼうとしていたので、いくつかのトリックを使用してvtableに直接アクセスすることにしました。私は2つのクラスを作成BaseDerv、それぞれに2つのvirtual関数があります(の関数DervをオーバーライドしますBase)。

ここで、コンパイラは各クラスにvtableポインタを追加し、メモリの最初の4バイト(32ビット)を占有します。size_t*ポインタがサイズの別のポインタを指しているため、オブジェクトのアドレスをにキャストしてこのポインタにアクセスしましたsizeof(size_t)。これで、vpointerにインデックスを付け、その結果を適切なタイプの関数ポインターにキャストすることで、仮想関数にアクセスできます。これらのステップを関数にカプセル化しました。

メンバー関数の1つがこのように呼び出された場合、たとえばcall(new Base(1, 2), 0)Base :: foo()を呼び出す場合、ポインターなしで呼び出されるため、何が起こるかを予測することは困難thisです。thisg ++がレジスタに-pointerを格納することを知って、少しテンプレート化された関数を追加することでこれを解決しました(ただし、これにより、コンパイラフラグecxを使用してコンパイルする必要があります)。-m32

setThisPtr(ptr)上記のスニペットの行のコメントを解除すると、プログラムとして機能するようになります。

この小さなプログラムを書く過程で、vtablesがどのように機能するかについてより多くの洞察を得て、他の人がこの資料をもう少しよく理解するのに役立つかもしれないので、これを共有することにしました。ただし、まだいくつか質問があります
。1. 64ビットバイナリをコンパイルするときにthis-pointerを格納するために使用されるレジスタ(gcc 4.x)はどれですか。ここに記載されているように、すべての64ビットレジスタを試しました。http://developers.sun.com/solaris/articles/asmregs.html
2. this-pointerはいつ/どのように設定されますか?コンパイラは、オブジェクトを介した各関数呼び出しで、これを行ったのと同じようにthisポインタを設定していると思います。これはポリモーフィズムが実際に機能する方法ですか?(最初にthis-pointerを設定してから、vtableから仮想関数を呼び出しますか?)

0 投票する
3 に答える
613 参照

c++ - G++ABI互換性リスト

プリロードファイルをUbuntuサーバーにコンパイルしました(x32とx64の2つのファイル)。コンパイルされたファイルがどのOSと互換性があり、互換性のために何を再コンパイルする必要があるかを確認できるリストはどこで入手できますか?

ありがとう!

0 投票する
2 に答える
256 参照

c++ - 仮想テーブルの変更による迂回に関する質問

Microsoft Detours と同じアプローチを使用して迂回を練習してきました (最初の 5 バイトを jmp とアドレスに置き換えます)。最近、仮想テーブルを変更して迂回することについて読んでいます。前述の方法と比較して、この方法の長所と短所をいくつか挙げて、誰かがこの問題に光を当てることができれば幸いです!

また、パッチを適用した vtable とスタック上のオブジェクトについてもお尋ねしたいと思います。次の状況を考慮してください。

この場合、元の関数 (つまりメソッド)foo->Call()を呼び出しMyCall(Foo * object)ながら呼び出すことになります。これは、可能な場合、コンパイラがコンパイル時に仮想呼び出しを決定しようとするためです (間違っている場合は修正してください)。スタック上のオブジェクトを使用する限り (ヒープが割り当てられていない場合)、仮想テーブルにパッチを適用するかどうかは問題ではないということですか?foo2.Call()Foo::Call(void)

0 投票する
2 に答える
1000 参照

c - sizeof(long long)!=8のアーキテクチャ/ABI

x86/amd64では世界sizeof(long long)は8です。

ZackWeinbergによる非常に洞察に満ちた8年前のメールを引用させてください。

スコットロバートラッドは書いています:

64ビットAMD64アーキテクチャでは、GCCはとlong long同じ64ビットとして定義しlongます。

特定の64ビット命令(乗算)が128ビットの結果を生成することを考えるとlong long、128ビットとして定義するのは論理的ではないでしょうか。

いいえ、2つの理由があります。

  1. 64ビット' long long'の選択は、ほとんどのLP64モデルオペレーティングシステムのABIに書き込まれています。一方的に変更することはできません。

  2. これは実際には正しい選択です。これは、' long'を最も広い基本積分タイプではないものにする収差を除去するためです。sizeof(long) >= sizeof(size_t)これは、longlongがlongよりも幅が広いABIによって少なくとも潜在的に破壊されるという仮定に基づいて書かれたコードがたくさんあります 。

    (これはC99の開発中に非常に論議を呼んだトピックでした。外部の観点から言えば、' long long'は、何らかの理由でLP64モデルを実装できないMicrosoftからの圧力により、標準化されただけです。他の誰もが嫌いでした。 ''を作成するという考えは、long必ずしも最も広い基本的な積分型ではありません。)

現在のベストプラクティスは、「拡張積分タイプ」を提供することであるように思われます__int128これは基本的なlong long積分型ではないため、''の問題はありません(特に、には使用できません )。size_t

zw


long long最も幅の広い基本一体型です。私が知っている古いアーキテクチャ/ABI以外のアーキテクチャでは64ビット長です。これにより、単純なクロスプラットフォーム(少なくとも多くの32/64ビットアーキテクチャでは)typedefを使用できます。

それは、よりも優れていますintXX_t。理由は次のとおりです。

  • 異なるプラットフォームの64ビット整数に同じ基になる型を使用します
  • PRId64冗長な/を回避できます(Visual C ++が/をサポートしているのは2005年以降PRIu64
    であることをよく知っています)%lld%llu

しかし、このソリューションがどれほど移植性があるかは、次の質問への回答で表すことができます。


アーキテクチャ/ABIはどこにありsizeof(long long) != 8ますか?

最近/最新のものを提供できない場合は、古いものを使用してください。ただし、それらがまだ使用されている場合に限ります。