Subject: Re: some code assumes sizeof(char *) == sizeof(int)
To: None <port-sparc64@netbsd.org, tech-pkg@netbsd.org>
From: Shin'ichiro TAYA <taya@sm.sony.co.jp>
List: port-sparc64
Date: 02/23/2001 01:36:38
I made a patch for bash to solve unwind_protect problem on sparc64.
How about this?
I tested on sparc64 & i386.
diff -ru ../../Orig/bash-2.04/lib/malloc/malloc.c ./lib/malloc/malloc.c
--- ../../Orig/bash-2.04/lib/malloc/malloc.c Sat Oct 2 04:39:32 1999
+++ ./lib/malloc/malloc.c Fri Feb 23 00:49:09 2001
@@ -796,10 +796,10 @@
if (ptr == 0)
return 0;
/* If entire block has the desired alignment, just accept it. */
- if (((int) ptr & (alignment - 1)) == 0)
+ if (((size_t) ptr & (alignment - 1)) == 0)
return ptr;
/* Otherwise, get address of byte in the block that has that alignment. */
- aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
+ aligned = (char *) (((size_t) ptr + alignment - 1) & -alignment);
/* Store a suitable indication of how to free the block,
so that free can find the true beginning of it. */
diff -ru ../../Orig/bash-2.04/unwind_prot.c ./unwind_prot.c
--- ../../Orig/bash-2.04/unwind_prot.c Thu Aug 5 20:23:32 1999
+++ ./unwind_prot.c Fri Feb 23 00:50:57 2001
@@ -51,7 +51,7 @@
points to this. */
typedef struct {
int *variable;
- char *desired_setting;
+ UWP desired_setting;
int size;
} SAVED_VAR;
@@ -250,8 +250,9 @@
discard_saved_var (sv)
SAVED_VAR *sv;
{
- if (sv->size != sizeof (int))
- free (sv->desired_setting);
+ if (sv->size != sizeof (int) && sv->size != sizeof (short) &&
+ sv->size != sizeof (char *))
+ free (sv->desired_setting.p);
free (sv);
}
@@ -263,13 +264,16 @@
restore_variable (sv)
SAVED_VAR *sv;
{
- if (sv->size != sizeof (int))
- {
- FASTCOPY ((char *)sv->desired_setting, (char *)sv->variable, sv->size);
- free (sv->desired_setting);
- }
- else
- *(sv->variable) = (int)sv->desired_setting;
+ if (sv->size == sizeof (int))
+ *(int *)(sv->variable) = sv->desired_setting.i;
+ else if (sv->size == sizeof (short))
+ *(short *)(sv->variable) = sv->desired_setting.s;
+ else if (sv->size == sizeof (char *))
+ *(char **)(sv->variable) = sv->desired_setting.p;
+ else {
+ FASTCOPY ((char *)sv->desired_setting.p, (char *)sv->variable, sv->size);
+ free (sv->desired_setting.p);
+ }
free (sv);
}
@@ -282,28 +286,32 @@
void
unwind_protect_var (var, value, size)
int *var;
- char *value;
+ UWP *value;
int size;
{
SAVED_VAR *s = (SAVED_VAR *)xmalloc (sizeof (SAVED_VAR));
s->variable = var;
- if (size != sizeof (int))
- {
+ if (size == sizeof (int)) {
+ s->desired_setting.i = value->i;
+ } else if (size == sizeof (short)) {
+ s->desired_setting.s = value->s;
+ } else if (size == sizeof (char *)) {
+ s->desired_setting.p = value->p;
+ } else {
/* There is a problem here when VALUE is 0. This tries to copy the
first SIZE bytes starting at memory location 0 into
s->desired_setting. There is no guarantee that these bytes are
0, or make a valid null pointer. We can try to bzero the space,
or just save it as 0 (or (void *)0). If we do the latter, make
sure restore_variable is changed to understand it. */
- s->desired_setting = (char *)xmalloc (size);
+ s->desired_setting.p = (char *)xmalloc (size);
if (value == 0)
- bzero ((char *)s->desired_setting, size);
+ bzero ((char *)s->desired_setting.p, size);
else
- FASTCOPY (value, (char *)s->desired_setting, size);
- }
- else
- s->desired_setting = value;
+ FASTCOPY (value, (char *)s->desired_setting.p, size);
+ }
+
s->size = size;
add_unwind_protect ((Function *)restore_variable, (char *)s);
}
diff -ru ../../Orig/bash-2.04/unwind_prot.h ./unwind_prot.h
--- ../../Orig/bash-2.04/unwind_prot.h Thu Aug 5 20:15:52 1999
+++ ./unwind_prot.h Fri Feb 23 00:51:19 2001
@@ -33,8 +33,9 @@
/* Try to force correct alignment on machines where pointers and ints
differ in size. */
typedef union {
- char *s;
+ char *p;
int i;
+ int s;
} UWP;
/* Define for people who like their code to look a certain way. */
@@ -46,16 +47,28 @@
{ \
UWP u; \
u.i = (X); \
- unwind_protect_var (&(X), u.s, sizeof (int)); \
+ unwind_protect_var (&(X), &u, sizeof (int)); \
} \
while (0)
#define unwind_protect_short(X) \
- unwind_protect_var ((int *)&(X), (char *)&(X), sizeof (short))
+ do \
+ { \
+ UWP u; \
+ u.s = (X); \
+ unwind_protect_var (&(X), &u, sizeof (short)); \
+ } \
+ while (0)
/* How to protect a pointer to a string. */
#define unwind_protect_string(X) \
- unwind_protect_var ((int *)&(X), (X), sizeof (char *))
+ do \
+ { \
+ UWP u; \
+ u.p = (X); \
+ unwind_protect_var (&(X), &u, sizeof (char *)); \
+ } \
+ while (0)
/* How to protect any old pointer. */
#define unwind_protect_pointer(X) unwind_protect_string (X)