This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Porting 1.14.0 to new OS
- From: Anders Lindgren <ali at df dot lth dot se>
- To: newlib at sources dot redhat dot com
- Date: Thu, 13 Jul 2006 18:13:08 +0200 (CEST)
- Subject: Porting 1.14.0 to new OS
I am porting newlib to a new OS and have successfully created my own
cross-toolchain and cross-built newlib (with stub syscalls) from within the GCC
build for my new target. Now I am looking into the details of how to replace
the stubs in sys/MyOS with real syscalls, and finishing things up.
I think I've managed to get my head around most of the configuration and
knobs, but I'd appreciate some help with the details. I am building a
multithreaded newlib, with __DYNAMIC_REENT__ so I don't need to modify the
(single memory space) kernel's thread-switching:
o It is my understanding that some dummy files in newlib should be
overridden by placing files with the same name in my sys/MyOS dir:
reent/impure.c (libc TLS data for "MyOS"), reent/getreent.c
(replace dummy __getreent()) and <sys/lock.h> (dummy lock defines).
Is this the Right(tm) way to implement the multithread support, i.e.
will C files and includes in my sys/MyOS dir override newlib's
corresponding default stubs? Are there other files I need to override?
o To skip one layer of indirection, one can supply reentrant
versions of libc syscalls (open, close etc) directly and define
MISSING_SYSCALL_NAMES, make syscall_dir empty in configure.host
(Linux does this?) and thus avoid getting stubs that only call
_open_r etc anyway -- correct? Is there any reason I shouldn't
do this?
o I understand _GLOBAL_REENT is only used to hold truly global data
such as potentially shared FILE pointers that shouldn't be cleaned up
when only a single thread exits, and that my __getreent()
implementation should arrange for each new thread to have its own
_reent structure allocated as needed. This brings up the question of
_impure_ptr, _global_impure_ptr and _reclaim_reent(): I don't quite
understand _reclaim_reent() in reent/reent.c:48 -- _impure_ptr is
referenced explicitly, which seems wrong in a __DYNAMIC_REENT__ newlib.
If it is meant to compare against the global _reent it should've been
_GLOBAL_REENT (or at least _global_reent_ptr) -- but doing so would
effectively turn the cleanup in stdlib/exit.c into a nop? Or is that
what the comment about not returning malloc()'d memory is about?)
o _wrapup_reent()/_reclaim_reent() aren't referenced anywhere afaict. I
take it these are utility routines provided for my convenience, to be
called in my thread implementation's thread-cleanup code?
o I was under the impression that in a __DYNAMIC_REENT__ newlib,
_impure_ptr shouldn't even be defined at all, since all references
to _reents should go through _REENT (== __getreent()) or _GLOBAL_REENT
(which will only equal _impure_ptr in a single-threaded or
!__DYNAMIC_REENT_ newlib). Please explain this relationship between
_impure_ptr, _global_impure_ptr and _reclaim_reent(). It sounds like
a pretty important, race condition prone thing I certainly don't want
to get wrong! :-)
Ok, quite a few questions and clarification points at once, but I hope you at
least find them reasonably informed questions -- I've tried to dig through the
source and mailing lists[0] thoroughly, and appreciate any answers the list may
have -- I really want to understand newlib internals properly.
[0] And many thanks to Jeff for all of his excellent and patient answers
on the list, which have contributed the bulk of my so far accumulated
understanding of newlib's internals.
Best Regards,
Anders "ali" Lindgren