printf() problem with ported NewLib

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
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: printf() problem with ported NewLib

Post by IanSeyler »

This is for running an application. The kernel is written in Assembly which is why I'm struggling with the C / NewLib apps.

I'm pretty sure its a sbrk() issue... I think BSS is getting zero'd now.

crt0.c

Code: Select all

extern int main(int argc, char **argv, char **environ);

extern char __bss_start, _end; // BSS should be the last think before _end

// XXX: environment
char *__env[1] = { 0 };
char **environ = __env;

_start()
{
	char *i;

	write(1, "trololo\n", 8);

	// zero BSS
	for(i = &__bss_start; i < &_end; i++)
	{
		*i = 0; 
	} 

	// XXX: get argc and argv

	main(0,0, __env);

	return 0;
}
test.c

Code: Select all

#include <stdio.h>

char tempstring[32];

int main()
{
	printf("NewLib Test Application\n=======================\n");
	printf("%s %d\n", "Output:", 1234);
	printf("Enter some text: ");
	fgets(tempstring, 32, stdin);			// Get up to 32 chars from the keyboard
	printf("You entered: '%s'", tempstring);
}
app.ld

Code: Select all

OUTPUT_FORMAT("binary")
OUTPUT_ARCH("i386:x86-64")
ENTRY(main)
SECTIONS
{
        . = 0x0000000000200000;
        .text : { *(.text) }
        .data : { *(.data .rodata) QUAD(ADDR(.bss)+SIZEOF(.bss)) }
	__bss_start = .;
        .bss : { *(.bss) }
        end = .; _end = .; __end = .;
}
Compile:

Code: Select all

gcc -I newlib-2.0.0/newlib/libc/include/ -c crt0.c -o crt0.o
gcc -I newlib-2.0.0/newlib/libc/include/ -c test.c -o test.o
ld -T app.ld -o test.app crt0.o test.o libc.a
The app runs with some of the output missing still. Is that valid for clearing BSS? Can the -fno-zero-initialized-in-bss flag be used instead?
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: printf() problem with ported NewLib

Post by bluemoon »

Instead of putting bss_start/end marker on the application, I clear the BSS from the loader with:

Code: Select all

if ( elf_phdr->p_filesz < elf_phdr->p_memsz ) {
    memset ( (void*)(seg->base + elf_phdr->p_filesz), 0, elf_phdr->p_memsz - elf_phdr->p_filesz);
}
BSS should be on such region.

Anyway, your way seems worked too, is sbrk called with sane parameter?
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: printf() problem with ported NewLib

Post by IanSeyler »

Is this accurate?:

Code: Select all

int x[256] = {0}; //this compiles to .bss
int y[256] = {1}; //this compiles to .data
In this case if I do a "printf("%d", x[0]);" without clearing BSS, I get a random value back. If I include the crt0.c I mentioned earlier then I get the correct value of '0' printed to the screen.

Checking into sbrk()...
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: printf() problem with ported NewLib

Post by IanSeyler »

Just a quick followup.. it appears that "-fno-zero-initialized-in-bss" does work.
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: printf() problem with ported NewLib

Post by IanSeyler »

I found the bug. write() was set to always return 0 instead of 'len'. Such a rookie mistake. :oops:

printf("Hello1\nHello2\nHello3\n"); results in 3 separate calls to write(). Since the first call to write() would succeed (but return that it failed) it would not continue with the rest of the string.
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Post Reply