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 fromdynamically allocated memory


On Sat, Jan 28, 2012 at 4:17 AM, Lars Magnusson <lavima@gmail.com> wrote:
> Hello
>
> I'm having some trouble executing pow() from dynamically allocated
> memory. The memory is allocated with mmap() and filled with x86-64
> instructions. This seems to work fine for the most part, but it fails
> with a segmentation fault when I try to invoke the pow function with x
> < 0 and y non-integer (which should return NaN).
>
> I've reduced the problem down to the following code:
>
> double my_pow() {
> ?printf("test\n");
> ?double ret = pow(-2.0, 0.5);
> ?printf("test2\n");
> ?return ret;
> }
>
> void execute() {
>
> ?uint8_t *code = ( uint8_t * ) mmap( NULL, 1024,
> ? ?PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0 );
>
> ?code[0] = 0x49; code[1] = 0xbb;
>
> ?uint64_t addr = (uint64_t)&my_pow;
> ?code[2] = addr % 0x100; code[3] = (addr % 0x10000) >> 8;
> ?code[4] = (addr % 0x1000000) >> 16; code[5] = (addr % 0x100000000) >> 24;
> ?code[6] = (addr % 0x10000000000) >> 32; code[7] = (addr %
> 0x1000000000000) >> 40;
> ?code[8] = (addr % 0x100000000000000) >> 48; code[9] = addr >> 56;
>
> ?code[10] = 0x41; code[11] = 0xff; code[12] = 0xd3; code[13] = 0xc3;
>
> ?double (*fun)(void) = (double (*)(void))code;
>
> ?printf("Result: %f\n", my_pow());
> ?printf("Result: %f\n", fun());
> }
>
> The normal invocation of my_pow works fine, but it fails with
> segmentation fault from the the dynamic code on my machine with glibc
> version 2.13. The code executes without trouble in both instances on
> an older system with version 2.5 of glibc.
>
> My initial thought was that this was a kernel issues (which also
> differs between the systems), but I wanted to hear what you think
> before moving on.

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.


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