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