Workaround stack alignment bugs when compiling with clang

This commit is contained in:
Jeremy Lakeman 2016-01-25 14:09:44 +10:30
parent f2e2b4acb5
commit ef208c9932
3 changed files with 21 additions and 11 deletions

View File

@ -175,10 +175,10 @@ JNIEXPORT jint JNICALL Java_org_servalproject_servaldna_ServalDCommand_rawComman
// Construct argv, argc from this method's arguments.
jsize len = (*env)->GetArrayLength(env, args);
const char **argv = alloca(sizeof(char*) * (len + 1));
if (argv == NULL)
return Throw(env, "java/lang/OutOfMemoryError", "alloca() returned NULL");
bzero(argv, sizeof(char*) * (len + 1));
const char *argv[len+1];
bzero(argv, sizeof(argv));
jsize i;
int argc = len;
// From now on, in case of an exception we have to free some resources before

View File

@ -1495,10 +1495,9 @@ int rhizome_list_next(struct rhizome_list_cursor *c)
uint64_t q_version = sqlite3_column_int64(c->_statement, 2);
int64_t q_inserttime = sqlite3_column_int64(c->_statement, 3);
const char *q_author = (const char *) sqlite3_column_text(c->_statement, 4);
sid_t *author = NULL;
sid_t author;
if (q_author) {
author = alloca(sizeof *author);
if (str_to_sid_t(author, q_author) == -1) {
if (str_to_sid_t(&author, q_author) == -1) {
WHYF("MANIFESTS row id=%s has invalid author column %s -- skipped", q_manifestid, alloca_str_toprint(q_author));
continue;
}
@ -1519,8 +1518,8 @@ int rhizome_list_next(struct rhizome_list_cursor *c)
q_manifestid, q_version, m->version);
continue;
}
if (author)
rhizome_manifest_set_author(m, author);
if (q_author)
rhizome_manifest_set_author(m, &author);
rhizome_manifest_set_rowid(m, q_rowid);
rhizome_manifest_set_inserttime(m, q_inserttime);
if (c->service && !(m->service && strcasecmp(c->service, m->service) == 0))

View File

@ -19,7 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __STRBUF_H__
#define __STRBUF_H__
#include <stddef.h>
#include "features.h"
/**
@ -133,6 +133,17 @@ typedef const struct strbuf *const_strbuf;
*/
#define SIZEOF_STRBUF (sizeof(struct strbuf))
// clang doesn't force the allignment of alloca() which can lead to undefined behaviour. eg SIGBUS
// TODO write autoconf test for this
#ifdef __clang__
#define __ALIGNMENT_OF(T) offsetof( struct { char x; T dummy; }, dummy)
#define alloca_aligned(size, T) (void*)((uintptr_t)alloca(size+__ALIGNMENT_OF(T)-1)+__ALIGNMENT_OF(T)-1 & ~(__ALIGNMENT_OF(T)-1) )
#else
#define alloca_aligned(size, T) alloca(size)
#endif
/** Convenience macro for allocating a strbuf and its backing buffer on the
* heap using a single call to malloc(3).
*
@ -166,7 +177,7 @@ typedef const struct strbuf *const_strbuf;
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
#define strbuf_alloca(size) strbuf_make(alloca(SIZEOF_STRBUF + (size)), SIZEOF_STRBUF + (size))
#define strbuf_alloca(size) strbuf_make(alloca_aligned(SIZEOF_STRBUF + (size), strbuf), SIZEOF_STRBUF + (size))
/** Convenience macro that calls strbuf_alloca() to allocate a large enough
* buffer to hold the entire content produced by a given expression that