Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I am in long mode and I have a function put(char) which writes to the screen corretly no problems there. But I then have a function write(char *) which will not print the string correctly it prints nothing.
void write(char *c) {
int i = 0;
while(c[i]) {
put(c[i++]);
}
}
The function above prints nothing because c[0] is equal to zero when it should be if I pass it a string like "hello". I don't get a fault or anything just nothing gets printed. I found this in an objdump of my file and wonding if this could be a cause:
It has a push command meaning it should go in the .text section.
I also checked my binary out put file and the string is in the binary, since the string is in rodata and i put it after the .text section, then that is where it is, just don't know why its not working, becuase the linker is putting it in the binary.
Next, have you currently got any way of checking the value of the char *c is when "write" gets called? Perhaps use some inline asm to load this pointer value in to a register, terminate Bochs and view the Bochs register dump. Is that value what you expect it to be? Of course, once you get it working, you will want a few sanity checks at the start of the write function (like is c NULL).
To clarify the objdump thing, just because objdump can find opcodes which match the hex data "68 65 6c 6c 6f" (translating it to a pushfq instruction) does not mean that your kernel ever tries to run that as code. You will note that these hex values translate to "hello", which means that it is stored as it should be.
The offset to c is 0x1011f1, whereas in the binary its at 0x3f5 (which is 0x1003f5 in memory)
Right now I wonder why the padding doesn't get into the output binary...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Combuster, I looked at what you said and I had change my linker script to see if it would fix it, but of cource it did not, so I looked at the binary file again, and this is where the string is located:
I am not trying to do anything with va_arg macros, I am just trying to print a string, I am not trying to pass it a string that needs to be formated, with arguments.
I did take a look at some linux source, and the only difference I see is that the use (const char*) instead of mine being (char *), i made that change and that didn't fix anything.
Does anyone have a working 64-bit string printing function that I could look at?
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)
I have been looking at where the pointer points to and it points to the beginning of the string in memory, I am 100% sure of this, but no matter what I do to dereference that location I get zero, why?
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)
Try to disassemble the function that is generated by gcc.
EDIT: Are you sure the pages that contain the string are properly mapped?
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
I found out that the string that is passed through the function (example: write("hello");) the hello gets put in the .rodata section as a pushq command, which is weird the parameter is not a (const char *). I include the .rodata at the end of my .text secion linker and then my linker compiles it to binary.
Is that how it should be done? or should I change something in my linker script?
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)
No. The .rodata section ideally should be in its own section, .rodata, rather than .text, as mentioned at the start of the thread. It is not a pushq instruction, it just so happens that the hex for "hello" translates to that instruction when objdump tries to disassemble it because you put it in the wrong section, as mentioned before as well. See AJ's first post about the linker script.
EDIT: It was pointed out to me on IRC that .rodata should really be in its own section, as by definition it is read-only so shouldn't be in .data, which is read-write. Corrected.
Last edited by xyzzy on Sat Jun 21, 2008 4:43 am, edited 1 time in total.
Okay i understand about the jump command, but it still isn't working.
It doesn't matter what section I put it in, if i put it in .data is doesn't work, if i put it in its own section it doesn't work, if i put it in .text it doesn't work. they all get the same result.
If i get the address of the passed string it is correct:
0x1011F1 - (0x100000 "Loaded Address") = 0x11F1
Checked with hex editor:
0x11F1 | 68 65 6C 6C 6F 00 < "h e l l o \0"
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)