Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

macos - Segfault with RIP-relative addressing on Linux

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

Called from a simple C program:

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

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
}

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?

Cheers

  • Iain
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The segfault happens because of misalignment. A 4 Byte alignment isn't sufficient for movapd, you need 16 Byte .align 16 at least.

You see 0(%rip) in objdump, because the code isn't relocated yet. The runtime linker will replace it with the correct offset when you execute it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...