Message ID | 20101229191700.GA8483@pld-linux.org |
---|---|
State | Rejected |
Headers | show |
On Wed, Dec 29, 2010 at 08:17:01PM +0100, Przemyslaw Iskra wrote: > On Wed, Dec 29, 2010 at 03:59:21PM +0100, acrux wrote: > > > > hi all, > > it seems that yaboot (1.3.16) does not compile against e2fsprogs > 1.41.12 > > It could be the new (from e2fsprogs-1.41.13): > > Added a new function to the ext2fs library, ext2fs_get_memalign(). > > attached patch could help, but note it is completely untested. Thanks. for the help a few comments inline below. I sent my version of the patch for testing and comparison. > Subject: [PATCH] Added posix_memalign() and memalign() functions. > > Adding those missing functions should solve compilation problems with > recent e2fsprogs. > > Signed-off-by: Przemysław Iskra <sparky@pld-linux.org> > --- > include/stdlib.h | 4 +- > lib/malloc.c | 66 +++++++++++++++++++++++++++++++++-------------------- > 2 files changed, 43 insertions(+), 27 deletions(-) > > diff --git a/include/stdlib.h b/include/stdlib.h > index 0b5e99a..55707e4 100644 > --- a/include/stdlib.h > +++ b/include/stdlib.h > @@ -11,10 +11,10 @@ extern void malloc_init(void *bottom, unsigned long size); > extern void malloc_dispose(void); > > extern void *malloc(unsigned int size); > +extern void *memalign(unsigned int alignment, unsigned int size); > +int posix_memalign(void **memptr, unsigned int alignment, unsigned int size); I think we only need posix_memalign() at this point. > extern void *realloc(void *ptr, unsigned int size); > extern void free (void *m); > -extern void mark (void **ptr); > -extern void release (void *ptr); No need to remove these. > extern int sprintf(char * buf, const char *fmt, ...); > extern int vsprintf(char *buf, const char *fmt, va_list args); > diff --git a/lib/malloc.c b/lib/malloc.c > index 81d7717..e9256b7 100644 > --- a/lib/malloc.c > +++ b/lib/malloc.c > @@ -1,6 +1,7 @@ > /* malloc.c - Dumb memory allocation routines > * > - * Copyright (C) 1997 Paul Mackerras > + * Copyright (C) 2010 Przemyslaw Iskra > + * 1997 Paul Mackerras > * 1996 Maurizio Plaza > * 1996 Jakub Jelinek > * > @@ -42,22 +43,51 @@ void malloc_dispose(void) > last_alloc = 0; > } > > -void *malloc (unsigned int size) > +int posix_memalign(void **memptr, unsigned int alignment, unsigned int size) > { > char *caddr; > > if (!malloc_ptr) > - return NULL; > - if ((malloc_ptr + size + sizeof(int)) > malloc_top) { > + return -1; /* should return ENOMEM */ We really need this to return ENOMEM, if we don't we'll break the callers (ie e2fsprogs) > + > + if (alignment < sizeof(void*) ) > + alignment = sizeof(void*); /* should return EINVAL */ No I think POSIX is reasonably clear that your code is right (but the comment is wrong). > + /* must be a power of 2 */ > + if ((alignment & (alignment - 1)) != 0) > + alignment = sizeof(long long); /* should return EINVAL */ Umm that's not the meaning of alignment. > + > + if ((malloc_ptr + size + alignment) > malloc_top) { > prom_printf("malloc failed\n"); malloc didn't fail posix_memalign() failed. > - return NULL; > + return -1; /* ENOMEM */ As above. > } > - *(int *)malloc_ptr = size; > - caddr = malloc_ptr + sizeof(int); > - malloc_ptr += size + sizeof(int); > + alignment--; > + malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + sizeof(int) + alignment) & (~alignment)); > + ((int *)malloc_ptr)[-1] = size; > + caddr = malloc_ptr; > + malloc_ptr += size; > last_alloc = caddr; > - malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + 3) & (~3)); > - return caddr; > + *memptr = caddr; > + return 0; > +} > + > +void *malloc (unsigned int size) > +{ > + void *ptr; > + > + if ( posix_memalign( &ptr, sizeof(void*), size ) != 0 ) > + return NULL; > + > + return ptr; > +} > + > +void *memalign (unsigned int alignment, unsigned int size) > +{ > + void *ptr; > + > + if ( posix_memalign( &ptr, alignment, size ) != 0 ) > + return NULL; > + > + return ptr; > } > > void *realloc(void *ptr, unsigned int size) > @@ -86,21 +116,7 @@ void free (void *m) > if (!malloc_ptr) > return; > if (m == last_alloc) > - malloc_ptr = (char *) last_alloc - sizeof(int); > -} > - > -void mark (void **ptr) > -{ > - if (!malloc_ptr) > - return; > - *ptr = (void *) malloc_ptr; > -} > - > -void release (void *ptr) > -{ > - if (!malloc_ptr) > - return; > - malloc_ptr = (char *) ptr; > + malloc_ptr = (int*) last_alloc - 1; I'm pretty sure that's not right, you'll be setting the address of the next allocation to the length of the last one? Yours Tony
diff --git a/include/stdlib.h b/include/stdlib.h index 0b5e99a..55707e4 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -11,10 +11,10 @@ extern void malloc_init(void *bottom, unsigned long size); extern void malloc_dispose(void); extern void *malloc(unsigned int size); +extern void *memalign(unsigned int alignment, unsigned int size); +int posix_memalign(void **memptr, unsigned int alignment, unsigned int size); extern void *realloc(void *ptr, unsigned int size); extern void free (void *m); -extern void mark (void **ptr); -extern void release (void *ptr); extern int sprintf(char * buf, const char *fmt, ...); extern int vsprintf(char *buf, const char *fmt, va_list args); diff --git a/lib/malloc.c b/lib/malloc.c index 81d7717..e9256b7 100644 --- a/lib/malloc.c +++ b/lib/malloc.c @@ -1,6 +1,7 @@ /* malloc.c - Dumb memory allocation routines * - * Copyright (C) 1997 Paul Mackerras + * Copyright (C) 2010 Przemyslaw Iskra + * 1997 Paul Mackerras * 1996 Maurizio Plaza * 1996 Jakub Jelinek * @@ -42,22 +43,51 @@ void malloc_dispose(void) last_alloc = 0; } -void *malloc (unsigned int size) +int posix_memalign(void **memptr, unsigned int alignment, unsigned int size) { char *caddr; if (!malloc_ptr) - return NULL; - if ((malloc_ptr + size + sizeof(int)) > malloc_top) { + return -1; /* should return ENOMEM */ + + if (alignment < sizeof(void*) ) + alignment = sizeof(void*); /* should return EINVAL */ + /* must be a power of 2 */ + if ((alignment & (alignment - 1)) != 0) + alignment = sizeof(long long); /* should return EINVAL */ + + if ((malloc_ptr + size + alignment) > malloc_top) { prom_printf("malloc failed\n"); - return NULL; + return -1; /* ENOMEM */ } - *(int *)malloc_ptr = size; - caddr = malloc_ptr + sizeof(int); - malloc_ptr += size + sizeof(int); + alignment--; + malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + sizeof(int) + alignment) & (~alignment)); + ((int *)malloc_ptr)[-1] = size; + caddr = malloc_ptr; + malloc_ptr += size; last_alloc = caddr; - malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + 3) & (~3)); - return caddr; + *memptr = caddr; + return 0; +} + +void *malloc (unsigned int size) +{ + void *ptr; + + if ( posix_memalign( &ptr, sizeof(void*), size ) != 0 ) + return NULL; + + return ptr; +} + +void *memalign (unsigned int alignment, unsigned int size) +{ + void *ptr; + + if ( posix_memalign( &ptr, alignment, size ) != 0 ) + return NULL; + + return ptr; } void *realloc(void *ptr, unsigned int size) @@ -86,21 +116,7 @@ void free (void *m) if (!malloc_ptr) return; if (m == last_alloc) - malloc_ptr = (char *) last_alloc - sizeof(int); -} - -void mark (void **ptr) -{ - if (!malloc_ptr) - return; - *ptr = (void *) malloc_ptr; -} - -void release (void *ptr) -{ - if (!malloc_ptr) - return; - malloc_ptr = (char *) ptr; + malloc_ptr = (int*) last_alloc - 1; } char *strdup(char const *str)