This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pow() fails with a segmentation fault when executed from dynamicallyallocated memory


On 28/01/12 13:21, Carlos O'Donell wrote:
IIUC you have a code trampoline in dynamically allocated memory
which calls my_pow() and somtimes it segfaults?

Rather than making me decode the trampoline by hand, could you
please provide the assembly instructions for the trampoline?

Is there any reason you wrote the trampoline out by hand?

My preference would have been to write the trampoline in C,
let the compiler compile it, dynamically allocate the memory,
and then memcpy the trampoline into place. The alternative
being: compile the trampoline from an assembly file which has
two symbols that mark the start and the end of the trampoline.
In either case you get the benefit of the assembler which will
double check your encoding and warn you if you made a mistake.
If you use a C compiler it's even better because you then are
assured you didn't make a procedure-call error.

Cheers,
Carlos.
I get the same failing behavior in both testcases as the reporter.

I have rewritten the testcase with a struct + memcpy (see below).

This way it can be disassembled with objdump -D, which shows
0000000000600b50 <value>:
  600b50:    49 bb c0 06 40 00 00     movabs $0x4006c0,%r11
  600b57:    00 00 00
  600b5a:    41 ff d3                 callq  *%r11
  600b5d:    c3                       retq
    ...
0x4006c0 is the address asignated to my_pow. Disassembled below:
00000000004006c0 <my_pow>:
4006c0: 48 83 ec 18 sub $0x18,%rsp
4006c4: bf ec 07 40 00 mov $0x4007ec,%edi
4006c9: e8 22 fe ff ff callq 4004f0 <puts@plt>
4006ce: f2 0f 10 0d 42 01 00 movsd 0x142(%rip),%xmm1 # 400818 <_IO_stdin_used+0x30>
4006d5: 00
4006d6: f2 0f 10 05 42 01 00 movsd 0x142(%rip),%xmm0 # 400820 <_IO_stdin_used+0x38>
4006dd: 00
4006de: e8 3d fe ff ff callq 400520 <pow@plt>
4006e3: bf f1 07 40 00 mov $0x4007f1,%edi
4006e8: f2 0f 11 04 24 movsd %xmm0,(%rsp)
4006ed: e8 fe fd ff ff callq 4004f0 <puts@plt>
4006f2: f2 0f 10 04 24 movsd (%rsp),%xmm0
4006f7: 48 83 c4 18 add $0x18,%rsp
4006fb: c3 retq




#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <sys/mman.h>

volatile double my_pow() {
  printf("test\n");
  double ret = pow(-2.0, 0.5);
  printf("test2\n");
  return ret;
}

struct {
char a, b;
void *addr;
char c, d, e, f;
} __attribute__((packed)) value = { 0x49, 0xBB, &my_pow, 0x41, 0xff, 0xd3, 0xc3 };


void execute() {

uint8_t *code = ( uint8_t * ) mmap( NULL, 1024,
PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0 );


memcpy(code, &value, sizeof(value));

  double (*fun)(void) = (double (*)(void))code;
  printf("value is at %p\n", &value);

  printf("Result: %f\n", my_pow());
  printf("Result: %f\n", fun());
}

int main() {
  execute();
  return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]