|
|
6bd781 |
diff --git a/src/util.c b/src/util.c
|
|
|
6bd781 |
index 2eebf30..4d1be64 100644
|
|
|
6bd781 |
--- a/src/util.c
|
|
|
6bd781 |
+++ b/src/util.c
|
|
|
6bd781 |
@@ -44,6 +44,7 @@
|
|
|
6bd781 |
#include <string.h>
|
|
|
6bd781 |
#include <fcntl.h>
|
|
|
6bd781 |
#include <errno.h>
|
|
|
6bd781 |
+#include <signal.h>
|
|
|
6bd781 |
|
|
|
6bd781 |
#include "types.h"
|
|
|
6bd781 |
#include "util.h"
|
|
|
6bd781 |
@@ -87,6 +88,23 @@ int checksum(const u8 * buf, size_t len)
|
|
|
6bd781 |
return (sum == 0);
|
|
|
6bd781 |
}
|
|
|
6bd781 |
|
|
|
6bd781 |
+/* Static global variables which should only
|
|
|
6bd781 |
+ * be used by the sigill_handler()
|
|
|
6bd781 |
+ */
|
|
|
6bd781 |
+static int sigill_error = 0;
|
|
|
6bd781 |
+static Log_t *sigill_logobj = NULL;
|
|
|
6bd781 |
+
|
|
|
6bd781 |
+void sigill_handler(int ignore_this) {
|
|
|
6bd781 |
+ sigill_error = 1;
|
|
|
6bd781 |
+ if( sigill_logobj ) {
|
|
|
6bd781 |
+ log_append(sigill_logobj, LOGFL_NODUPS, LOG_WARNING,
|
|
|
6bd781 |
+ "SIGILL signal caught in mem_chunk()");
|
|
|
6bd781 |
+ } else {
|
|
|
6bd781 |
+ fprintf(stderr,
|
|
|
6bd781 |
+ "** WARNING ** SIGILL signal caught in mem_chunk()\n");
|
|
|
6bd781 |
+ }
|
|
|
6bd781 |
+}
|
|
|
6bd781 |
+
|
|
|
6bd781 |
/*
|
|
|
6bd781 |
* Copy a physical memory chunk into a memory buffer.
|
|
|
6bd781 |
* This function allocates memory.
|
|
|
6bd781 |
@@ -100,15 +118,20 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem)
|
|
|
6bd781 |
size_t mmoffset;
|
|
|
6bd781 |
void *mmp;
|
|
|
6bd781 |
#endif
|
|
|
6bd781 |
-
|
|
|
6bd781 |
- if((fd = open(devmem, O_RDONLY)) == -1) {
|
|
|
6bd781 |
- log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: %s", devmem, strerror(errno));
|
|
|
6bd781 |
- return NULL;
|
|
|
6bd781 |
+ sigill_logobj = logp;
|
|
|
6bd781 |
+ signal(SIGILL, sigill_handler);
|
|
|
6bd781 |
+ if(sigill_error || (fd = open(devmem, O_RDONLY)) == -1) {
|
|
|
6bd781 |
+ log_append(logp, LOGFL_NORMAL, LOG_WARNING,
|
|
|
6bd781 |
+ "Failed to open memory buffer (%s): %s",
|
|
|
6bd781 |
+ devmem, strerror(errno));
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
|
|
|
6bd781 |
- if((p = malloc(len)) == NULL) {
|
|
|
6bd781 |
- log_append(logp, LOGFL_NORMAL, LOG_WARNING, "malloc: %s", strerror(errno));
|
|
|
6bd781 |
- return NULL;
|
|
|
6bd781 |
+ if(sigill_error || (p = malloc(len)) == NULL) {
|
|
|
6bd781 |
+ log_append(logp, LOGFL_NORMAL, LOG_WARNING,"malloc: %s", strerror(errno));
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
#ifdef USE_MMAP
|
|
|
6bd781 |
#ifdef _SC_PAGESIZE
|
|
|
6bd781 |
@@ -122,33 +145,49 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem)
|
|
|
6bd781 |
* to read from /dev/mem using regular read() calls.
|
|
|
6bd781 |
*/
|
|
|
6bd781 |
mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
|
|
|
6bd781 |
- if(mmp == MAP_FAILED) {
|
|
|
6bd781 |
+ if(sigill_error || (mmp == MAP_FAILED)) {
|
|
|
6bd781 |
log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno));
|
|
|
6bd781 |
free(p);
|
|
|
6bd781 |
- return NULL;
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
|
|
|
6bd781 |
memcpy(p, (u8 *) mmp + mmoffset, len);
|
|
|
6bd781 |
-
|
|
|
6bd781 |
- if(munmap(mmp, mmoffset + len) == -1) {
|
|
|
6bd781 |
+ if (sigill_error) {
|
|
|
6bd781 |
+ log_append(logp, LOGFL_NODUPS, LOG_WARNING,
|
|
|
6bd781 |
+ "Failed to do memcpy() due to SIGILL signal");
|
|
|
6bd781 |
+ free(p);
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
+ }
|
|
|
6bd781 |
+
|
|
|
6bd781 |
+ if(sigill_error || (munmap(mmp, mmoffset + len) == -1)) {
|
|
|
6bd781 |
log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno));
|
|
|
6bd781 |
+ free(p);
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
#else /* USE_MMAP */
|
|
|
6bd781 |
- if(lseek(fd, base, SEEK_SET) == -1) {
|
|
|
6bd781 |
+ if(sigill_error || (lseek(fd, base, SEEK_SET) == -1)) {
|
|
|
6bd781 |
log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno));
|
|
|
6bd781 |
free(p);
|
|
|
6bd781 |
- return NULL;
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
|
|
|
6bd781 |
- if(myread(logp, fd, p, len, devmem) == -1) {
|
|
|
6bd781 |
+ if(sigill_error || (myread(logp, fd, p, len, devmem) == -1)) {
|
|
|
6bd781 |
free(p);
|
|
|
6bd781 |
- return NULL;
|
|
|
6bd781 |
+ p = NULL;
|
|
|
6bd781 |
+ goto exit;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
#endif /* USE_MMAP */
|
|
|
6bd781 |
|
|
|
6bd781 |
if(close(fd) == -1)
|
|
|
6bd781 |
perror(devmem);
|
|
|
6bd781 |
|
|
|
6bd781 |
+ exit:
|
|
|
6bd781 |
+ signal(SIGILL, SIG_DFL);
|
|
|
6bd781 |
+ sigill_logobj = NULL;
|
|
|
6bd781 |
return p;
|
|
|
6bd781 |
}
|
|
|
6bd781 |
|