OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 7:27 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Mon Oct 12, 2015 3:54 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
gerryg400 wrote:
Hi, please see the attached file. I wouldn't describe these as rigorous. Most of these failed when I first tried but they all pass now :)


Thank you. How do I initialise the "testfile.bin"? Is it supposed to be initialised to some specific size and/or data?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Mon Oct 12, 2015 4:18 am 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
Code:
    fd = open("testfile.bin", O_RDWR | O_CREAT, 0550);
    for (j=0; j<10; ++j)
    {
        for (i='!'; i<='}'; ++i)
        {
            unsigned char ch = i;
            write(fd, &ch, 1);
        }
    }
    close(fd);

Code:
    fd = open("testfile2.bin", O_RDWR | O_CREAT, 0550);
    for (i=0; i<256; ++i) {
        unsigned char ch = i;
        write(fd, &ch, 1);
    }
    for (i=0; i<256; ++i) {
        unsigned char ch = 255-i;
        write(fd, &ch, 1);
    }
    for (i=0; i<256; ++i) {
        unsigned char ch = i;
        write(fd, &ch, 1);
    }
    for (i=0; i<256; ++i) {
        unsigned char ch = 255-i;
        write(fd, &ch, 1);
    }
    close(fd);

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Mon Oct 12, 2015 2:28 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
I seem to be getting some confusion again.

http://pubs.opengroup.org/onlinepubs/00 ... ngetc.html

This says that one byte of push-back shall be provided. This means that multiple calls to ungetc() without fgetc()/fread()/etc do not have to succeed. My implementation buffers only one "ungot" character, but your tests seem to enforce the buffer to be bigger (3 ungetc()s in a row).

Does software tend to assume that the unget buffer is larger than 1 byte?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Mon Oct 12, 2015 2:52 pm 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
Yep. I support 2 so you'll need to modify the tests slightly.

[edit] I just re-read your post and the question at the end. I don't think it is necessary to support more than 1 char of pushback. I supported 2 just because.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Tue Oct 13, 2015 2:16 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
I also had a really strange... "event"... while building binutils. There were lots of warnings that strcasecmp() is implicit declared (which means it's not in the headers), but there was no linking error despite the fact that my libc does not yet implement this function...


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Tue Oct 13, 2015 3:02 pm 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
Binutils links with its own copy of strcasecmp, probably in libiberty if you don't supply it.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Tue Oct 13, 2015 3:58 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
OK one of the tests failed and I'm a bit confused as to why:

Code:
   rewind(f);
   test_assert(fgetc(f) == 0x21);
   test_assert(ftell(f) == 1);
   test_assert(ungetc('x', f) == 'x');
   test_assert(ftell(f) == 0);
   test_assert(fseek(f, 0, SEEK_CUR) == 0);
   test_assert(ftell(f) == 0);


the standard says fseek() must reverse the effect of ungetc(). http://pubs.opengroup.org/onlinepubs/00 ... fseek.html

after the call to ungetc(), the file position is still 1 due to the previous fgetc(), but reported position is 0 as expected. but the fseek() to SEEK_CUR should set the reported position to 1, as it is 0 bytes away from the current file position, as far as I understand. And yet the last test (test_assert(ftell(f) == 0) ) fails. What is wrong?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 2:37 am 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
mariuszp wrote:
OK one of the tests failed and I'm a bit confused as to why:

Code:
   rewind(f);
   test_assert(fgetc(f) == 0x21);
   test_assert(ftell(f) == 1);
   test_assert(ungetc('x', f) == 'x');
   test_assert(ftell(f) == 0);
   test_assert(fseek(f, 0, SEEK_CUR) == 0);
   test_assert(ftell(f) == 0);


the standard says fseek() must reverse the effect of ungetc(). http://pubs.opengroup.org/onlinepubs/00 ... fseek.html

after the call to ungetc(), the file position is still 1 due to the previous fgetc(), but reported position is 0 as expected. but the fseek() to SEEK_CUR should set the reported position to 1, as it is 0 bytes away from the current file position, as far as I understand. And yet the last test (test_assert(ftell(f) == 0) ) fails. What is wrong?

I think you are probably correct. I based my implementation on the doc for fflush() which says
fflush() wrote:
[CX] [Option Start] For a stream open for reading, if the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset).[Option End]
IOW, fflush() is optionally different from fseek() in this detail. My fseek() calls fflush() so operates incorrectly.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 3:25 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
gerryg400 wrote:
mariuszp wrote:
OK one of the tests failed and I'm a bit confused as to why:

Code:
   rewind(f);
   test_assert(fgetc(f) == 0x21);
   test_assert(ftell(f) == 1);
   test_assert(ungetc('x', f) == 'x');
   test_assert(ftell(f) == 0);
   test_assert(fseek(f, 0, SEEK_CUR) == 0);
   test_assert(ftell(f) == 0);


the standard says fseek() must reverse the effect of ungetc(). http://pubs.opengroup.org/onlinepubs/00 ... fseek.html

after the call to ungetc(), the file position is still 1 due to the previous fgetc(), but reported position is 0 as expected. but the fseek() to SEEK_CUR should set the reported position to 1, as it is 0 bytes away from the current file position, as far as I understand. And yet the last test (test_assert(ftell(f) == 0) ) fails. What is wrong?

I think you are probably correct. I based my implementation on the doc for fflush() which says
fflush() wrote:
[CX] [Option Start] For a stream open for reading, if the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset).[Option End]
IOW, fflush() is optionally different from fseek() in this detail. My fseek() calls fflush() so operates incorrectly.


Ohhhh hang on, my fflush() doesn't work correctly then. Other than that, my fseek() is the same as yours.


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 3:52 am 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
This behaviour is optional...

Also I don't think this part is critical. I'm guessing binutils doesn't rely on it too much...

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 3:59 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
gerryg400 wrote:
This behaviour is optional...

Also I don't think this part is critical. I'm guessing binutils doesn't rely on it too much...

Still better to keep up with the up-to-date standard.

Also it seems like "ld" doesn't rely on ungetc() at all. Perhaps your fread() test will reveal something. Otherwise I'll probably have to "readelf" the glidix "ld" and see which libc functions it calls and maybe I could guess which one of them is buggy.


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 4:07 am 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
I do remember that ld does lots of fseek/fread/fseek/fwrite ALSO fprintf and fscanf.

Read carefully what it says for fread and fwrite. (Same applies for fprintf and fscanf.

fread() wrote:
For each object, size calls shall be made to the fgetc() function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object.

fwrite() wrote:
For each object, size calls shall be made to the fputc() function, taking the values (in order) from an array of unsigned char exactly overlaying the object.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 4:20 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
So fread() and fwrite() are equivalent to calling read() and write() with (count*size) and the buffer passed (which is what they do in my case except fread() also calls fflush() first).

My fprintf() uses fwrite() internally and fscanf() calls fgetc() a lot. I just fixed my (f)scanf() implementation and that works as far as I cna tell. Time to get on with fprintf() because it's stupid and doesn't support qualifiers like %ld, just the single specifiers like "%d", "%s" etc and if as you say it is called a lot, that could indeed be the problem.


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 4:25 am 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
mariuszp wrote:
So fread() and fwrite() are equivalent to calling read() and write() with (count*size) and the buffer passed (which is what they do in my case except fread() also calls fflush() first).
No, for example if you call ungetc() then the next fread() will get that character. Calling flush() first in wrong because that will forget the ungot chars.

mariuszp wrote:
My fprintf() uses fwrite() internally and fscanf() calls fgetc() a lot. I just fixed my (f)scanf() implementation and that works as far as I cna tell. Time to get on with fprintf() because it's stupid and doesn't support qualifiers like %ld, just the single specifiers like "%d", "%s" etc and if as you say it is called a lot, that could indeed be the problem.
All the I/O methods must be built on the basic fgetc() and fputc() methods. You will need fprintf and fscanf of %08x etc. to work properly.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Debugging binutils under my OS?
PostPosted: Wed Oct 14, 2015 4:29 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
gerryg400 wrote:
mariuszp wrote:
So fread() and fwrite() are equivalent to calling read() and write() with (count*size) and the buffer passed (which is what they do in my case except fread() also calls fflush() first).
No, for example if you call ungetc() then the next fread() will get that character. Calling flush() first in wrong because that will forget the ungot chars.

mariuszp wrote:
My fprintf() uses fwrite() internally and fscanf() calls fgetc() a lot. I just fixed my (f)scanf() implementation and that works as far as I cna tell. Time to get on with fprintf() because it's stupid and doesn't support qualifiers like %ld, just the single specifiers like "%d", "%s" etc and if as you say it is called a lot, that could indeed be the problem.
All the I/O methods must be built on the basic fgetc() and fputc() methods. You will need fprintf and fscanf of %08x etc. to work properly.


Oh wait, I did handle the ungetc() case in fread() by the equivalent "if (fp->_ungot != -1) {*put++ = (char) fp->_ingot; size--};" but I forgot that I call fflush() first thus making it useless. I guess I should just implement it with fgetc() and fputc().

Also, why does ld need "%08x" in printf? (out of curiosity). I mean it reads/writes binary files.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 45 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group