Debugging binutils under my OS?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

Code: Select all

    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: Select all

    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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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...
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

OK one of the tests failed and I'm a bit confused as to why:

Code: Select all

	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?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

mariuszp wrote:OK one of the tests failed and I'm a bit confused as to why:

Code: Select all

	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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

gerryg400 wrote:
mariuszp wrote:OK one of the tests failed and I'm a bit confused as to why:

Code: Select all

	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.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Debugging binutils under my OS?

Post by gerryg400 »

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 ?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

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.
Post Reply