From: Grant Edwards <grante@visi.com>
To: Keith Seitz <keiths@cygnus.com>
Cc: Andrew Cagney <ac131313@cygnus.com>, gdb@sourceware.cygnus.com
Subject: Re: Semihosting output on ARM7TDMI
Date: Tue, 14 Aug 2001 11:43:00 -0000 [thread overview]
Message-ID: <20010814134522.A8849@visi.com> (raw)
In-Reply-To: <Pine.GSO.4.33.0108140928480.23443-100000@makita.cygnus.com>
On Tue, Aug 14, 2001 at 09:31:26AM -0700, Keith Seitz wrote:
> On Tue, 14 Aug 2001, Grant Edwards wrote:
>
> > But, the RDI stuff isn't aware of gdb, and it would take some
> > work to make it aware. It would be "a good thing" but somebody
> > would have to want it bad enough to actuallly do it.
>
> Isn't there already some machinery in place to do target I/O? You can
> certainly do printf and the like on an arm board using rdi and gdb.
I wasn't aware that that stuff worked. What I've seen in the
past is that the semi-hosting routines generates the "CL_Write"
messages, and the handler for that flushes the data.
> What do the the members writec, readc, write, gets in struct
> Dbg_HostosInterface mean? Specifically:
It appears that they're the routines that are supposed to get
called for semi-hosting console I/O.
> gdb_hostif.dbgprint = myprint;
> gdb_hostif.dbgpause = mypause;
> gdb_hostif.dbgarg = NULL;
> gdb_hostif.writec = mywritec;
> gdb_hostif.readc = myreadc;
> gdb_hostif.write = mywrite;
> gdb_hostif.gets = mygets;
> gdb_hostif.hostosarg = NULL;
> gdb_hostif.reset = voiddummy;
>>
> Doesn't any of this deal with "semi-hosting"?
It's supposed to, but I don't think it all works. From what
I've seen, the semi-hosting client stuff generates writes to fd
0, and since that fd has never been opened, the data is
discarded in hsys.c by HandleSysMessage:
490 case CL_Write:
491 {
492 /* Write(word handle, word nbtotal, word nbytes, bytes data)
493 * return(word nbytes)
494 * WriteX(word nbytes, bytes data)
495 * return(word nbytes)
496 */
497 unsigned char *rwdata = NULL, *rwhead = NULL;
498 unsigned char *write_source = NULL;
499 char flags;
500 FILE *fhreal;
501 unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
502
503 err = -1; /* err == 0 is fwrite() error indication */
504 unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
505 DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
506 fh, nbtotal, nbytes));
507
** 508 fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
509 nbtogo = nbtotal;
510
511 /* deal with the file handle */
** 512 if (fhreal == NULL)
** 513 err = 0;
514 else {
515 if (flags & READOP)
516 fseek(fhreal,0,SEEK_CUR);
517 stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
line 508 returns a NULL, since no file has been opened, and the
data is flushed.
[It looks like CL_WriteC and CL_ReadC do what they should:
calling hostif->writec and hostif->readc, but I've never seen
anybody post ADP traces that showed those being used.]
Aha! I just noticed something that I missed before...
It also looks like somebody _did_ create a special case when an
fd maps to stdout or stderr by calling hostif->write() instead
of calling fwrite() on the file handle directly. The RDI stuff
is more aware than I thought. It isn't aware specifically of
gdb, but the remote-rdi.c adapts the RDI API well enough that I
think semi-hosting can be made to work right.
535 do {
536 /* at least once!! */
537
538 if (nbtogo == 0 && err != 0) {
539 /* Do the actual write! */
** 540 if (fhreal == stdout || fhreal == stderr) {
** 541 stateptr->hostif->write(stateptr->hostif->hostosarg,
542 (char *)write_source, nbtotal);
543 }
544 else
** 545 err = fwrite(write_source, 1, nbtotal, fhreal);
546 stateptr->last_errno = errno;
547 DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
548 }
549
I think that if you initialize fd #0 to be stdout, then the
hostif->write() routine will get called, and that in turn calls
fputc_unfiltered(c,gdb_stdout). I don't know why the
semi-hosting client routines are writing to fd 0 (which I would
assume to be stdin) rather than 1 (stdout) or 2 (stderr).
So one could try changing my three-line kludge to initialize
the first fd to stdout instead of stdin.
The handling for CL_Read is different and doesn't check for
stdin, stdout, stderr. Instead, if the fd maps to a file handle
that's a tty, then hostif->gets() is called which then does an
fgets() on stdin. Otherwise fread() is called on the file
handle.
--
Grant Edwards
grante@visi.com
prev parent reply other threads:[~2001-08-14 11:43 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-08-14 4:51 Joel Brenner
2001-08-14 7:56 ` Grant Edwards
2001-08-14 8:33 ` Andrew Cagney
2001-08-14 8:46 ` Grant Edwards
2001-08-14 9:11 ` Andrew Cagney
2001-08-14 9:24 ` Grant Edwards
2001-08-14 9:31 ` Keith Seitz
2001-08-14 11:43 ` Grant Edwards [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20010814134522.A8849@visi.com \
--to=grante@visi.com \
--cc=ac131313@cygnus.com \
--cc=gdb@sourceware.cygnus.com \
--cc=keiths@cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox