Linux上具有RIP相对寻址的Segfault [英] Segfault with RIP-relative addressing on Linux

查看:50
本文介绍了Linux上具有RIP相对寻址的Segfault的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的汇编代码,可以在Mac OS X(x86-64)上正常工作,但不能在Linux(x86-64)上正常工作:

I have a simple piece of assembly code that works correctly on Mac OS X (x86-64) but not on Linux (x86-64):

.data
.align 4

foo: .quad 1,2

.text

.globl fun
fun:
movapd foo(%rip), %xmm1
ret

从一个简单的C程序调用:

Called from a simple C program:

int main(void){
  fun();
  return 0;
}

在Mac上发生的是xmm1寄存器中的数据位于foo位置,即在GDB中:

What happens on the Mac is that the xmm1 register is filled with the data at location foo i.e. in GDB:

(gdb) p $xmm1
$2 = {
...
v2_int64 = {2, 1}, 
uint128 = 0x00000000000000020000000000000001
}

当我在Linux下运行相同的代码时,它会出现段错误-似乎foo标签对应于0x0:

When I run the same code under Linux it segfaults - it seems that the foo label corresponds to 0x0:

> objdump -d asm.o
...

Disassembly of section .text:
0000000000000000 <fun>:
   0:   66 0f 28 0d 00 00 00   movapd 0x0(%rip),%xmm1
...

有人可以解释为什么会发生这种情况吗?我该怎么做才能避免这种情况发生?

Can someone explain why this occurs and what I can do to avoid it?

欢呼

  • 伊恩

推荐答案

在主线gnu binutils上,在i386和x86_64上, .align n 指令告诉汇编器将其对齐为n个字节(但是),在某些架构和平台上,它还有其他含义.有关详细信息,请查阅文档).

On the mainline gnu binutils, on i386 and x86_64, the .align n directive tells the assembler to align to n bytes (however, on some architectures and platforms, it has other meanings. Consult the documentation for full details).

在OS X上, .align n 指令告诉汇编程序将其对齐为2 ^ n个字节.这就是为什么您的代码可以在Mac上运行的原因.

On OS X, the .align n directive tells the assembler to align to 2^n bytes. This is why your code works on the Mac.

如果要保持一致的跨平台行为,请改用 .p2align 指令,该指令在两个平台上均受支持,并告诉汇编程序将其对齐为2 ^ n个字节.

If you want consistent cross-platform behavior, use the .p2align directive instead, which is supported on both platforms, and tells the assembler to align to 2^n bytes.

这篇关于Linux上具有RIP相对寻址的Segfault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆