Remove use of setjmp/longjmp from libacc compiler.
It makes it harder to deal with memory allocation.
Also fix bug in the otcc-ansi.c test, where the wrong part of the
code buffer was being mprotected, so that if the code buffer happened
to be allocated across a page boundary, some code would no receive
execute permission.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index e0043ef..e7f95b0 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -11,7 +11,6 @@
#include <ctype.h>
#include <dlfcn.h>
#include <errno.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -69,6 +68,7 @@
char* pProgramBase;
ErrorSink* mErrorSink;
int mSize;
+ bool mOverflowed;
void release() {
if (pProgramBase != 0) {
@@ -77,13 +77,16 @@
}
}
- void check(int n) {
+ bool check(int n) {
int newSize = ind - pProgramBase + n;
- if (newSize > mSize) {
+ bool overflow = newSize > mSize;
+ if (overflow && !mOverflowed) {
+ mOverflowed = true;
if (mErrorSink) {
mErrorSink->error("Code too large: %d bytes", newSize);
}
}
+ return overflow;
}
public:
@@ -92,6 +95,7 @@
ind = 0;
mErrorSink = 0;
mSize = 0;
+ mOverflowed = false;
}
~CodeBuf() {
@@ -110,7 +114,9 @@
}
int o4(int n) {
- check(4);
+ if(check(4)) {
+ return 0;
+ }
intptr_t result = (intptr_t) ind;
* (int*) ind = n;
ind += 4;
@@ -121,7 +127,9 @@
* Output a byte. Handles all values, 0..ff.
*/
void ob(int n) {
- check(1);
+ if(check(1)) {
+ return;
+ }
*ind++ = n;
}
@@ -1037,6 +1045,7 @@
int decodeOp(int op) {
if (op < 0 || op > OP_COUNT) {
error("Out-of-range operator: %d\n", op);
+ op = 0;
}
return operatorHelper[op];
}
@@ -1363,8 +1372,6 @@
String mErrorBuf;
- jmp_buf mErrorRecoveryJumpBuf;
-
String mPragmas;
int mPragmaStringCount;
@@ -1430,6 +1437,7 @@
void pdef(int t) {
if (dstk - sym_stk >= ALLOC_SIZE) {
error("Symbol table exhausted");
+ return;
}
*dstk++ = t;
}
@@ -1475,7 +1483,6 @@
} else {
error("Unsupported preprocessor directive \"%s\"", last_id);
}
-
}
inp();
}
@@ -1609,6 +1616,7 @@
if (ch == '(') {
delete pName;
error("Defines with arguments not supported");
+ return;
}
while (isspace(ch)) {
inp();
@@ -1669,7 +1677,6 @@
mErrorBuf.printf("%ld: ", file->getLine());
mErrorBuf.vprintf(fmt, ap);
mErrorBuf.printf("\n");
- longjmp(mErrorRecoveryJumpBuf, 1);
}
void skip(intptr_t c) {
@@ -2053,6 +2060,7 @@
char* allocGlobalSpace(int bytes) {
if (glo - pGlobalBase + bytes > ALLOC_SIZE) {
error("Global space exhausted");
+ return NULL;
}
char* result = glo;
glo += bytes;
@@ -2132,8 +2140,9 @@
}
if (pGen == NULL) {
error("No code generator defined.");
+ } else {
+ pGen->setErrorSink(this);
}
- pGen->setErrorSink(this);
}
public:
@@ -2154,30 +2163,34 @@
int compile(const char* text, size_t textLength) {
int result;
- if (! (result = setjmp(mErrorRecoveryJumpBuf))) {
- cleanup();
- clear();
- codeBuf.init(ALLOC_SIZE);
- setArchitecture(NULL);
- if (!pGen) {
- return -1;
+
+ cleanup();
+ clear();
+ codeBuf.init(ALLOC_SIZE);
+ setArchitecture(NULL);
+ if (!pGen) {
+ return -1;
+ }
+ pGen->init(&codeBuf);
+ file = new TextInputStream(text, textLength);
+ sym_stk = (char*) calloc(1, ALLOC_SIZE);
+ static const char* predefinedSymbols =
+ " int char void"
+ " if else while break return for"
+ " pragma define main ";
+ dstk = strcpy(sym_stk, predefinedSymbols)
+ + strlen(predefinedSymbols);
+ pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
+ glo = pGlobalBase;
+ pVarsBase = (char*) calloc(1, ALLOC_SIZE);
+ inp();
+ next();
+ globalDeclarations();
+ result = pGen->finishCompile();
+ if (result == 0) {
+ if (mErrorBuf.len()) {
+ result = -2;
}
- pGen->init(&codeBuf);
- file = new TextInputStream(text, textLength);
- sym_stk = (char*) calloc(1, ALLOC_SIZE);
- static const char* predefinedSymbols =
- " int char void"
- " if else while break return for"
- " pragma define main ";
- dstk = strcpy(sym_stk, predefinedSymbols)
- + strlen(predefinedSymbols);
- pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
- glo = pGlobalBase;
- pVarsBase = (char*) calloc(1, ALLOC_SIZE);
- inp();
- next();
- globalDeclarations();
- result = pGen->finishCompile();
}
return result;
}
diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c
index 5b75879..3ffad36 100644
--- a/libacc/tests/data/otcc-ansi.c
+++ b/libacc/tests/data/otcc-ansi.c
@@ -450,7 +450,7 @@
o();
ad();
ab(0);
- if (mprotect((ac + 592) & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
+ if (mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
printf("Mprotect failed. %d\n", errno);
return -1;
}