Mail Archives: djgpp-workers/2013/11/25/18:20:50
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
X-Recipient: | djgpp-workers AT delorie DOT com
|
Message-ID: | <5293DBB3.6020501@gmx.de>
|
Date: | Tue, 26 Nov 2013 00:22:27 +0100
|
From: | Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
|
User-Agent: | Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0
|
MIME-Version: | 1.0
|
To: | djgpp-workers AT delorie DOT com
|
Subject: | Wrong order of memalign arguments
|
X-Provags-ID: | V03:K0:at0kz5jMWtKyVTyFlfohVTGC5p4sa8I/Wf1uEutaTUM4WO0LiII
|
| QsLXy5Ack/LwwKhpLzFqUZ9Q5k9R9X8UICrec1B/CiYOVO733sXUW01Tt/C/bpLtzpfP0L/
|
| A3N33VsZAIx0Q6oB0TDRpp304V5LEzb8udynNlBYBcu8v6qrhY8Ih+HTvClIQdP18+wt6CR
|
| g0ZKqO0MDSnDuOA04fwEA==
|
Reply-To: | djgpp-workers AT delorie DOT com
|
As Rugxulo pointed out a couple of days before there is a very serious bug in
memalign. It concerns the reversed order of memalign arguments. From the very
first check in of this file, the function arguments were swapped. I am not
familiar enough with unix and bsd history, so I do not know if the reversed
argument order was ever the right order. According to my linux man page this
is not the case.
The second issue is if memalign should still be declared in stdlib.h. AFAIK
newlib does not provide it at all. It provides posix_memalign instead and
linux declares memalign in malloc.h (or in stdlib.h if _BSD_SOURCE is defined).
The swapped arguments in mealign is a serious bug and must be fixed. If
the declaration of memalign shall be moved from stdlib.h to malloc.h may
be objectionable.
The patch below provides a fix for memalign and valloc. Also it provides
small test cases for both functions.
As usual suggestions, objections, comments are welcome.
Regards,
Juan M. Guerrero
2013-11-25 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* djgpp/tests/libc/compat/malloc/makefile: Added memalign check.
* djgpp/tests/libc/compat/malloc/memalign.c: Check memalign function.
* djgpp/tests/libc/compat/stdlib/makefile: Added valloc check.
* djgpp/tests/libc/compat/stdlib/valloc.c: Check valloc function.
2013-11-24 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* djgpp/include/malloc.h: memalign declaration added.
* djgpp/include/stdlib.h: memalign declaration moved to malloc.h.
* djgpp/src/libc/compat/stdlib/memalign.c: Switch the argument sequence
in the memalign definition.
* djgpp/src/libc/compat/stdlib/memalign.txh: Switch the argument sequence
in the memalign definition and include malloc.h instead of stdlib.h.
* djgpp/src/libc/compat/stdlib/valloc.c: Switch the argument sequence
in the memalign call.
diff -aprNU5 djgpp.orig/include/malloc.h djgpp/include/malloc.h
--- djgpp.orig/include/malloc.h 2012-09-23 07:49:10 +0100
+++ djgpp/include/malloc.h 2013-11-24 23:12:22 +0100
@@ -1,5 +1,6 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#ifndef __dj_include_malloc_h_
#define __dj_include_malloc_h_
@@ -17,10 +18,11 @@ extern "C" {
#ifndef __STRICT_ANSI__
#ifndef _POSIX_SOURCE
#include <stdlib.h>
+void *memalign(size_t _align, size_t _amt);
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
diff -aprNU5 djgpp.orig/include/stdlib.h djgpp/include/stdlib.h
--- djgpp.orig/include/stdlib.h 2012-09-23 07:49:12 +0100
+++ djgpp/include/stdlib.h 2013-11-24 23:12:22 +0100
@@ -1,5 +1,6 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
@@ -130,11 +131,10 @@ char * getpass(const char *_prompt);
int getlongpass(const char *_prompt, char *_buffer, int _max_len);
char * itoa(int _value, char *_buffer, int _radix);
long jrand48(unsigned short _state[3]);
void lcong48(unsigned short _param[7]);
unsigned long lrand48(void);
-void * memalign (size_t _amt, size_t _align);
long mrand48(void);
unsigned long nrand48(unsigned short _state[3]);
unsigned short *seed48(unsigned short _state_seed[3]);
void srand48(long _seedval);
int stackavail(void);
diff -aprNU5 djgpp.orig/src/libc/compat/stdlib/memalign.c djgpp/src/libc/compat/stdlib/memalign.c
--- djgpp.orig/src/libc/compat/stdlib/memalign.c 2013-11-24 22:17:22 +0100
+++ djgpp/src/libc/compat/stdlib/memalign.c 2013-11-24 23:12:22 +0100
@@ -1,7 +1,8 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
-#include <stdlib.h>
+#include <malloc.h>
#include <libc/malloc.h>
/* Make VAL a multiple of ALIGN. */
static inline
size_t
@@ -65,11 +66,11 @@ split_alloc(char *ptr, size_t split_pos)
}
/* Return a block of memory AMT bytes long whose address is a multiple
ALIGN. ALIGN must be a power of 2. */
void *
-memalign(size_t amt, size_t align)
+memalign(size_t align, size_t amt)
{
char *ptr, *aligned_ptr;
size_t alloc_size, before_size, after_size;
if (align != align_val(align, align))
diff -aprNU5 djgpp.orig/src/libc/compat/stdlib/memalign.txh djgpp/src/libc/compat/stdlib/memalign.txh
--- djgpp.orig/src/libc/compat/stdlib/memalign.txh 2003-01-29 12:41:10 +0100
+++ djgpp/src/libc/compat/stdlib/memalign.txh 2013-11-24 23:12:22 +0100
@@ -1,13 +1,13 @@
@node memalign, memory
@findex memalign
@subheading Syntax
@example
-#include <stdlib.h>
+#include <malloc.h>
-void *memalign(size_t size, size_t alignment);
+void *memalign(size_t alignment, size_t size);
@end example
@subheading Description
This function is like @code{malloc} (@pxref{malloc}) except the returned
@@ -23,7 +23,7 @@ A pointer to a newly allocated block of
@portability !ansi, !posix
@subheading Example
@example
-char *page = memalign(1024, 1024 * 4);
+char *page = memalign(1024 * 4, 1024);
@end example
diff -aprNU5 djgpp.orig/src/libc/compat/stdlib/valloc.c djgpp/src/libc/compat/stdlib/valloc.c
--- djgpp.orig/src/libc/compat/stdlib/valloc.c 2013-11-24 22:15:24 +0100
+++ djgpp/src/libc/compat/stdlib/valloc.c 2013-11-24 23:13:50 +0100
@@ -1,15 +1,16 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
-#include <stdlib.h>
+#include <malloc.h>
#include <unistd.h>
void *
valloc(size_t amt)
{
static int page_size = -1;
if (page_size == -1)
page_size = getpagesize();
- return memalign(amt, page_size);
+ return memalign(page_size, amt);
}
diff -aprNU5 djgpp.orig/tests/libc/compat/malloc/makefile djgpp/tests/libc/compat/malloc/makefile
--- djgpp.orig/tests/libc/compat/malloc/makefile 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/compat/malloc/makefile 2013-11-25 20:21:54 +0100
@@ -0,0 +1,5 @@
+TOP=../..
+
+SRC += memalign.c
+
+include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/tests/libc/compat/malloc/memalign.c djgpp/tests/libc/compat/malloc/memalign.c
--- djgpp.orig/tests/libc/compat/malloc/memalign.c 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/compat/malloc/memalign.c 2013-11-25 22:09:20 +0100
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <malloc.h>
+
+int
+main(void)
+{
+ size_t aligment = 0;
+ size_t amount = 1024;
+ char *p;
+ int i, failed = 0;
+
+
+ p = memalign(aligment, amount);
+ if (!p)
+ {
+ printf("memalign failed to align on byte boundary.\n");
+ failed++;
+ }
+
+ p = memalign(++aligment, amount);
+ if ((size_t)p % aligment)
+ {
+ printf("memalign erroneously allowed to aligned on %zd byte boundary.\n", aligment);
+ failed++;
+ }
+
+ for (++aligment, i = 0; i < 10; i++, aligment = 2 << i)
+ {
+ p = memalign(aligment, amount);
+ if (!p || (size_t)p % aligment)
+ {
+ printf("memalign failed to align on %zd byte boundary.\n", aligment);
+ failed++;
+ }
+
+ p = memalign(++aligment, amount);
+ if (p)
+ {
+ printf("memalign erroneously allowed to aligned on %zd byte boundary.\n", aligment);
+ failed++;
+ }
+ }
+
+ if (failed)
+ printf("memalign failed for %d checks.\n", failed);
+ else
+ printf("memalign check passed.\n");
+
+ return 0;
+}
diff -aprNU5 djgpp.orig/tests/libc/compat/stdlib/makefile djgpp/tests/libc/compat/stdlib/makefile
--- djgpp.orig/tests/libc/compat/stdlib/makefile 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/compat/stdlib/makefile 2013-11-25 19:56:00 +0100
@@ -0,0 +1,5 @@
+TOP=../..
+
+SRC += valloc.c
+
+include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/tests/libc/compat/stdlib/valloc.c djgpp/tests/libc/compat/stdlib/valloc.c
--- djgpp.orig/tests/libc/compat/stdlib/valloc.c 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/compat/stdlib/valloc.c 2013-11-25 22:09:18 +0100
@@ -0,0 +1,24 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+ int pagesize = getpagesize();
+ char *p = valloc(pagesize);
+ int i = (long int)p;
+
+
+ if (i & (pagesize - 1))
+ {
+ printf("Alignment problem: valloc returns %p\n", p);
+ return 1;
+ }
+ else
+ printf("valloc check passed\n");
+
+ return 0;
+}
- Raw text -