Skip to content

Instantly share code, notes, and snippets.

@deltheil
Last active March 24, 2018 07:51
Show Gist options
  • Save deltheil/3858530 to your computer and use it in GitHub Desktop.
Save deltheil/3858530 to your computer and use it in GitHub Desktop.
ARM: unaligned memory access (EXC_ARM_DA_ALIGN)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define DEREFENCE_MODE 1
#define IS_ALIGNED(P_tr) \
(((uintptr_t) (P_tr) & 3) == 0 ? "YES" : "NO")
static struct {
const char *buf;
int len;
double x;
} foo[] = {
{"abcd", 4, 3.14159} /* OK */,
{"abc", 3, 6.28318} /* KO */
};
int main() {
int ntests = (sizeof(foo)/sizeof(foo[0]));
for (int i = 0; i < ntests; i++) {
/* Serialize */
int siz = sizeof(foo[i].len) + foo[i].len + sizeof(foo[i].x);
char *ptr = malloc(siz);
char *wp = ptr;
memcpy(wp, (char *)&foo[i].len, sizeof(int));
wp += sizeof(int);
memcpy(wp, foo[i].buf, foo[i].len);
wp += foo[i].len;
memcpy(wp, (char *)&foo[i].x, sizeof(double));
wp += sizeof(double);
/* Unserialize */
const char *rp = ptr;
printf("(1) %p (4-byte aligned: %s)\n", rp, IS_ALIGNED(rp));
int len = *((int *) rp);
rp += sizeof(int);
printf("(2) %p (4-byte aligned: %s)\n", rp, IS_ALIGNED(rp));
char *buf = malloc(len+1);
memcpy(buf, (const char *) rp, len);
buf[len] = '\0';
rp += len;
/* On ARM-based systems, When `rp' is not aligned on a word boundary
this causes an "unaligned memory accesses" (EXC_ARM_DA_ALIGN). See:
http://www.galloway.me.uk/2010/10/arm-hacking-exc_arm_da_align-exception/
https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html
*/
printf("(3) %p (4-byte aligned: %s)\n", rp, IS_ALIGNED(rp));
#if DEREFENCE_MODE
double x = *((double *) rp);
#else
double x;
memcpy(&x, rp, sizeof(x));
#endif
printf(" -> len = %d\n", len);
printf(" -> buf = %s\n", buf);
printf(" -> x = %f\n", x);
free(buf);
printf(" -- end of test %d\n", i);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment