Open Vogtinator opened 6 months ago
The _getentropy
issue is because in the newer version of Newlib, the headers declare arc4random
/getentropy
and libstdc++ detects it during configuration. This was supposed to fix it (by doing a compile+link test, not just compile) but doesn't work here because linking isn't possible. One solution is to include a _getentropy
stub that fails and sets errno=ENOSYS
, but the arc4random
function will still be included in that case. The other solution is to remove arc4random
/getentropy
from the Newlib headers before building GCC.
The more concerning issue is that after fixing the above issue, the newlib-c++
sample crashes because std::cout
is not initialized, due to this change (more description here). The __ioinit
object is not brought in at link time. This seems like possibly a bug in libstdc++
.
The new version of ld gives a warning about a "LOAD segment with RWX permissions," this can be suppressed with --no-warn-rwx-segments
. It's also possible to have this warning suppressed by default by setting --enable-warn-rwx-segments=no
at configure time.
nSDL seems to work fine for me without --enable-newlib-reent-binary-compat
.
The _getentropy issue is because in the newer version of Newlib, the headers declare arc4random/getentropy and libstdc++ detects it during configuration. This was supposed to fix it (by doing a compile+link test, not just compile) but doesn't work here because linking isn't possible. One solution is to include a _getentropy stub that fails and sets errno=ENOSYS, but the arc4random function will still be included in that case. The other solution is to remove arc4random/getentropy from the Newlib headers before building GCC.
What actually pulls in the randomness functions? The program doesn't use std::random_device directly, but somehow ends up needing it.
The more concerning issue is that after fixing the above issue, the newlib-c++ sample crashes because std::cout is not initialized, due to this change (more description here). The __ioinit object is not brought in at link time. This seems like possibly a bug in libstdc++.
The init_array content was in a separate section not handled by the linker script and startup code. Should be fixed.
The new version of ld gives a warning about a "LOAD segment with RWX permissions," this can be suppressed with --no-warn-rwx-segments. It's also possible to have this warning suppressed by default by setting --enable-warn-rwx-segments=no at configure time.
Hm, maybe we should try to make .text separate from data:
diff --git a/ndless-sdk/system/ldscript b/ndless-sdk/system/ldscript
index 5ff03eb..8c7a3bf 100644
--- a/ndless-sdk/system/ldscript
+++ b/ndless-sdk/system/ldscript
@@ -1,5 +1,10 @@
ENTRY(_start)
+PHDRS {
+ text PT_LOAD;
+ data PT_LOAD;
+}
+
SECTIONS {
.text 0x0 : {
_start = .;
@@ -10,13 +15,13 @@ SECTIONS {
KEEP(*(.fini_array))
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
*(.text.*)
- }
+ } :text
.got : {
*(.got.plt*)
*(.got)
LONG(0xFFFFFFFF)
- }
+ } :data
.data : {
*(.rodata*)
genzehn doesn't care about segments so it's pretty much a noop though.
What actually pulls in the randomness functions? The program doesn't use std::random_device directly, but somehow ends up needing it.
This, apparently.
The init_array content was in a separate section not handled by the linker script and startup code. Should be fixed.
Yes, that fixes it.
What actually pulls in the randomness functions? The program doesn't use std::random_device directly, but somehow ends up needing it.
This, apparently.
That looks like the other way around: It's pulled in if old (pre-C++11) std::string
is passed to std::random_device
.
What actually pulls in the randomness functions? The program doesn't use std::random_device directly, but somehow ends up needing it.
This, apparently.
That looks like the other way around: It's pulled in if old (pre-C++11)
std::string
is passed tostd::random_device
.
Nope, you're correct - I missed that #include "string-inst.cc"
isn't a header but a whole massive source file. Apparently it's pulled in by some objects which also provide non-cow std::string
. If that's not the case for the non-cow c++11 and later std::string
, I'd like to just disable the old cow string ABI, but apparently there's only an option to disable the new ABI :-/
Maybe building libstdc++ with -ffunction-sections
helps, trying that now. The documentation lists it as one of the Fun flags to try
:grin: (https://gcc.gnu.org/onlinedocs/gcc-14.1.0/libstdc++/manual/manual/configure.html)
What actually pulls in the randomness functions? The program doesn't use std::random_device directly, but somehow ends up needing it.
This, apparently.
That looks like the other way around: It's pulled in if old (pre-C++11)
std::string
is passed tostd::random_device
.Nope, you're correct - I missed that
#include "string-inst.cc"
isn't a header but a whole massive source file. Apparently it's pulled in by some objects which also provide non-cowstd::string
. If that's not the case for the non-cow c++11 and laterstd::string
, I'd like to just disable the old cow string ABI, but apparently there's only an option to disable the new ABI :-/Maybe building libstdc++ with
-ffunction-sections
helps, trying that now. The documentation lists it as one of theFun flags to try
😁 (https://gcc.gnu.org/onlinedocs/gcc-14.1.0/libstdc++/manual/manual/configure.html)
No, doesn't. Probably because of the static constructor which ends up in the .elf before sections get GC'd.
I played around with the newlib-c++ bloat a bit and I don't think there's much we can effectively do. Even avoiding the random stuff by force only gets rid of ~20K which isn't really worth it. <iostream>
is just incredibly heavy.
I think SDL_image has to be rebuilt.
Might need nSDL rebuilt, could also drop
--enable-newlib-reent-binary-compat
then.For some reason, the
newlib-c++
sample pulls in arc4random which requires_getentropy
and is massive. Needs investigation why.