'Libary' problems, and syscalls.

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.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

'Libary' problems, and syscalls.

Post by piranha »

Hello, everyone.
This has been annoying me for a while.
I have implemented syscalls and am now testing binary file loading and libraries to use syscalls and etc.
Now, my problem:

I have (for now) set syscall 1 to be a sys_print function (to write a character to the screen). I also have a basic library to call that syscall:

Code: Select all

int putch(char c)
{
	asm("int $0x80"::"a"(1), "b"(c));
	return 1;
}
This is tested and works.

I also have a program (init.c) which does run on my OS. Now, I have made it print 'Hello' on the screen with a bunch of putch() calls. My problem function is this:

Code: Select all

int puts(char str[256])
{
	int i=0;
	while(str[i] != '\0')
	{
		putch(str[i]);
		i++;
	}
	return 1;
}
When I call this function, nothing appears on the screen after the 'Hello' print out.

Here is the main() function:

Code: Select all

int main_init()
{
	putch('H');putch('e');putch('l');putch('l');putch('o');putch('!');putch('\n');
        puts("Hello, Testing. Hello World!");
}
I can't figure it out!
It compiles with this:

Code: Select all

gcc -c -o init.o -nostdlib -nostdinc -I ../library/include -m32 init.c
ld -m elf_i386 --oformat binary -e main_init -o init -nostdlib init.o ../library/libc.o
Thanks,
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
ucosty
Member
Member
Posts: 271
Joined: Tue Aug 08, 2006 7:43 am
Location: Sydney, Australia

Post by ucosty »

Your code looks good so, and since you say the printing of individual letters works, it looks to me to be a problem in linking (rodata).
The cake is a lie | rackbits.com
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

Well, heres some more info that might help:
This here is my stdio.h file (which is included in init.c):

Code: Select all

extern int putch(char c);
extern int puts(char *str);
#define NULL 0
Here is how the library is built:

Code: Select all

gcc -c -o libc.o libc.c
ld libc.o -e libc_main -o libc.elf
Note: The entry libc_main isn't there. Problem?
And you may notice that I don't use the libc.elf file generated in linking. Should I?

My sys_print function:

Code: Select all

void sys_print(struct Register *regs)
{
	_printf("%c", regs->ebx);
}
How could I fix a linking problem? A linker script? What would I need to do?
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
ucosty
Member
Member
Posts: 271
Joined: Tue Aug 08, 2006 7:43 am
Location: Sydney, Australia

Post by ucosty »

piranha wrote:Well, heres some more info that might help:
This here is my stdio.h file (which is included in init.c):

Code: Select all

extern int putch(char c);
extern int puts(char *str);
#define NULL 0
Here is how the library is built:

Code: Select all

gcc -c -o libc.o libc.c
ld libc.o -e libc_main -o libc.elf
Note: The entry libc_main isn't there. Problem?
And you may notice that I don't use the libc.elf file generated in linking. Should I?
I don't think you can because you would be mixing executable types.
piranha wrote:My sys_print function:

Code: Select all

void sys_print(struct Register *regs)
{
	_printf("%c", regs->ebx);
}
How could I fix a linking problem? A linker script? What would I need to do?
-JL
I would create a linker script for you programs that would remove any ambiguity as to where you program contains data and code. I would also suggest reading up on ELF files as they are nice and flexible as well as being easy to read.
The cake is a lie | rackbits.com
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

What do I need to do in my linker script? I'm not too good at making linker scripts.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

One thing I notice is that you define/call your puts function 3 different ways.
puts ("char constant");
puts (char str[256]);
puts (char *str);

I think that sometimes mixing constants in this way can cause compiler goofs. I suspect that you get a warning, at least, already. I'm not sure this is actually a problem, though.
User avatar
ucosty
Member
Member
Posts: 271
Joined: Tue Aug 08, 2006 7:43 am
Location: Sydney, Australia

Post by ucosty »

I checked that in VS2005 and it didn't even produce a warning. I *think* that the array length is ignored as it doesn't limit the array access bounds at all.
The cake is a lie | rackbits.com
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: 'Libary' problems, and syscalls.

Post by Combuster »

piranha wrote:When I call this function, nothing appears on the screen after the 'Hello' print out.

Here is the main() function:

Code: Select all

int main_init()
{
	putch('H');putch('e');putch('l');putch('l');putch('o');putch('!');putch('\n');
        puts("Hello, Testing. Hello World!");
}
You say you have tested it with characters, but do punctuation and special characters work as well?
"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 ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Test 1:

putch('x') seems to work allright. Add a putch('x') as first statement to your puts() function to see puts() actually gets executed.

Test 2:

Check a hexdump of your binary to see if it actually contains your "Hello world" statement. If not, you're missing .rodata (as ucosty suspected).
Every good solution is obvious once you've found it.
DeletedAccount
Member
Member
Posts: 566
Joined: Tue Jun 20, 2006 9:17 am

Well ...

Post by DeletedAccount »

Hi , i also had the same problem once ... But it worked the after i replaced ur above code with something like this

Code: Select all


void put_str(char *str)
{
   char *str_ptr = str;
   while(*str_ptr != '\0')
   {
          putchar(*str_ptr);
          str_ptr++;
    }
}
I still do not know the reason for the glitch ... but it works this way ...
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

putch('x') seems to work allright. Add a putch('x') as first statement to your puts() function to see puts() actually gets executed.
I tried that, puts() is executed.
One thing I notice is that you define/call your puts function 3 different ways.
puts ("char constant");
puts (char str[256]);
puts (char *str);

I think that sometimes mixing constants in this way can cause compiler goofs. I suspect that you get a warning, at least, already. I'm not sure this is actually a problem, though.
OK, I now have that, heres the new code:

Code: Select all

	putch('H');putch('e');putch('l');putch('l');putch('o');putch('!');putch('!');putch('\n');
	char hw[16];
	hw[0] = 'W';
hw[1] = 'o';
hw[2] = 'r';
hw[3] = 'l';
hw[4] = 'd';
hw[5] = '\n';
	put_str(hw);
I know I waste space, but it's for testing. Anyway, the output:

Code: Select all

Hello!!
World
*
NOTE: Replace the star with a funny little arrow pointing to the right symbol.
Maybe the new function (the one recommended by SandeepMathew) calls putch() one too many times with a junk character at the end?
Yes, thats the problem. Actually, I need to append a \0 character.

OK, cool. It works now.
However, a const string don't (like put_str("Hello")).......can you give me tips on linker scripts? It is odd, seeing as a normal C program can use "..." but this one can't. Why is that?

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
ucosty
Member
Member
Posts: 271
Joined: Tue Aug 08, 2006 7:43 am
Location: Sydney, Australia

Post by ucosty »

String constants (like "Hello, world" and similar) are put in the .rodata section by GCC. Without a linker script the linker drops the section.

Here is an example linker script derived from the script on the FreeBasic barebones tutorial by combuster.

Code: Select all

OUTPUT_FORMAT("elf32-i386")
ENTRY (loader)

SECTIONS{
    . = 0x00100000;

    .text :{
        *(.text)
    }

    .data ALIGN (0x1000) : {
        *(.data)
        [b]*(.rodata)[/b]
    }

    .bss : {
        _sbss = .;
        *(.bss)
        _ebss = .;
    }
}
obviously you cant just drop this in and expect it to work. You'll have to at least change the entrypoint, output format and the link address to make it work with what your OS expects.
Last edited by ucosty on Thu Jan 31, 2008 2:34 am, edited 1 time in total.
The cake is a lie | rackbits.com
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I copied that script from one of those other tuts out there :wink:
"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 ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

piranha wrote:Maybe the new function (the one recommended by SandeepMathew) calls putch() one too many times with a junk character at the end?
Yes, thats the problem. Actually, I need to append a \0 character.
A \0 character is appended automatically when you use "...". A C coder of some repute should know that.
It is odd, seeing as a normal C program can use "..." but this one can't. Why is that?
See above - because you are missing the .rodata section (and so far, all hints that pointed in that direction).
Every good solution is obvious once you've found it.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

Solar wrote:
piranha wrote:Maybe the new function (the one recommended by SandeepMathew) calls putch() one too many times with a junk character at the end?
Yes, thats the problem. Actually, I need to append a \0 character.
A \0 character is appended automatically when you use "...". A C coder of some repute should know that.
It is odd, seeing as a normal C program can use "..." but this one can't. Why is that?
See above - because you are missing the .rodata section (and so far, all hints that pointed in that direction).
Well, I said that is a post where the code didn't use a "..." string. Plus appending a \0 character to the array I used worked.

Yes, I didn't know that ld drops the .rodata. So, now I'm a tryin' to fix that.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Post Reply