[solved] Newlib issues.
Posted: Sat Dec 17, 2011 10:07 pm
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:
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.
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;
}