hello, all.
here is my implementation of printf for use in syslinux core.
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 1024
char buf[BUF_SIZE];
extern void myputs(const char *);
int printf(const char *format, ...)
{
va_list ap;
int rv;
#if 1
myputs("DEBUG:the string we want fomart is\n\r");
myputs(format);
#endif
va_start(ap, format);
rv = vsprintf(buf, format, ap);
va_end(ap);
myputs(buf);
return rv;
}
well, this program is simple. but it can't work; then i debugged it, found
something error really happened.
it's called from hello() in hello.c, here is the snippet::
void hello(void)
{
static char hello_str[] = "Hello, World! (hello.c)\r\n";
myputs(hello_str);
printf(hello_str);
printf("testing with format output %d\n\r", 2);
}
here is the disassemble:
sub esp, 0x0000000c ; seems it want allocate some memory, but I didn't see
anything pushed on it..
mov eax, 0x00100fb0 ; the address of hello_str.
call 0x100170(myputs) ; the myputs() function. Seems the function passed
the parameter by register but not stack.
; then I would be really confused, why
it don't use the stack after allocating the stack memory.
; and for now, it goes well, the hello_str displayed well.
mov eax, 0x00100fb0 ; also use the eax to pass the parameter.
call 0x1001b8(printf) ; the printf function. trace in.....
-------------printf------------
push ebx
sub esp 0x00000008 ; allocate memory again...
mov eax, 0x00100f68
call 0x100170(myputs) ; puts the debug message, work wee too.
; then here we go
mov eax, dword ptr ss:[esp+0x10] ; well, as we haven't push the fomart
address, so how can we get the address by stack?
call 0x100170(myputs)
; so eax would point to a unknow value, in there, I don't know why it point
to "linux".
; and as we can think, it will output "linux" but not the hello_str
string.
; so it failed.
I don't know why, but I'm think of the gcc flags.
any ideas?
Thanks!
--
regards
liu Aleaxander
liu Aleaxander wrote:> > well, this program is simple. but it can't work; then i debugged it, found > something error really happened. > it's called from hello() in hello.c, here is the snippet:: > > void hello(void) > { > static char hello_str[] = "Hello, World! (hello.c)\r\n"; > > myputs(hello_str); > printf(hello_str); > printf("testing with format output %d\n\r", 2); > } > > > > here is the disassemble: > > sub esp, 0x0000000c ; seems it want allocate some memory, but I didn't see > anything pushed on it.. > mov eax, 0x00100fb0 ; the address of hello_str. > > call 0x100170(myputs) ; the myputs() function. Seems the function passed > the parameter by register but not stack. > ; then I would be really confused, why > it don't use the stack after allocating the stack memory. > > ; and for now, it goes well, the hello_str displayed well. > > mov eax, 0x00100fb0 ; also use the eax to pass the parameter.^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^> call 0x1001b8(printf) ; the printf function. trace in..... >The 32-bit code in Syslinux is compiled with -mregparm=3, which means that it uses registers to pass in the arguments to *non-varadic* functions. However, it should not use registers to pass in the argument to a varadic function like printf(). The easiest explanation for this problem is that it is missing the prototype, i.e. <stdio.h> isn't included. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Seemingly Similar Threads
- How does LLVM know where to resolve declared only functions?
- How does LLVM know where to resolve declared only functions?
- Crash with core32 (syslinux-3.81-pre12-68-g4a211f6)
- Register parameters are unsafe with gcc 3.3.2
- [PATCH] Add syscall wrappers required by libkeyutils