3

One of my generated functions doesn't compute what it should and I am trying to debug it separately. I have the assembler for it and I try to call it from a stripped down C program. However, for some reason I end up getting segfaults in the function (so, calling the function seems to work, but execution fails). There might be something wrong with passing the arguments..

The functions signature is

void func(int, int, float*, float*, float*); 

The function ignores the first two arguments and received 3 arrays of 32 floats each. It would add element-wise the latter two and store the result element-wise into the first array. However, it would do that in a kind of weird order (as opposed to streaming linearly through it, the reason for doing this is not in the scope of this SO question). That's what the offset_arrays are for in the assembler code.

I checked the x86 calling conventions (that's the architecture I am using) and the first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9.

Here' the function implementation:

 .text .globl func .align 16, 0x90 .type func,@function func: .cfi_startproc xorl %eax, %eax movabsq $offset_array1, %r9 movabsq $offset_array, %r10 xorl %esi, %esi .align 16, 0x90 .LBB0_1: movq (%r9,%rax), %r11 movq (%r10,%rax), %rdi movss (%r8,%rdi,4), %xmm0 addss (%rcx,%rdi,4), %xmm0 movss %xmm0, (%rdx,%r11,4) incq %rsi addq $8, %rax cmpq $33, %rsi jb .LBB0_1 retq .Ltmp0: .size func, .Ltmp0-func .cfi_endproc .type offset_array,@object .section .rodata,"a",@progbits .align 16 offset_array: .quad 0 .quad 16 .quad 1 .quad 17 .quad 2 .quad 18 .quad 3 .quad 19 .quad 4 .quad 20 .quad 5 .quad 21 .quad 6 .quad 22 .quad 7 .quad 23 .quad 8 .quad 24 .quad 9 .quad 25 .quad 10 .quad 26 .quad 11 .quad 27 .quad 12 .quad 28 .quad 13 .quad 29 .quad 14 .quad 30 .quad 15 .quad 31 .size offset_array, 256 .type offset_array1,@object .align 16 offset_array1: .quad 0 .quad 16 .quad 1 .quad 17 .quad 2 .quad 18 .quad 3 .quad 19 .quad 4 .quad 20 .quad 5 .quad 21 .quad 6 .quad 22 .quad 7 .quad 23 .quad 8 .quad 24 .quad 9 .quad 25 .quad 10 .quad 26 .quad 11 .quad 27 .quad 12 .quad 28 .quad 13 .quad 29 .quad 14 .quad 30 .quad 15 .quad 31 .size offset_array1, 256 .section ".note.GNU-stack","",@progbits 

I try to call the function from this C code:

float f0[32]; float f1[32]; float f2[32]; extern void func(int i0,int i1,float* dest,float* src0,float* src1); int main(int argc, char *argv[]) { func(0,0,f0,f1,f2); } 

Compiling both and linking with

gcc -o f.o -c -g f.S gcc -g -o test_f test_f.c f.o 

and running though gdb results in

Program received signal SIGSEGV, Segmentation fault. func () at f.S:17 17 movss %xmm0, (%rdx,%r11,4) 

So, this is obviously a write to memory, namely to the first array. Why would it segfault and how to call this function correctly (without changing the assembler code)?

4
  • Do you have the source code to the function you're debugging? That'd be a heck of a lot easier to work with than the assembly. Commented Jul 21, 2015 at 20:20
  • What are the register values after the crash? (just the ones from line 17) Commented Jul 21, 2015 at 20:55
  • SonOfSun and merridius, thanks for catching this. Changing the value to $32 works. Wow, then I will have to file a bug report to LLVM, since this assembler was generated from its x86-64 backend from IR that had the correct loop bounds :-( Commented Jul 22, 2015 at 1:49
  • how to debug asm: use gdb with layout reg and layout asm. See stackoverflow.com/tags/x86/info for more info and links. In this case, since you already had gdb running on it, you could x (examine) the memory at the address referenced by %rdx + r11 * 4, and see that it was inaccessible. Commented Jul 23, 2015 at 12:02

2 Answers 2

2

The problem comes from this line

cmpq $33, %rsi 

it should be

cmpq $32, %rsi 

you are accessing the junk in the memory after .quad 31 and sticking that into r11 at movq (%r9,%rax), %r11

Sign up to request clarification or add additional context in comments.

1 Comment

We found it almost together :)
2

The size of the arrays is 32, but in the function the %rsi is incrementing from 0 to 33 with jb after it. It is wrong and access this part of static memory(not allocated) raieses a segmentation fault. It should be changed to 32. Tested in ubuntu.

func: .cfi_startproc xorl %eax, %eax movabsq $offset_array1, %r9 movabsq $offset_array, %r10 xorl %esi, %esi .align 16, 0x90 .LBB0_1: movq (%r9,%rax), %r11 movq (%r10,%rax), %rdi movss (%r8,%rdi,4), %xmm0 addss (%rcx,%rdi,4), %xmm0 movss %xmm0, (%rdx,%r11,4) incq %rsi addq $8, %rax cmpq $32, %rsi jb .LBB0_1 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.