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!
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 just checked it seems to use %d and %lu when reading libgcc.a (sorry not %08x my memory is failing)
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, now my libc passes your tests. "ld" does not call fprintf() (i checked). It still produces the broken binary. Inspecting undex linux, I can see that the first few bytes (the ELF header and perhaps a few more bytes) are the same in both the correct and broken binary. The rest of the broken binary seems to be random bytes, then a lot of zeroes, then the strings at the end. But in the working binary, there are a lot of zeroes at the end, and the strings come before them.

Looking at "readelf -s ld" (ran under linux, on the glidix linker) I get:

Code: Select all

Symbol table '.dynsym' contains 95 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND putchar
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcpy
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND dlerror
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getgid
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf
     6: 00000000006f2900     8 OBJECT  GLOBAL DEFAULT   19 stdout
     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND vsprintf
     8: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strerror
     9: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memmove
    10: 0000000000486690     8 FUNC    GLOBAL DEFAULT    9 getopt_long
    11: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND snprintf
    12: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND pathconf
    13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getenv
    14: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND qsort
    15: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memcpy
    16: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts
    17: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getuid
    18: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND feof
    19: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND malloc
    20: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND isatty
    21: 00000000007f7698     8 OBJECT  GLOBAL DEFAULT   19 optarg
    22: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strtoul
    23: 00000000006f28ac     4 OBJECT  GLOBAL DEFAULT   18 opterr
    24: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fflush
    25: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND realpath
    26: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND lseek
    27: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND dlclose
    28: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND abort
    29: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND chmod
    30: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strtol
    31: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strrchr
    32: 0000000000401940     0 FUNC    GLOBAL DEFAULT  UND calloc
    33: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fstat
    34: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fprintf
    35: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcat
    36: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fseek
    37: 00000000006f28b0     4 OBJECT  GLOBAL DEFAULT   18 optind
    38: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memchr
    39: 00000000006f2908     8 OBJECT  GLOBAL DEFAULT   19 stdin
    40: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND umask
    41: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND lstat
    42: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ferror
    43: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strstr
    44: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND read
    45: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strncmp
    46: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND dlopen
    47: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strncpy
    48: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND unlink
    49: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND realloc
    50: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memcmp
    51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fdopen
    52: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __glidixrt_init
    53: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sscanf
    54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strncat
    55: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fread
    56: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND dlsym
    57: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strdup
    58: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fopen
    59: 00000000006f28e8     0 NOTYPE  GLOBAL DEFAULT   19 __bss_start
    60: 0000000000486680    13 FUNC    GLOBAL DEFAULT    9 getopt
    61: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memset
    62: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ftell
    63: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fclose
    64: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND time
    65: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcmp
    66: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getcwd
    67: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fgetc
    68: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sprintf
    69: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strcspn
    70: 00000000006f2910     8 OBJECT  GLOBAL DEFAULT   19 stderr
    71: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fputc
    72: 00000000006f28a8     4 OBJECT  GLOBAL DEFAULT   18 optopt
    73: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND stat
    74: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fwrite
    75: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND access
    76: 00000000006f28e8     0 NOTYPE  GLOBAL DEFAULT   18 _edata
    77: 00000000007f7cd8     0 NOTYPE  GLOBAL DEFAULT   19 _end
    78: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND rewind
    79: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _glidix_geterrnoptr
    80: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND exit
    81: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND atoi
    82: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fileno
    83: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _exit
    84: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strspn
    85: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strlen
    86: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND open
    87: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND clock
    88: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strchr
    89: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fputs
    90: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND fcntl
    91: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND close
    92: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND vfprintf
    93: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strpbrk
    94: 0000000000401ca0     0 FUNC    GLOBAL DEFAULT  UND free
And I see nothing else that could affect the file size. (yes, I see the vfprintf() call, but no debug messages show upon calls to it, so it is not called in my test case).

Any ideas on what else could be wrong?

And is there a way to trace which library calls my cross-compiling ld uses under Linux, so that I could compare?
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, have you tried running objdump on your OS ?

I think I compiled some object files with my cross-compiler and copied them to my OS machine. Then I checked whether objdump could read them on my OS. Objump is a simpler program and if you get it working first at least you know your binutils can read obj files correctly.
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, have you tried running objdump on your OS ?

I think I compiled some object files with my cross-compiler and copied them to my OS machine. Then I checked whether objdump could read them on my OS. Objump is a simpler program and if you get it working first at least you know your binutils can read obj files correctly.
Well, indeed objdump shows the correct disassembly of the object file. So it looks like it can read it. The only problem is the broken printf() which I finally got to fixing, so we'll see if there are any anomalies after it works.
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:Well, indeed objdump shows the correct disassembly of the object file. So it looks like it can read it. The only problem is the broken printf() which I finally got to fixing, so we'll see if there are any anomalies after it works.
That's great news. It's getting close. :)

Try objdump on some .a files as well. They have slightly different code paths.
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:That's great news. It's getting close. :)

Try objdump on some .a files as well. They have slightly different code paths.
OK now "objdump -d hello.o" shows the correct disassembly, but strangely, upon getting to the almost-end of the code, it receives a SIGSEGV (inside of my OS, not linux).

The relevant snippet (linux):

Code: Select all

  2e:	64                   	fs
  2f:	0a                   	.byte 0xa
And in glidix:

Code: Select all

  2e: Invalid memory access
I'm wondering if this even has anything to do with the ld problem.

But clearly there is some kind of libc problem that causes this.

EDIT: Furthermore, "ld" only writes to "hello", it never reads back what it has written. And since Glidix writes the requested data to the positions that ld has indeed seeked to using fseek(), it must either be misreading the hello.o file for some weird reason, or incorrectly writing structures to the executeable. I don't know why the structure definitions would be incorrect though, but "as" likewise produces strangely small and corrupt output. Perhaps it is some type definition in <sys/types.h> that is incorrect?
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

OH MY GOD
Is fseek() supposed to allow seeking past the end of the file?
E.g. a file is 100 bytes long but you seek to 300 and you write and the file is automatyically expanded?

Because uh:

Code: Select all

{fseek 528:0 in 5}
{fwrite 104+216 -> 5}
That looks like it actually tried writing to 528 but failed to do so.
Octocontrabass
Member
Member
Posts: 5512
Joined: Mon Mar 25, 2013 7:01 pm

Re: Debugging binutils under my OS?

Post by Octocontrabass »

mariuszp wrote:Is fseek() supposed to allow seeking past the end of the file?
This document says yes:
The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap.
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Debugging binutils under my OS?

Post by mariuszp »

Well, I have just fixed this subtle lseek() bug and suddenly, I can both assemble the code, and link it to create a working executable.
For some reason, "objdump" still receives the SIGSEGV though.
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, not just fseek() but also lseek().
The lseek() function shall allow the file offset to be set beyond the end of the existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap.
and
Although lseek() may position the file offset beyond the end of the file, this function does not itself extend the size of the file. While the only function in POSIX.1-2008 that may directly extend the size of the file is write(), truncate(), and ftruncate(), several functions originally derived from the ISO C standard, such as fwrite(), fprintf(), and so on, may do so (by causing calls on write()).
If a trainstation is where trains stop, what is a workstation ?
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:Well, I have just fixed this subtle lseek() bug and suddenly, I can both assemble the code, and link it to create a working executable.
For some reason, "objdump" still receives the SIGSEGV though.
Well done!
If a trainstation is where trains stop, what is a workstation ?
Post Reply