标签: abi

ARM在Linux内核中注册r9

"ARM体系结构过程调用标准"(AAPCS/EABI)声明(5.1.1)

"The role of register r9 is platform specific."
Run Code Online (Sandbox Code Playgroud)

"A virtual platform [...] may designate r9 as an additional callee-saved
 variable register, v6."
Run Code Online (Sandbox Code Playgroud)

问题是:Linux内核是否将r9用于特殊用途?或者它是否用作普通的非易失性寄存器?

arm abi cpu-registers linux-kernel

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

使用libelf提示生成ELF

我正在尝试使用libelf生成一个简单的静态ELF,但我似乎遇到了麻烦.

我不希望生成一个目标文件然后用LD链接它,而是希望我自己生成它.

该程序的主要目的是生成具有一个LOAD段的静态ELF并执行代码.

主要问题不在于shellcode本身,而是在我试图以错误的方式生成的一些标题中.当我尝试运行生成的ELF时,它会被杀死,好像内核无法找到它刚刚加载的段等.

如果你们能暗示我,我会很喜欢.

create_elf.3.c

#include <err.h>
#include <fcntl.h>
#include <libelf.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>

unsigned char code[] =
"\x0b\x58\x99\x52\x66\x68\x2d\x70"
"\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61"
"\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52"
"\x51\x53\x89\xe1\xcd\x80";

int main(int argc, char *argv[])
{
  int           fd;
  Elf           *e;
  Elf_Scn       *scn;
  Elf_Data      *data;
  Elf32_Ehdr    *ehdr;
  Elf32_Phdr    *phdr;
  Elf32_Shdr    *shdr;
  if (argc != 2)
    errx(EX_USAGE,"input... ./%s filename\n",argv[0]);
  if (elf_version(EV_CURRENT) == EV_NONE)
    errx(EX_SOFTWARE,"elf_version is ev_none, wtf? %s\n",elf_errmsg(-1));
  if ((fd = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0)
    errx(EX_OSERR, "open %s\n",elf_errmsg(-1));
  if ((e = …
Run Code Online (Sandbox Code Playgroud)

c linux elf abi

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

枚举和枚举类的链接兼容性

假设有一个使用枚举类的C++ 11 API:

// api.hpp
enum class E {A, B, C};
void f(E);
...

// api.cpp
void f(E e)
{
    if (e == E::A)
       ...
}
Run Code Online (Sandbox Code Playgroud)

现在假设我想使用这个API,但我没有C++ 11编译器.所以我:

  • 修改api.hpp枚举类并将其更改为常规枚举.
  • 编写一些包含修改后的代码,api.hpp并正常使用API​​(例如调用f).
  • 使用我的非C++ 11编译器编译此代码,并将其链接到使用C++ 11编译器编译的API实现(使用未修改的编译器api.hpp).

这似乎与海湾合作委员会有关,但一般来说是安全的,还是我玩火(ODR违规等)?

假设两个编译器在其他方面是链接兼容的,那么只有enum vs. enum类才有问题.

c++ linker abi c++11 enum-class

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

确定在C++ 11中实现bignums的最有效字大小?

通常使用多个单词来实现bignums,但我想尽可能地选择单词大小.这比看起来更棘手 - std::uint64_t在许多32位编译器中都可用,但std::uint32_t在32位机器上可能是更好的选择.那么诱惑就是使用std :: size_t,但不能保证给定的体系结构std::size_t是最有效的算术类型,例如在新的x32 Linux ABI std::size_t上将是32位但std::uint64_t仍然是最佳选择.

C++ 11定义了各种大小的快速/最小类型,但它没有提供任何查询它们相对性能的方法.我意识到可能没有最好的可移植答案,我现在最好的猜测是std::size_t在配置时默认并检测出特殊的架构.但也许有更好的方法?

c++ portability integer abi c++11

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

从64位asm调用Printf时,params如何通过?

我正在学习再次使用汇编语言,到目前为止我遇到的唯一问题就是调用C语言.我所拥有的书是32位,而我的工作是64位.显然,调用约定存在很大差异,并且http://www.x86-64.org/documentation站点已关闭.因此,经过一些挖掘/测试,在C中编译虚拟程序并花费3天时间,我想我会发布我的发现,如果它可以帮助其他人.

RAX是否需要给出浮点数?堆栈填充"阴影空间"16或32位?这个宏用于对齐小程序的堆栈是否可以通过?我知道你可以用对齐NOP填充代码,我不确定堆栈框架.

; pf.asm compiled with 'nasm -o pf.o -f elf64 -g -F stabs'
; linked with 'gcc -o pf pf.o'
; 64-bit Bodhi (ubuntu) linux

%include "amd64_abi.mac"
[SECTION .data]
First_string:   db "First string.",10,"%s", "%d is an integer. So is %d",10
                db "Floats XMM0:%5.7f  XMM1:%.6le  XMM2:%lg",10,0  
Second_String:  db "This is the second string... %s's are not interpreted here.",10
                db " Neither are %d's nor %f's. 'Cause it is a passed value.", 10, 0
; Just a regular string …
Run Code Online (Sandbox Code Playgroud)

assembly printf x86-64 abi calling-convention

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

GCC API无法解码自己的导出符号

我正在尝试使用GCCabi::__cxa_demangle来解码从生成的目标文件导出的符号g++.但是,我不变得到错误

mangled_name不是C++ ABI修改规则下的有效名称

这是我调用函数的方式:

std::string demangled(std::string const& sym) {
    std::unique_ptr<char, void(*)(void*)>
        name{abi::__cxa_demangle(sym.c_str(), nullptr, nullptr, nullptr), std::free};
    return {name.get()};
}
Run Code Online (Sandbox Code Playgroud)

(省略错误处理;它出现在完整的在线演示中.)

我测试过的符号来自这个小代码:

namespace foo {
    template <typename T>
    struct bar { bar() { } };
}

void baz(int x) { }

template struct foo::bar<int>;
Run Code Online (Sandbox Code Playgroud)

通过g++ -c test.cpp; nm test.o | cut -d ' ' -f3:

EH_frame1
__Z3bazi
__ZN3foo3barIiEC1Ev
__ZN3foo3barIiEC2Ev
Run Code Online (Sandbox Code Playgroud)

我不确定GCC demangling API的目的是什么,如果它不能解码这些符号 - 它可以成功地解码C++ typeid表示.例如,在测试代码中写入typeid(foo::bar<int>*).name()将产生PN3foo3barIiEE …

c++ gcc abi name-mangling

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

我可以从堆栈中间弹出吗?

在x86汇编语言中:

我假设我有一个正常的功能序言,请阅读

push ebp
mov  ebp,esp
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过访问内存目标操作数来读取或写入寄存器,假设我想要第一个参数。我会做

mov eax,[ebp +8]
Run Code Online (Sandbox Code Playgroud)

从堆栈中获取一个整数参数。

那为什么我不直接使用stackpointer呢?

add  esp,8              ; point ESP at the data we want
pop  eax
sub  esp,12             ; restore ESP to its original position
Run Code Online (Sandbox Code Playgroud)

这会导致错误吗?在任何情况下都使用吗?

我当然知道第一个操作的大小较小,因为它只是一个操作码,mov而不是三个,但这不是问题的重点。

(编者注:mov eax, [ebp+8]。在x86机器代码的3字节的指令 add/ subESP,imm8指定为3个字节的每个,pop eax是1个字节。
mov eax, [esp+8]是一个4字节的指令:不像在16位寻址模式,ESP可以是一个基址寄存器。但是它确实需要一个SIB字节来对其进行编码。
这些都是现代CPU上的单联指令,不包括额外的堆栈同步联指令。)

为什么这样做是错误的做法?

x86 assembly callstack abi red-zone

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

std :: regex和双ABI

今天我发现了一个有趣的双libstdc ++ ABI案例,影响了库的兼容性.

长话短说,我有两个库都在内部使用std :: regex.一个是使用CXX11 ABI构建的,另一个不是.当这两个库在一个可执行文件中链接在一起时,它会在启动时崩溃(在main输入之前).

库是不相关的,不公开提及任何std::类型的接口.我认为这些库应该不受双重ABI问题的影响.显然不是!

这个问题可以通过这种方式轻松复制:

// file.cc
#include <regex>
static std::regex foo("(a|b)");

// main.cc
int main() {}

// build.sh
g++ -o new.o file.cc
g++ -o old.o file.cc -D_GLIBCXX_USE_CXX11_ABI=0 
g++ -o main main.cc new.o old.o
./main
Run Code Online (Sandbox Code Playgroud)

输出是:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

无论我做什么,问题仍然存在.file.cc可以制作成两个独立的源文件,编译成单独的共享库,这两个std::regex对象可能有不同的名称,它们可以是全局的,静态的或自动的(main从那时起需要调用相应的函数).这些都没有帮助.

显然(这是我的简短调查的结果)libstdc ++正则表达式编译器有一些存储的内部静态数据,std::string当两个ABI不兼容的代码片段试图使用该数据时,它会对std::string对象的布局产生冲突的想法.

所以我的问题是:

  • 这个问题有解决方法吗?
  • 这应该被视为libstdc ++中的错误吗?

这个问题在g ++/libstdc ++的几个版本中是可重现的(我尝试了一些从5.4到7.1).libc ++不会出现这种情况.

c++ g++ abi libstdc++ c++11

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

如何通过gcc的配置选项确定默认枚举大小(短或非短)?

我尝试了一些gcc编译器来查看默认的枚举大小是短(至少一个字节,如强制-fshort-enums)还是不短(至少4个字节,强制使用-fno-short-enums):

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | x86_64-linux-gnu-gcc -fsyntax-only -xc - && echo "OK, enum size is 4 on x86_64-linux-gnu"
OK, enum size is 4 on x86_64-linux-gnu

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | arm-linux-gnueabihf-gcc -fsyntax-only -xc - && echo "OK, enum size is 4 on arm-linux-gnueabihf"
OK, enum size is 4 on arm-linux-gnueabihf

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | /opt/Atollic_TrueSTUDIO_for_STM32_x86_64_9.1.0/ARMTools/bin/arm-atollic-eabi-gcc -fsyntax-only …
Run Code Online (Sandbox Code Playgroud)

c enums gcc abi

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

Swift 5.1运行时如何与旧版iOS一起使用?

About a year ago, if you wanted to use Swift 4.2 for iOS development, you would have to install Xcode 10, which meant that you used iOS 12 SDK. As part your apps deployment, Swift 4.2 runtime would automatically be bundled with your app binary. This would mean that user installing your app would essentially download a copy of that Swift runtime that will enable your app work.

However, ABI stability came with Swift 5, and you no longer needed …

xcode abi ios swift

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