问题标签 [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.
c - 指向 amd64 ABI 中的 va_list 的指针
我担心 Linux amd64 (x86_64) 下的可变参数函数。
我的示例在 linux i386 (ia32) 上构建和工作正常,但是在为 linux amd64 构建时,GCC 会产生这样的错误:
这里的例子:
根据C11 草案( ISO/IEC 9899:2011 )
对象 ap 可以作为参数传递给另一个函数;如果该函数调用带有参数 ap 的 va_arg 宏,则调用函数中 ap 的值是不确定的,应在进一步引用 ap 之前将其传递给 va_end 宏。
但后者添加
允许创建指向 va_list 的指针并将该指针传递给另一个函数,在这种情况下,原始函数可以在其他函数返回后进一步使用原始列表。
我不清楚AMD 64 ABI是否在标准上是错误的。
将函数更改为vtest()
在第一次调用时使用指针可以解决问题,但是让内部函数中不起作用的东西实际上在外部函数中起作用感觉是错误的。
如果有人可以找到 AMD64 ABI 行为是否符合标准的地方。对于向我提供其他 ABI 与 stdarg 使用(相同)问题的人的附加点。
问候
gcc - GCC 和 LLVM 之间的兼容性
我正在开发一个跨平台的项目,在 OS X 上,必须使用 clang/llvm 构建一个部分,因为它创建了一个 Cocoa 窗口,该项目的其余部分是使用 GCC 构建的。这被编译成一个静态库,该库链接到主可执行文件。例如
我正在使用 CMake 生成生成文件。我尝试了几组不同的编译器标志-fPIC
等。但我得到的值打印为 1835455280、1746993968、1648001840。这两个编译器不应该是二进制兼容的吗?如果我使函数无效,那么它就可以正常工作。
visual-studio-2010 - 如何让 MS Visual C++ 使用 LP64 而不是 LLP64
我想知道是否可以使用 VC++LP64
代替LLP64
,我知道我可以使用其他编译器,例如 GCC 或 Intel C++,但出于各种原因我想使用 VC++。
不需要与 Microsoft 标头等兼容,我已经在使用 LIBC 作为我的运行时库。
android - Android 4.0.3(MIUI ROM)下未加载本机库
一位客户联系了我——我的一个 Android 应用程序在他将他的 Android ROM 更新到相当于 Android 4.0.3 的 MIUI 后就崩溃了。LogCat 中的相关行是:
不用说,该应用程序在升级之前就可以运行。所以原生库并没有神奇地消失。任何想法为什么Android 4.0.3会拒绝加载早期版本的本机库?该库是为 x86 和armeabi
(armeabi-v7a
虽然不是)而构建的。崩溃报告包含以下几行:
所以armeabi
应该支持吧?
可能的相关信息:这里。但是错误中的情况与我在这里得到的相反。
c++ - 枚举和枚举类的链接兼容性
假设有一个使用枚举类的 C++11 API:
现在假设我想使用这个 API,但我没有 C++11 编译器。所以我:
- 修改
api.hpp
枚举类并将其更改为常规枚举。 - 编写一些包含修改后的代码代码
api.hpp
并正常使用API(例如调用f
)。 - 使用我的非 C++11 编译器编译此代码,并将其链接到使用 C++11 编译器编译的 API 实现(使用未修改的
api.hpp
)。
这似乎适用于 GCC,但总的来说它是安全的,还是我在玩火(违反 ODR 等)?
假设这两个编译器在其他方面是链接兼容的,那么只有 enum 与 enum 类有问题。
c++ - 在独立类中重新排序公共非虚拟方法是否会破坏 ABI?
更改独立类中公共非虚拟非内联重载方法的顺序是否会破坏 ABI?
前:
后:
谢谢!
c++ - vtables 和 this 指针
我试图了解更多关于 vtables 和 vpointers 的内部工作原理,所以我决定尝试使用一些技巧直接访问 vtable。我创建了两个类,Base
每个Derv
都有两个virtual
函数(Derv
覆盖那些Base
)。
现在,编译器为每个类添加一个 vtable 指针,占用内存中的前 4 个字节(32 位)。我通过将对象的地址转换为 a 来访问该指针size_t*
,因为该指针指向另一个大小为 的指针sizeof(size_t)
。现在可以通过索引 vpointer 并将结果转换为适当类型的函数指针来访问虚函数。我将这些步骤封装在一个函数中:
当以这种方式调用其中一个成员函数时,例如call(new Base(1, 2), 0)
调用 Base::foo(),很难预测会发生什么,因为它们是在没有this
-pointer 的情况下调用的。我通过添加一个小模板化函数解决了这个问题,知道 g++ 将this
-pointer 存储在ecx
寄存器中(但这迫使我使用编译-m32
器标志进行编译):
取消注释setThisPtr(ptr)
上面代码段中的行现在使它成为一个工作程序:
我决定分享这个,因为在编写这个小程序的过程中,我对 vtables 的工作原理有了更多的了解,它可能有助于其他人更好地理解这些材料。但是我还有一些问题:
1. 编译 64 位二进制文件时使用哪个寄存器(gcc 4.x)来存储 this 指针?我尝试了这里记录的所有 64 位寄存器:http: //developers.sun.com/solaris/articles/asmregs.html
2. this-pointer 何时/如何设置?我怀疑编译器会通过一个对象在每个函数调用上设置 this 指针,就像我刚刚做的那样。这是多态性实际工作的方式吗?(通过先设置 this 指针,然后从 vtable 调用虚函数?)。
c++ - G++ ABI compatibility list
I have compiled my preload file on Ubuntu server (two files for x32 and x64). Where I can get list, in which I will see with what OS my compiled files are compatible and with what I should recompile for compatibility?
Thanks!
c++ - 关于修改虚拟表绕行的问题
我一直在使用与 Microsoft Detours 相同的方法练习 detours(将前五个字节替换为 jmp 和地址)。最近,我一直在阅读有关通过修改虚拟表来绕行的信息。如果有人能通过提及与前面提到的方法相比的一些优点和缺点来阐明这个主题,我将不胜感激!
我还想询问有关堆栈上已修补的 vtable 和对象的信息。考虑以下情况:
在这种情况下foo->Call()
,最终会在调用原始函数(即方法)MyCall(Foo * object)
时调用。这是因为如果可能,编译器将尝试在编译期间决定任何虚拟调用(如果我错了,请纠正我)。这是否意味着您是否修补虚拟表并不重要,只要您使用堆栈上的对象(不是堆分配的)?foo2.Call()
Foo::Call(void)
c - sizeof(long long) != 8 的架构/ABI
在 x86/amd64 中,世界sizeof(long long)
是 8。
让我引用扎克·温伯格(Zack Weinberg)颇有见地的 8 年邮件:
斯科特·罗伯特·拉德写道:
在 64 位 AMD64 架构上,GCC 定义
long long
为 64 位,与long
.
long long
鉴于某些 64 位指令(乘法)产生 128 位结果,将其定义为 128 位似乎不合逻辑吗?不,有两个原因:
long long
大多数 LP64 型号操作系统的 ABI 中都写入了64 位 ' ' 的选择;我们不能单方面改变它。这实际上是正确的选择,因为它消除了使 '
long
' 不是最广泛的基本整数类型的像差。在野外有很多代码是为了假设sizeof(long) >= sizeof(size_t)
- 这至少可能被 ABI 破坏,其中 long long 比 long 更宽。(在 C99 的开发过程中这是一个非常有争议的话题。据我所知,从外部角度来看,“
long long
”只是由于微软的压力而被标准化,微软由于某种原因无法实现 LP64 模型。其他人都讨厌使 'long
' 不一定是最广泛的基本整数类型的想法。)当前的最佳做法似乎是提供“扩展整数类型”
__int128
。这不存在 'long long
' 的问题,因为它不是基本的整数类型(特别是不能用于size_t
)。zw
long long
是最宽的基本整数类型。在我知道的任何非死旧架构/ABI 上,它都是 64 位长的。这允许使用简单的跨平台(嗯,至少对于许多 32/64 位架构)类型定义:
比 更好intXX_t
,因为:
- 他们在不同平台上对 64 位整数使用相同的底层类型
- 允许避免冗长的
PRId64
/PRIu64
(我很清楚 Visual C++ 支持%lld
/%llu
仅自 2005 年起)
但是这个解决方案的可移植性可以通过以下问题的答案来表达。
什么是架构/ABI sizeof(long long) != 8
?
如果您不能提供任何最近/现代的,那么请继续使用旧的,但前提是它们仍在使用中。