Need to use the alignment of the largest possible type that we access, which is
uint64_t in this case.
void* can be 32-bits, and uint64_t still requires 64-bit alignment on Sparc,
when compiling for 32-bits (default).
... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Sun Aug 2 14:46:40 EEST 2009 (edwin) |
|
2 |
+------------------------------------- |
|
3 |
+ * libclamav/bytecode_vm.c: fix SIGBUS on sparc. |
|
4 |
+ |
|
1 | 5 |
Fri Jul 31 21:28:18 CEST 2009 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* libclamav, clamd: handle file exclusion in cli_ftw() (bb#1656) |
... | ... |
@@ -103,6 +103,10 @@ struct stack { |
103 | 103 |
uint16_t last_size; |
104 | 104 |
}; |
105 | 105 |
|
106 |
+/* type with largest alignment that we use (in general it is a long double, but |
|
107 |
+ * thats too big alignment for us) */ |
|
108 |
+typedef uint64_t align_t; |
|
109 |
+ |
|
106 | 110 |
static always_inline void* cli_stack_alloc(struct stack *stack, unsigned bytes) |
107 | 111 |
{ |
108 | 112 |
struct stack_chunk *chunk = stack->chunk; |
... | ... |
@@ -110,7 +114,7 @@ static always_inline void* cli_stack_alloc(struct stack *stack, unsigned bytes) |
110 | 110 |
|
111 | 111 |
/* last_size is stored after data */ |
112 | 112 |
/* align bytes to pointer size */ |
113 |
- bytes = (bytes + sizeof(uint16_t) + sizeof(void*)) & ~(sizeof(void*)-1); |
|
113 |
+ bytes = (bytes + sizeof(uint16_t) + sizeof(align_t)) & ~(sizeof(align_t)-1); |
|
114 | 114 |
last_size_off = bytes - 2; |
115 | 115 |
|
116 | 116 |
if (chunk && (chunk->used + bytes <= STACK_CHUNKSIZE)) { |
... | ... |
@@ -118,7 +122,7 @@ static always_inline void* cli_stack_alloc(struct stack *stack, unsigned bytes) |
118 | 118 |
void *ret; |
119 | 119 |
|
120 | 120 |
*(uint16_t*)&chunk->u.data[chunk->used + last_size_off] = stack->last_size; |
121 |
- stack->last_size = bytes/sizeof(void*); |
|
121 |
+ stack->last_size = bytes/sizeof(align_t); |
|
122 | 122 |
|
123 | 123 |
ret = chunk->u.data + chunk->used; |
124 | 124 |
chunk->used += bytes; |
... | ... |
@@ -135,7 +139,7 @@ static always_inline void* cli_stack_alloc(struct stack *stack, unsigned bytes) |
135 | 135 |
return NULL; |
136 | 136 |
|
137 | 137 |
*(uint16_t*)&chunk->u.data[last_size_off] = stack->last_size; |
138 |
- stack->last_size = bytes/sizeof(void*); |
|
138 |
+ stack->last_size = bytes/sizeof(align_t); |
|
139 | 139 |
|
140 | 140 |
chunk->used = bytes; |
141 | 141 |
chunk->prev = stack->chunk; |
... | ... |
@@ -151,17 +155,17 @@ static always_inline void cli_stack_free(struct stack *stack, void *data) |
151 | 151 |
cli_errmsg("cli_stack_free: stack empty!\n"); |
152 | 152 |
return; |
153 | 153 |
} |
154 |
- if ((chunk->u.data + chunk->used) != ((char*)data + stack->last_size*sizeof(void*))) { |
|
154 |
+ if ((chunk->u.data + chunk->used) != ((char*)data + stack->last_size*sizeof(align_t))) { |
|
155 | 155 |
cli_errmsg("cli_stack_free: wrong free order: %p, expected %p\n", |
156 |
- data, chunk->u.data + chunk->used - stack->last_size*sizeof(void*)); |
|
156 |
+ data, chunk->u.data + chunk->used - stack->last_size*sizeof(align_t)); |
|
157 | 157 |
return; |
158 | 158 |
} |
159 | 159 |
last_size = *(uint16_t*)&chunk->u.data[chunk->used-2]; |
160 |
- if (chunk->used < stack->last_size*sizeof(void*)) { |
|
160 |
+ if (chunk->used < stack->last_size*sizeof(align_t)) { |
|
161 | 161 |
cli_errmsg("cli_stack_free: last_size is corrupt!\n"); |
162 | 162 |
return; |
163 | 163 |
} |
164 |
- chunk->used -= stack->last_size*sizeof(void*); |
|
164 |
+ chunk->used -= stack->last_size*sizeof(align_t); |
|
165 | 165 |
stack->last_size = last_size; |
166 | 166 |
if (!chunk->used) { |
167 | 167 |
stack->chunk = chunk->prev; |