[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
RE: sl_malloc is unportable (ITS#2551)
> -----Original Message-----
> From: owner-openldap-bugs@OpenLDAP.org
> [mailto:owner-openldap-bugs@OpenLDAP.org]On Behalf Of hyc@symas.com
> > -----Original Message-----
> > From: owner-openldap-bugs@OpenLDAP.org
> > [mailto:owner-openldap-bugs@OpenLDAP.org]On Behalf Of
> h.b.furuseth@usit.uio.no
>
> > Full_Name: Hallvard B Furuseth
> > Version: HEAD
> > OS:
> > URL:
> > Submission from: (NULL) (129.240.186.42)
> > Submitted by: hallvard
>
> > This test in sl_realloc() and sl_free() yields undefined behaviour:
> > /* Not our memory? */
> > if ( !sh || ptr < sh->h_base || ptr >= sh->h_end ) {
> > Also this in sl_release() and sl_context():
> > if ( sh && ptr >= sh->h_base && ptr <= sh->h_end ) {
> > The operators < <= > >= are only defined between two
> pointers into the
> > same block of memory. An example of how they can fail with pointers
> > to different blocks of memory is if a pointer consists of a segment
> > number and an offset into the segment, and an object cannot cross a
> > segment boundary. Then these operators need only compare
> the offsets,
> > they can ignore the segment numbers.
This is a flaw in the ANSI C specification. It's important not to lose sight
of practical considerations when delving into specs and theoretical
situations. The fact is that at the machine level, a pointer *must* fit in a
machine word. If it is larger than a machine word, then it can only be used
indirectly - i.e., you need a pointer to point to it. This is patently
ridiculous. As such, a compiler gains no performance advantage from
generating code that only compares a portion of a pointer against a portion
of another pointer. Generally this will be more expensive, because while a
single instruction can be used to compare one word to another, multiple
instructions would be required to mask off portions of a word before and
after the comparison.
Note that the objective isn't an ordering comparison here; it would be fine
with me to replace these comparisons with a macro:
#ifndef HAVE_NONLINEAR_MALLOC
#define SLAP_PTR_WITHIN(a,b,c) ((b)<=(a) && (a)<=(c))
#else
/* What goes here is up to whoever is unfortunate enough to be porting
* to such a broken compiler architecture. Some possibilities:
*
* segment/offset based malloc:
* SEGMENT_OF(a) == SEGMENT_OF(b)
*
* some other bizarre machine:
* memcmp(&a,&b,sizeof(a)) >= 0 && memcmp(&a,&c,sizeof(a)) <= 0)
*/
#error FixMe
#endif
Whether the architecture/compiler uses linear memory or not has no bearing on
whether we can or cannot distinguish our TL pointers from any other pointers.
As an aside, whether a system uses linear memory or not also should not have
any effect on the outcome of comparing two arbitrary pointers. At the machine
level, a word is a word is a word is a word.
> > So slapd needs an `#ifdef USE_SL_MALLOC' to be defined for
> > architectures
> > or architecture/compiler combinations where sl_malloc works.
> > Unfortunately I cannot think of a reliable configure test for this,
> > the best I can think of is to collect information about where
> > it works,
> > and hard-code #if tests for that into the code.
> -- Howard Chu
> Chief Architect, Symas Corp. Director, Highland Sun
> http://www.symas.com http://highlandsun.com/hyc
> Symas: Premier OpenSource Development and Support