MrSmith33 / vox

Vox language compiler. AOT / JIT / Linker. Zero dependencies
Boost Software License 1.0
327 stars 18 forks source link

weird bug that causes newlines not get printed #35

Closed rempas closed 2 years ago

rempas commented 2 years ago

This is a little bit weird and doesn't make any sense to begin with. So I will declare some variables and that will cause newlines (the "\n" character) to not get printed. I don't know if it is only newlines that will not get printed but newlines will not get printed for sure. So here is the code:

u8[10000] stdout_buffer;
u8[10000] stderr_buffer;
u16 stdout_index = 0;
u16 stderr_index = 0;

#version(linux) {
  /* read system call */
  enum u32 stdin = 0;
  @extern(syscall, 0)
  void sys_read(u32 fd, u8* buf, u64 count);

  /* write system call */
  enum u32 stdout = 1;
  enum u32 stderr = 2;
  @extern(syscall, 1)
  void sys_write(u32 fd, u8* buf, u64 count);
  void write(u8[] data) {
    sys_write(1, data.ptr, data.length);
  }
}

void main() {
  u8* num;
  num = to_str(32);
  sys_write(1, num, strlen(num));
  write("\n\n");

  num = to_str(-10);
  sys_write(1, num, strlen(num));
  write("\n\n"); // Ask this function if you don't have it

  exit(0);
}

This is some code I got from a previous error and I tested out. Now "to_str" just converts an integer to a u8* and then we got printing. If we uncomment the first 4 lines, the output will be as expected but when the lines get compiled, for some reason the newlines will not get printed.

MrSmith33 commented 2 years ago

Reproduced

MrSmith33 commented 2 years ago

Since string literals are stored in static memory, just like globals it should be related

rempas commented 2 years ago

Since string literals are stored in static memory, just like globals it should be related

Oh, I see! I'm glad you have an idea of what the problem is. As always, good luck!

MrSmith33 commented 2 years ago

the problem is with ELF64 executable.

The good version has 3 sections

Program Header:
  LOAD off    0x001000 vaddr 0x400000 paddr 0x0 align 2**12
       filesz 0x000066 memsz 0x000066 flags r-x
  LOAD off    0x002000 vaddr 0x401000 paddr 0x0 align 2**12
       filesz 0x000028 memsz 0x000028 flags rw-
  LOAD off    0x003000 vaddr 0x402000 paddr 0x0 align 2**12 <- .rdata
       filesz 0x000002 memsz 0x000002 flags r--

while bad version has 4 sections:

Program Header:
  LOAD off    0x001000 vaddr 0x400000 paddr 0x0 align 2**12
       filesz 0x000066 memsz 0x000066 flags r-x
  LOAD off    0x002000 vaddr 0x401000 paddr 0x0 align 2**12
       filesz 0x000028 memsz 0x000028 flags rw-
  LOAD off    0x003000 vaddr 0x402000 paddr 0x0 align 2**12 <- .data
       filesz 0x000000 memsz 0x000000 flags rw-
  LOAD off    0x004000 vaddr 0x403000 paddr 0x0 align 2**12 <- .rdata
       filesz 0x000002 memsz 0x000002 flags r--

and when I try to print string memory in the debugger it cannot access the memory in the bad version of the program.

The program correctly contains the reference to 0x0000000000402000 and 0x0000000000403000, so the problem is entirely in the ELF file.

MrSmith33 commented 2 years ago

Looks like the ELF file generation is a bit broken

MrSmith33 commented 2 years ago

Now it is correct

Program Header:
  LOAD off    0x001000 vaddr 0x400000 paddr 0x0 align 2**12
       filesz 0x000066 memsz 0x000066 flags r-x
  LOAD off    0x002000 vaddr 0x401000 paddr 0x0 align 2**12
       filesz 0x000028 memsz 0x000028 flags rw-
  LOAD off    0x003000 vaddr 0x402000 paddr 0x0 align 2**12 <- .data
       filesz 0x000000 memsz 0x000001 flags rw-
  LOAD off    0x003000 vaddr 0x403000 paddr 0x0 align 2**12 <- .rdata
       filesz 0x000002 memsz 0x000002 flags r--

The bug was that I was calculating address as if I was storing section in the file, but it didn't do it, because there was no data. So actually addresses were wrong. In the incorrect file actual data was stored at 0x003000, while ELF header said that data is at 0x004000, so loader just didn't load it.

rempas commented 2 years ago

You are so fast that you are challenging me to go even faster to finish my library!!! Thanks a lot for everything for one more time!