标签: abi

FreeBSD/amd64 程序集 - 如何从 _start 读取“ARGC”?

argc有时返回正确的值,有时返回 0,有时返回(看似)随机数……所有这些都来自同一个可执行文件。

.section .text
.global _start
_start:
    movq    $1, %rax
    popq    %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

例如:

%as -o this.o this.s ; ld -o this this.o

%./this; echo $?
1

%./this 1; echo $?
0

%./this 1 2; echo $?
3

%./this 1 2 a; echo $?
4

%./this 1 2 a f; echo $?
0

%_
Run Code Online (Sandbox Code Playgroud)

我对汇编有点陌生,但我非常有信心获取参数计数就像在 Linux 中将其从堆栈中弹出一样简单,其中 System V ABI 记录 RSP 在argcexecve进程中指向的内容。

是我做错了什么,还是事情真的很糟糕?

assembly freebsd x86-64 abi argc

6
推荐指数
1
解决办法
776
查看次数

使用_GLIBCXX_CXX11_ABI使用带有C++ 11/14功能的5.1之前的C++ ABI有什么影响?

手册:

在GCC 5.1版本中,libstdc ++引入了一个新的库ABI,其中包括std :: string和std :: list的新实现.这些更改对于符合2011 C++标准是必要的,该标准禁止写入时写入字符串并要求列表跟踪其大小.

可以使用_GLIBCXX_USE_CXX11_ABI宏来控制库标头使用旧的或新的ABI,而不管使用哪个"-std".

我想知道使用这种"兼容性ABI"的含义是什么?我猜小串操作的运行时性能会受到影响(我假设是负面的),并且列表大小访问从O(1)(C11 ABI)到O(N)(兼容性ABI).

  1. 我的猜测是否正确,任何人都可以详细说明吗?
  2. 我错过了其他影响吗?原子和并发功能怎么样?有什么影响?

c++ gcc abi

6
推荐指数
1
解决办法
225
查看次数

通过 cmake 链接 libc++ 时 libc++abi 的链接问题

我正在尝试C++使用 LLVM/Clang 3.7.0 构建一个简单的(“hello world”)程序,该程序是根据工具链的源代码构建的libc++,使用命令行:

\n\n
clang++ -std=c++14 -stdlib=libc++ -fno-exceptions hello.cpp\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,我收到以下错误:

\n\n
/usr/bin/ld: warning: libc++abi.so.1, needed by /bulk/workbench/llvm/3.7.0\n/toolchain4/bin/../lib/libc++.so, not found (try using -rpath or -rpath-link)\n/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_rethrow_primary_exception\'\n/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_decrement_exception_refcount\'\n/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `std::out_of_range::~out_of_range()\'\n[...]\n
Run Code Online (Sandbox Code Playgroud)\n\n

LD_LIBRARY_PATH设置工具链的安装目录已添加到我的工作中PATH中:

\n\n
export PATH=$PATH:/bulk/workbench/llvm/3.7.0/toolchain4/bin/\n
Run Code Online (Sandbox Code Playgroud)\n\n

我上线了Ubuntu GNU/Linux 14.04,并且尚未从任何存储库安装任何 LLVM 或 Clang 相关的软件包。

\n\n

根据libc++ 文档

\n\n
\n

在 Linux 上,libc++ 通常只能与 \xe2\x80\x98-stdlib=libc++\xe2\x80\x99 一起使用。然而,某些 libc++ 安装需要用户自己手动链接 libc++abi。如果在使用 …

linker abi llvm clang libc++

6
推荐指数
0
解决办法
2365
查看次数

什么真的是什么意思?

我比较了返回结构的2个C函数.我们知道在ABI级别上,大型结构将被指针作为第一个函数参数传递.

struct S {
    int words[8];
};

struct S fsret() {
    struct S s;
    s.words[0] = 1;
    return s;
}

void fout(struct S* s) {
    s->words[0] = 1;
}
Run Code Online (Sandbox Code Playgroud)

对于这些函数,我检查了x86_64 Linux和Windows的程序集.该fsret声明为void @fsret(%struct.S* sret %s).

比较这两种变体,被叫方没有区别.但是,在函数内部,fsret另外将其第一个参数(指向结构的指针)复制到RAX寄存器.为什么?

c abi llvm

6
推荐指数
1
解决办法
191
查看次数

即使没有其他必要,合法的结语是否需要包括虚拟 rsp 调整?

该X86-64的Windows ABI有一个概念合法收尾,这是可以的功能收尾的一种特殊类型的模拟异常处理过程中,以恢复呼叫者上下文1所描述的在这里

如果 RIP 在一个结语内 [当异常发生时],那么控制正在离开函数,...并且结语的影响必须继续计算调用者函数的上下文。为了确定 RIP 是否在结语内,检查从 RIP 开始的代码流。如果该代码流可以与合法结语的尾随部分匹配,则它在结语中,结语的其余部分被模拟,上下文记录随着每条指令的处理而更新......

您可以在此处找到对合法结语 的散文描述,其中包括以下示例:

如果函数中未使用帧指针,则结语必须首先释放堆栈的固定部分,弹出非易失性寄存器,并将控制权返回给调用函数。例如,

add      RSP, fixed-allocation-size  
pop      R13  
pop      R14  
pop      R15  
ret
Run Code Online (Sandbox Code Playgroud)

它包含一个类似的示例,lea用于在使用帧指针时恢复堆栈。

但是,如果函数内根本没有固定大小的分配怎么办?函数不使用堆栈的情况并不少见。add rsp, 0在这种情况下是否需要插入一个哑元以符合合法结语的规则,还是可以省略?


1例如,恢复可能被调用者破坏的非易失性寄存器。

windows exception x86-64 abi seh

6
推荐指数
0
解决办法
92
查看次数

Solidity如何使用元组(嵌套abi)进行函数签名?

struct Test {
  uint ui;
  string s;
}
function test(Test t) public {
  emit Log(t.ui, t.s);
}
Run Code Online (Sandbox Code Playgroud)

我对ABI有一些了解。我使用实验性 ABIEncoderV2 选项签订了这份合同。总之,这个函数的签名是0x6056f4cc,我在操作码中找到了这个值。我用 sha3 尝试了一些 case test(uint256,string), test(tuple(uint256,string)), test(tuple), test(tuple[uint256,string])) ...但没有人做出正确的签名。Solidity 如何使用元组进行函数签名?

abi solidity

6
推荐指数
1
解决办法
3709
查看次数

EnableABIBreakingChecks 上的编译失败

我最近安装了 LLVM v8.0.0(在 RHEL 7.4 上)。我正在阅读LLVM Kaleidoscope 教程以了解如何使用该系统,但遇到了链接问题。

根据教程(第 2 章结尾),我运行:

clang++ -g -O3 kld.cpp `llvm-config --cxxflags` -o kld
Run Code Online (Sandbox Code Playgroud)

它编译,但链接器失败:

/tmp/kld-f7264f.o:(.data+0x0): undefined reference to `llvm::EnableABIBreakingChecks'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

我怀疑这可能是 的问题llvm-config,所以我也尝试使用--ldflags--system-libs标志,但没有运气。

llvm-config --cxxflags 给出(重新格式化以提高可读性)

-I~/project/llvm-src/include -I~/project/llvm-build/include 
-fPIC -fvisibility-inlines-hidden
-std=c++11
-Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-g 
-fno-exceptions -fno-rtti
-D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
Run Code Online (Sandbox Code Playgroud)

哪里~/... …

abi llvm llvm-clang llvm-c++-api

6
推荐指数
3
解决办法
2188
查看次数

在使用栈方面,为什么需要基指针和栈指针

无论如何,就 x86 汇编代码而言。我一直在阅读有关函数调用的内容,但仍然无法完全掌握对基/帧指针 (EBP) 和堆栈指针 (ESP) 的需求。

当我们调用一个函数时,EBP的当前值会被放入栈中,然后EBP获取当前的ESP值。

函数的返回值、函数参数和局部变量的占位符然后将被放置在堆栈中,并且堆栈指针 ESP 值将减少(或增加)指向放置在堆栈上的最后一个占位符之后。

现在我们让 EBP 指向当前堆栈帧的开头,而 ESP 指向堆栈帧的结尾。

由于与 EBP 的恒定偏移量,EBP 将用于访问函数的参数和局部变量。那没关系。我不明白的是,为什么 ESP 不能通过使用其偏移量来访问这些变量。EBP指向栈帧的开头,ESP指向栈帧的结尾。有什么不同?

一旦所有局部变量等有了占位符,ESP 就不应该改变,还是应该改变?

c x86 assembly stack abi

6
推荐指数
1
解决办法
533
查看次数

堆栈何时增长?操作系统如何知道何时增长堆栈?

注意:这个问题是关于 x86_64 架构和 Linux ABI。

当程序启动时,会为堆栈分配一些空间。稍后,在程序执行期间,堆栈区域可以调整大小(当需要更多空间时)达到操作系统指定的某个最大值。

让我们以简单的程序为例:

int main() {
    char bytes[7 * 1024 * 1024];
}
Run Code Online (Sandbox Code Playgroud)

让我们在 gdb 下运行它并设置断点:main 之前和声明数组之后。

gdb> b *main
gdb> b main
gdb> r
gdb> info proc mapping // breakpoint before pushing stack
          Start Addr           End Addr       Size     Offset objfile
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
gdb> c
gdb> info proc mapping // breakpoint after pushing stack
          Start Addr           End Addr       Size     Offset objfile
      0x7fffff8fe000     0x7ffffffff000   0x701000        0x0 [stack]
Run Code Online (Sandbox Code Playgroud)

所以我们可以看到堆栈实际上被调整了大小。

问题是操作系统如何知道何时必须调整堆栈大小?. 一些互联网资源说操作系统处理page fault …

c memory x86 assembly abi

6
推荐指数
1
解决办法
174
查看次数

ABI 规范中的内存布局是否仅适用于 ABI 边界?

ABI 标准中与内存布局相关的规范是否通常仅适用于 ABI 边界或例如在翻译单元内,或者如果不是这种情况,编译器通常是否会做出此类额外保证?

如果“一般”太宽泛,请考虑例如带有 System V x64 和 Itanium C++ ABI 的 GCC/Clang。

这里有两个例子来说明我的意思:

  1. System V x64 ABI 指定大小至少为 16 字节的数组具有至少 16 字节的对齐,即使元素类型的对齐更小,因此对齐比alignof建议的更严格。它还指定 的对齐方式long double16。那么以下在 C++ 标准下具有未定义行为的函数(如果调用)是否可以安全地在 System V x86 ABI 下使用,即使该storage数组从未跨翻译单元边界公开?

    void f() {
        char storage[16]; // Only guaranteed to have alignment `1` by the C++ standard.
        using T = long double;
        auto p = new(storage) T;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. Itanium C++ ABI 指定了类的布局。例如:

    #include<new>
    
    struct A {
        int i;
        virtual ~A() …
    Run Code Online (Sandbox Code Playgroud)

c++ abi

6
推荐指数
1
解决办法
222
查看次数

标签 统计

abi ×10

assembly ×3

c ×3

llvm ×3

c++ ×2

x86 ×2

x86-64 ×2

argc ×1

clang ×1

exception ×1

freebsd ×1

gcc ×1

libc++ ×1

linker ×1

llvm-c++-api ×1

llvm-clang ×1

memory ×1

seh ×1

solidity ×1

stack ×1

windows ×1