* incorrect dereference of implicit memcpy
@ 2006-10-05 9:35 Woytech Karl-Heinz
2006-10-05 11:00 ` Andrew Haley
0 siblings, 1 reply; 4+ messages in thread
From: Woytech Karl-Heinz @ 2006-10-05 9:35 UTC (permalink / raw)
To: gcc-help
Hello,
I am working on an x86 embedded system where we do not have ld/libc
onboard. our OS provides basic libc functions and does it's own dynamic
linking for the applications.
Basic function dereferencing works properly, our problem is with the
implicit function calls that gcc makes for copying structs.
When the application code below gets started our OS finds the 'imex'
structure and correctly fills out the required function pointers so that
calls to the fn's result in the code provided by the os getting called.
Thus the explicit call
jimbob(815);
translates to
push $0x32f
call *0x804912c
memcpy (dest, src, 20);
translates to
push $0x14
push %ebx
lea 0xffffff61(%ebp),%eax
push %eax
call *0x8049128
which is also good
BUT the structure copy x=y becomes
push $0x16
push %eax
push %edx
call 8049128 <- no '*'
which is a direct jump into memory instead of a jump to the dereference
of the memory location. as of that moment the application crashes. below
are our build commands and the program.
Am I doing something wrong here, or do i have incorrect cflags/ldflags?
ie can i get gcc to produce the same derefecenced call as per the
explicit calls?
Thanks in advance for any input
Charlie
gcc testjmp.c -c -o testjmp.o -ffreestanding -march=i386 -g -Os
-fno-builtin
ld testjmp.o -o testjmp -static -nostdlib
objdump testjmp -DSx > testjmp.dis
testjmp.c:
// structure def for our import/export table
typedef struct imex_s {
char name[16];
void *ptr;
} imex_t;
// fixed typedefs for our funcions
typedef int (*jimbob_t)(int jb);
typedef void (*memcpy_t)(char *d, char *s, int l);
// memory space for the to be linked fn's will be in .bss
jimbob_t jimbob;
memcpy_t memcpy;
// our import table will be in .const
const imex_t imex[] =
{
{ "jimbob", (void*)&jimbob},
{ "memcpy", (void*)&memcpy}
};
// test struct for x=y
typedef struct
{
char Bytes[22];
} structure_t;
int main(int argc, char *argv[])
{
char dest[100];
char src[] = {"hello pdts"};
volatile structure_t X, Y;
jimbob(815);
memcpy (dest, src, 20);
X = Y; /* gcc creates a memcpy here */
return 0;
}// main
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: incorrect dereference of implicit memcpy
2006-10-05 9:35 incorrect dereference of implicit memcpy Woytech Karl-Heinz
@ 2006-10-05 11:00 ` Andrew Haley
0 siblings, 0 replies; 4+ messages in thread
From: Andrew Haley @ 2006-10-05 11:00 UTC (permalink / raw)
To: Woytech Karl-Heinz; +Cc: gcc-help
Woytech Karl-Heinz writes:
> I am working on an x86 embedded system where we do not have ld/libc
> onboard. our OS provides basic libc functions and does it's own dynamic
> linking for the applications.
>
> Basic function dereferencing works properly, our problem is with the
> implicit function calls that gcc makes for copying structs.
>
> When the application code below gets started our OS finds the 'imex'
> structure and correctly fills out the required function pointers so that
> calls to the fn's result in the code provided by the os getting called.
>
> Thus the explicit call
> jimbob(815);
> translates to
> push $0x32f
> call *0x804912c
>
> memcpy (dest, src, 20);
> translates to
> push $0x14
> push %ebx
> lea 0xffffff61(%ebp),%eax
> push %eax
> call *0x8049128
>
> which is also good
> BUT the structure copy x=y becomes
> push $0x16
> push %eax
> push %edx
> call 8049128 <- no '*'
>
> which is a direct jump into memory instead of a jump to the dereference
> of the memory location. as of that moment the application crashes. below
> are our build commands and the program.
>
> Am I doing something wrong here, or do i have incorrect cflags/ldflags?
> ie can i get gcc to produce the same derefecenced call as per the
> explicit calls?
gcc generates a direct call to memcpy(), and it's up to you to make
sure that there is executable code at that address.
However, given that you have the opportunity to change gcc's behaviour
by patching emit_block_move() to do something else, you can do so.
Also, you might like to look at init_block_move_fn().
I'm sure it would be a lot easier to put a jump instruction at memcpy,
though.
Andrew.
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: incorrect dereference of implicit memcpy
@ 2006-10-05 20:21 Kaz Kylheku
0 siblings, 0 replies; 4+ messages in thread
From: Kaz Kylheku @ 2006-10-05 20:21 UTC (permalink / raw)
To: Woytech Karl-Heinz, gcc-help
> Woytech Karl-Heinz wrote:
> When the application code below gets started our OS finds the 'imex'
> structure and correctly fills out the required function
> pointers so that
> calls to the fn's result in the code provided by the os
> getting called.
>
> Thus the explicit call
> jimbob(815);
> translates to
> push $0x32f
> call *0x804912c
That's because it's not an explicit call to a function, but through a
function pointer which you declared.
> BUT the structure copy x=y becomes
> push $0x16
> push %eax
> push %edx
> call 8049128 <- no '*'
>
> which is a direct jump into memory instead of a jump to the
> dereference
That's because the compiler does not read your memcpy declaration.
It assumes that there is a memcpy function and generates a call to it.
That generation is not influenced by your redeclaration of memcpy.
You must provide a real memcpy function.
> ie can i get gcc to produce the same derefecenced call as per the
> explicit calls?
Forget about it.
> gcc testjmp.c -c -o testjmp.o -ffreestanding -march=i386 -g -Os
> -fno-builtin
> ld testjmp.o -o testjmp -static -nostdlib
> objdump testjmp -DSx > testjmp.dis
>
> testjmp.c:
>
> // structure def for our import/export table
> typedef struct imex_s {
> char name[16];
> void *ptr;
> } imex_t;
>
> // fixed typedefs for our funcions
> typedef int (*jimbob_t)(int jb);
> typedef void (*memcpy_t)(char *d, char *s, int l);
ANSI C memcpy is void * (void *, const void *, size_t).
> // memory space for the to be linked fn's will be in .bss
> jimbob_t jimbob;
> memcpy_t memcpy;
Call these jimbob_ptr, memcpy_ptr.
> // our import table will be in .const
> const imex_t imex[] =
> {
> { "jimbob", (void*)&jimbob},
&jimbob_ptr
> { "memcpy", (void*)&memcpy}
&memcpy_ptr
> };
Now write this function and link it to your program:
/* wrapper for indirection */
void *memcpy(void *dest, void *src, size_t len)
{
memcpy_ptr(dest, src, len);
return dest;
}
Note that this wrapper not only ensures that control is routed
to your function, but also provides ANSI C compatibility.
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: incorrect dereference of implicit memcpy
@ 2006-10-05 13:15 Woytech Karl-Heinz
0 siblings, 0 replies; 4+ messages in thread
From: Woytech Karl-Heinz @ 2006-10-05 13:15 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
Woytech Karl-Heinz writes:
> > I am working on an x86 embedded system where we do not have ld/libc
> onboard. our OS provides basic libc functions and does it's own
dynamic > linking for the applications.
> >
> > Basic function dereferencing works properly, our problem is with
the > implicit function calls that gcc makes for copying structs.
> >
> > When the application code below gets started our OS finds the
'imex'
> > structure and correctly fills out the required function pointers so
that > calls to the fn's result in the code provided by the os getting
called.
> >
> > Thus the explicit call
> > jimbob(815);
> > translates to
> > push $0x32f
> > call *0x804912c
> >
> > memcpy (dest, src, 20);
> > translates to
> > push $0x14
> > push %ebx
> > lea 0xffffff61(%ebp),%eax
> > push %eax
> > call *0x8049128
> >
> > which is also good
> > BUT the structure copy x=y becomes
> > push $0x16
> > push %eax
> > push %edx
> > call 8049128 <- no '*'
> >
> > which is a direct jump into memory instead of a jump to the
dereference > of the memory location. as of that moment the application
crashes. below > are our build commands and the program.
> >
> > Am I doing something wrong here, or do i have incorrect
cflags/ldflags?
> > ie can i get gcc to produce the same derefecenced call as per the
> explicit calls?
Andrew Haley:
> gcc generates a direct call to memcpy(), and it's up to you to make
sure that there is executable code at that address.
>
> However, given that you have the opportunity to change gcc's behaviour
by patching emit_block_move() to do something else, you can do so.
Also, you might like to look at init_block_move_fn().
>
> I'm sure it would be a lot easier to put a jump instruction at memcpy,
though.
>
> Andrew.
Thanks for the prompt answer and the food for though,
I would like to leave my sticky little fingers from patching gcc at the
moment as this would restict all our developers to one specially
compiled gcc.
Currently we are considering either adding the following to the
application code
__asm__
(".bss \n"
".align 4 \n"
"dmymemcpy : .space 3 \n"
".globl memcpy \n"
"memcpy : .space 1 \n"
".globl fmemcpy \n"
"fmemcpy : .space 4 \n");
extern char memcpy;
extern memcpy_t fmemcpy;
memcpy = 0xe9; // jmp [abs]
#define memcpy(d,s,l) fmemcpy((d),(s),(l))
which would not break our legacy function ptr code and keeps gcc happy
or just statically linking a memcpy to the applications (even easier)
kind regards
charlie
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2006-10-05 20:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-05 9:35 incorrect dereference of implicit memcpy Woytech Karl-Heinz
2006-10-05 11:00 ` Andrew Haley
2006-10-05 13:15 Woytech Karl-Heinz
2006-10-05 20:21 Kaz Kylheku
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).