How to get printf() output?
Kai Ruottu
kai.ruottu@luukku.com
Thu Sep 25 10:04:00 GMT 2003
Toralf Lund <toralf@procaptura.com> wrote:
> Ken Rose wrote:
>
> > Toralf Lund wrote:
> >
> >> Can someone repeat for me what I should do to get printf() to work
> >> when linking with newlib, but not libgloss? I was under the
> >> impression that write() would be called eventually, but it looks like
> >> it isn't. I've tried step-tracing the printf execution via the ROM
> >> monitor to find out what is going on, but it's a bit hard to follow...
One can track the 'execution' even without any monitor, hardware etc., by
simply making a disassembly output from the produced executable and then
searching 'write', which one knows being the 'low-level I/O' routine needed.
The 'write()' in libgloss seems to use the 'outbyte()' which writes one
char at a time to the serial port (via the monitor on the board):
00015b5c <write>:
15b5c: 4e56 0000 linkw %fp,#0
15b60: 48e7 3020 moveml %d2-%d3/%a2,%sp@-
15b64: 262e 0010 movel %fp@(16),%d3
15b68: 6f2e bles 15b98 <write+0x3c>
15b6a: 246e 000c moveal %fp@(12),%a2
15b6e: 2403 movel %d3,%d2
15b70: 0c12 000a cmpib #10,%a2@
15b74: 6714 beqs 15b8a <write+0x2e>
15b76: 101a moveb %a2@+,%d0
15b78: 49c0 extbl %d0
15b7a: 2f00 movel %d0,%sp@-
15b7c: 61ff 0000 0040 bsrl 15bbe <outbyte> <---- !!!
15b82: 588f addql #4,%sp
15b84: 5382 subql #1,%d2
15b86: 66e8 bnes 15b70 <write+0x14>
15b88: 600e bras 15b98 <write+0x3c>
15b8a: 4878 000d pea d <OPER1+0x1>
15b8e: 61ff 0000 002e bsrl 15bbe <outbyte> <---- !!!
15b94: 588f addql #4,%sp
15b96: 60de bras 15b76 <write+0x1a>
15b98: 2003 movel %d3,%d0
15b9a: 4cee 040c fff4 moveml %fp@(-12),%d2-%d3/%a2
15ba0: 4e5e unlk %fp
15ba2: 4e75 rts
<snip>
00015bbe <outbyte>:
15bbe: 4e56 fffc linkw %fp,#-4
15bc2: 1eae 000b moveb %fp@(11),%sp@
15bc6: 4e4f trap #15
15bc8: 0020 4e5e orib #94,%a0@-
15bcc: 4e75 rts
The usual way to make a disassembly listing is to use the :
m68k-elf-objdump -dr <executable-name>
command (and redirecting it to 'less' etc.)...
Instead of doing this kind of 'reverse engineering', one can also
look at the sources (or the provided documentation) for newlib,
here 'libgloss/write.c' :
/*
* write -- write bytes to the serial port. Ignore fd, since
* stdout and stderr are the same. Since we have no filesystem,
* open will only return an error.
*/
int
_DEFUN (write, (fd, buf, nbytes),
int fd _AND
char *buf _AND
int nbytes)
{
int i;
for (i = 0; i < nbytes; i++) {
if (*(buf + i) == '\n') {
outbyte ('\r');
}
outbyte (*(buf + i));
}
return (nbytes);
}
Looking at the 'libgloss/m68k' implementations of 'outbyte()' for the
IDP and DBUG monitors will be left as homework...
So the simple way is to use the existing libgloss and steal code
from it, implementing the 'outbyte()' with one's own code when
one hasn't neither IDP, nor DBUG on the board... One can produce
those 'libidp.a', 'libdbug.a' (or what they were), make a copy from
some suitable 'glue library' into 'libmyio.a', and then replace the
'outbyte()' there with ones own using the archiver like:
m68k-elf-ar dv libmyio.a idp-outbyte.o (remove the existing one)
m68k-elf-ar ruv libmyio.a my-outbyte.o (add the own one)
(if the 'libidp.a' was copied)
Or one can try to edit the sources and add the support for one's own
hardware and then getting the 'libmyio.a' from the libgloss build...
> >> Just to make it clear: I have provided custom version all routines
> >> necessary to link the application correctly, including read(),
> >> write(), open() and close(). I'm linking with libc, libm and crt0.o,
> >> but not libgloss or similar.
If you didn't use the previous 'monkey-like' approach in your low-level
I/O-implementation, ie. not using the provided 'write()' etc. and then
writing your own 'outbyte()', 'inbyte()' etc., basically you are on your
own. Otherwise you could simply show your 'outbyte()' and ask what is
wrong with it...
> > If isatty() claims that stdout isn't a tty, then printf will buffer
> > the output. The quick way to test this theory is to do fflush(0) to
> > push all the putput out.
>
> isatty() should be correct, and I've also tried fflush(0), but still no
> output...
I'm not that much familiar with the m68k-support, so I would use the
'monkey-like' approach if needing to implement the I/O-routines for
something new...
So my advice is that you would check your I/O-implementation once
again, the bug most probably is there...
Cheers, Kai
------
Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com
More information about the crossgcc
mailing list