Page 1 of 1

[solved] Newlib issues.

Posted: Sat Dec 17, 2011 10:07 pm
by RobertF
I've had this problem for quite a while now, and need a little push in the right direction: I've been porting newlib for a while now, and I have a problem with calling functions that call the system calls (printf, fopen, bread, etc.) Whenever these functions are referenced anywhere in the code, whether they're called or not, the program will page fault at an address outside of what is contained in the program. When functions like rand() are called, the program executes and exits fine, as well as when system calls are called.

Is it possible that I'm loading the ELF wrong? Maybe linking libc.a wrong? (Thinking of these two things myself, I've read over the ELF format manual again, but I'm still getting the same result, but maybe I'm missing something simple here).

Also, it seems that if I undefine errno and redefine it as an extern int or make __environ null, the address at which I page fault will change.

Prior to now, I had all the system calls set up, but right now I'm running a fresh build of newlib with a target of i586-elf. Currently, if I call fopen(), located at 0x08048170, I will page fault at 0xA00A316C, although I highly doubt this is relevant. Also, I checked 0x0848170 to see if there is code residing there; there is.

Edit:
Here is the relevant code:

Code: Select all

int krun(u8int *name) {
    int fd = kopen(name); 
    Elf32_Ehdr *ehdr = kmalloc(sizeof(Elf32_Ehdr*));
    read(fd, ehdr, sizeof(Elf32_Ehdr));
    
    if (ehdr->e_ident[0] != 0x7F || ehdr->e_ident[1] != 'E' || ehdr->e_ident[2] != 'L' || ehdr->e_ident[3] != 'F') {
        kfree(ehdr);
        return -1; 
    }

    int pheaders    = ehdr->e_phnum;
    int phoff       = ehdr->e_phoff;
    int phsize      = ehdr->e_phentsize;
    
    int sheaders    = ehdr->e_shnum;
    int shoff       = ehdr->e_shoff;
    int shsize      = ehdr->e_shentsize; 
        
    for (int i = 0; i < pheaders; i++) {
        lseek(fd, phoff + phsize * i, SEEK_SET);
        
        Elf32_Phdr *phdr = kmalloc(sizeof(Elf32_Phdr*));
        read(fd, phdr, sizeof(Elf32_Phdr)); 
        
        u32int page = PMMAllocPage();
        
        int flags = 0; 
        if (phdr->p_flags & PF_R) flags |= PAGE_PRESENT;
        if (phdr->p_flags & PF_W) flags |= PAGE_WRITE; 
        
        int pages = (phdr->p_memsz / 0x1000) + 1;
        while (pages >= 0) {
            u32int mapaddr = (phdr->p_vaddr + (pages * 0x1000)) & 0xFFFFF000; 
            map(mapaddr, page, flags | PAGE_USER); 
            pages--; 
        }
                    
        lseek(fd, phdr->p_offset, SEEK_SET);
        read(fd, (void *)phdr->p_vaddr, phdr->p_filesz);   

        kfree(phdr);
    }
   
    // Removed: code block that zeroes .bss: it's already zeroed whenever I check it anyways
    // Removed: code block that creates thread and adds it to scheduler 

    kfree(ehdr);                
    return 0;
}
I found that if I make a system call, like write, and then I call printf two or more times, I will get an unknown opcode exception. Strange.

Re: Newlib issues

Posted: Sun Dec 18, 2011 3:31 am
by Muneer
Did you zero the BSS. When I tried porting newlib to my os I found out bugs in my Elf-loader.
Advice: Double check your Elf-loader.

Re: Newlib issues

Posted: Sun Dec 18, 2011 12:52 pm
by RobertF
HardCoder wrote:Did you zero the BSS. When I tried porting newlib to my os I found out bugs in my Elf-loader.
Advice: Double check your Elf-loader.
I wasn't zeroing the BSS; but now that I am, it didn't make a difference.
I checked my ELF loader and can't find anything else wrong/missing.

Re: Newlib issues [edited]

Posted: Tue Dec 20, 2011 2:10 pm
by RobertF
Well, I feel silly. Mapping with the same page for each 0x1000 bytes of the program segment was the issue. Allocating a different page and mapping that each time fixed it.