Broken Newlib Program
Re: Broken Newlib Program
Why are you loading the code to 0xffff800000000000, though? You could load it to 0xffffffff80000000, have 2GB of address space left to play with (really ought to be enough for anyone), and compile with -mcmodel=kernel. Might save you a headache or two. And dynamic allocation can be outside of that range.
Carpe diem!
-
- Member
- Posts: 31
- Joined: Sun Nov 05, 2017 2:29 pm
- Libera.chat IRC: tay10r
- Location: Middleboro, MA
Re: Broken Newlib Program
That link to the manual is a good tip, I should probably read the rest of it! Thanks for your help! It was definitely helpful. Yes, app.ld is the one on the GitHub repo.simeonz wrote:I wouldn't have picked up on that myself. Not by looking at the script, to be honest. (Is it app.ld from github?) The manual kind-of warns about this issue, but sends perplexing message with the round-about solution it offers. Your approach seems more stable. In case you're wondering, the relevant documentation snippet I am talking about is in the bottom half of this page. Anyway - sorry for not being very helpful. Glad you figured it on your own.
I'm a contributor to BareMetal OS. View it at https://github.com/ReturnInfinity/BareMetal-OS
-
- Member
- Posts: 31
- Joined: Sun Nov 05, 2017 2:29 pm
- Libera.chat IRC: tay10r
- Location: Middleboro, MA
Re: Broken Newlib Program
Not sure what headaches I'd be avoided. The address range wasn't my choice but I don't really see what's wrong with it. You might have to explain that to me a bit more.nullplan wrote:Why are you loading the code to 0xffff800000000000, though? You could load it to 0xffffffff80000000, have 2GB of address space left to play with (really ought to be enough for anyone), and compile with -mcmodel=kernel. Might save you a headache or two. And dynamic allocation can be outside of that range.
I'm a contributor to BareMetal OS. View it at https://github.com/ReturnInfinity/BareMetal-OS
Re: Broken Newlib Program
Large memory model means "make no assumptions about symbol values". This means that the compiler has to generate code that can deal with any address for all external symbols. So, if you want to call an external function, direct relative call is right out, because that only works within 2GB of the instruction.
So all calls to external functions end up like
Not nice, since it needs one more register. And not really tested, since all the world uses the small and kernel models (who needs more than 2GB static allocation?). While I don't know of any bugs, I have learned to be wary of uncommon options in complex external components, like the compiler and the binutils.
Kernel memory model means "all link/load time symbols are between -2GB and 0", so now the compiler can generate a relative direct call to external functions again, since it knows that the instruction and its target will be within 2GB of each other.
So all calls to external functions end up like
Code: Select all
movq $printf, %rax
callq *%rax
Kernel memory model means "all link/load time symbols are between -2GB and 0", so now the compiler can generate a relative direct call to external functions again, since it knows that the instruction and its target will be within 2GB of each other.
Carpe diem!
-
- Member
- Posts: 31
- Joined: Sun Nov 05, 2017 2:29 pm
- Libera.chat IRC: tay10r
- Location: Middleboro, MA
Re: Broken Newlib Program
All of the kernel and Alloy functions are in the 0x1xxxxx range. Applications need to be able to call functions in this address range. There is no system call interface, they have to be called directly. I believe that requires us to use a large memory model.nullplan wrote:Large memory model means "make no assumptions about symbol values". This means that the compiler has to generate code that can deal with any address for all external symbols. So, if you want to call an external function, direct relative call is right out, because that only works within 2GB of the instruction.
I believe the register can be used in between function calls though, right?nullplan wrote: Not nice, since it needs one more register.
I would like to see the degree at which this impacts performance, out of curiosity.
I agree with you on this.nullplan wrote: And not really tested, since all the world uses the small and kernel models (who needs more than 2GB static allocation?). While I don't know of any bugs, I have learned to be wary of uncommon options in complex external components, like the compiler and the binutils.
For a while, I was actually starting to suspect that this was a corner case bug in GCC.
I see your point now.nullplan wrote: Kernel memory model means "all link/load time symbols are between -2GB and 0", so now the compiler can generate a relative direct call to external functions again, since it knows that the instruction and its target will be within 2GB of each other.
I think this is something that we'll keep in mind when we begin profiling and optimizing the software.
I don't think I'll begin to look at that until there is a working end-point application (like a web server or something.)
We're a little off topic at this point, since the newlib port works now.
If you'd like to talk more about it, then you can reach me on Keybase or open a GitHub issue.
Thanks!
I'm a contributor to BareMetal OS. View it at https://github.com/ReturnInfinity/BareMetal-OS