Index: third_party/yasm/patched-yasm/libyasm/section.c |
=================================================================== |
--- third_party/yasm/patched-yasm/libyasm/section.c (revision 71129) |
+++ third_party/yasm/patched-yasm/libyasm/section.c (working copy) |
@@ -25,7 +25,7 @@ |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "util.h" |
-/*@unused@*/ RCSID("$Id: section.c 2109 2008-06-08 09:06:05Z peter $"); |
+/*@unused@*/ RCSID("$Id: section.c 2310 2010-03-28 19:28:54Z peter $"); |
#include <limits.h> |
@@ -346,6 +346,9 @@ |
s->res_only = res_only; |
s->def = 0; |
+ /* Initialize object format specific data */ |
+ yasm_objfmt_init_new_section(s, line); |
+ |
*isnew = 1; |
return s; |
} |
@@ -864,16 +867,18 @@ |
* checking for circular references (cycles) with id=0 spans. |
*/ |
yasm_span **backtrace; |
+ int backtrace_size; |
/* First offset setter following this span's bytecode */ |
yasm_offset_setter *os; |
}; |
typedef struct optimize_data { |
- /*@reldef@*/ TAILQ_HEAD(, yasm_span) spans; |
- /*@reldef@*/ STAILQ_HEAD(, yasm_span) QA, QB; |
+ /*@reldef@*/ TAILQ_HEAD(yasm_span_head, yasm_span) spans; |
+ /*@reldef@*/ STAILQ_HEAD(yasm_span_shead, yasm_span) QA, QB; |
/*@only@*/ IntervalTree *itree; |
- /*@reldef@*/ STAILQ_HEAD(, yasm_offset_setter) offset_setters; |
+ /*@reldef@*/ STAILQ_HEAD(offset_setters_head, yasm_offset_setter) |
+ offset_setters; |
long len_diff; /* used only for optimize_term_expand */ |
yasm_span *span; /* used only for check_cycle */ |
yasm_offset_setter *os; |
@@ -901,6 +906,7 @@ |
span->id = id; |
span->active = 1; |
span->backtrace = NULL; |
+ span->backtrace_size = 0; |
span->os = os; |
return span; |
@@ -1160,7 +1166,8 @@ |
optimize_data *optd = d; |
yasm_span_term *term = node->data; |
yasm_span *depspan = term->span; |
- int bt_size = 0, dep_bt_size = 0; |
+ int i; |
+ int depspan_bt_alloc; |
/* Only check for cycles in id=0 spans */ |
if (depspan->id > 0) |
@@ -1170,10 +1177,8 @@ |
* span is in our backtrace. |
*/ |
if (optd->span->backtrace) { |
- yasm_span *s; |
- while ((s = optd->span->backtrace[bt_size])) { |
- bt_size++; |
- if (s == depspan) |
+ for (i=0; i<optd->span->backtrace_size; i++) { |
+ if (optd->span->backtrace[i] == depspan) |
yasm_error_set(YASM_ERROR_VALUE, |
N_("circular reference detected")); |
} |
@@ -1183,25 +1188,51 @@ |
* span. |
*/ |
if (!depspan->backtrace) { |
- depspan->backtrace = yasm_xmalloc((bt_size+2)*sizeof(yasm_span *)); |
- if (bt_size > 0) |
+ depspan->backtrace = yasm_xmalloc((optd->span->backtrace_size+1)* |
+ sizeof(yasm_span *)); |
+ if (optd->span->backtrace_size > 0) |
memcpy(depspan->backtrace, optd->span->backtrace, |
- bt_size*sizeof(yasm_span *)); |
- depspan->backtrace[bt_size] = optd->span; |
- depspan->backtrace[bt_size+1] = NULL; |
+ optd->span->backtrace_size*sizeof(yasm_span *)); |
+ depspan->backtrace[optd->span->backtrace_size] = optd->span; |
+ depspan->backtrace_size = optd->span->backtrace_size+1; |
return; |
} |
- while (depspan->backtrace[dep_bt_size]) |
- dep_bt_size++; |
- depspan->backtrace = |
- yasm_xrealloc(depspan->backtrace, |
- (dep_bt_size+bt_size+2)*sizeof(yasm_span *)); |
- if (bt_size > 0) |
- memcpy(&depspan->backtrace[dep_bt_size], optd->span->backtrace, |
- (bt_size-1)*sizeof(yasm_span *)); |
- depspan->backtrace[dep_bt_size+bt_size] = optd->span; |
- depspan->backtrace[dep_bt_size+bt_size+1] = NULL; |
+ /* Add our complete backtrace, checking for duplicates */ |
+ depspan_bt_alloc = depspan->backtrace_size; |
+ for (i=0; i<optd->span->backtrace_size; i++) { |
+ int present = 0; |
+ int j; |
+ for (j=0; j<depspan->backtrace_size; j++) { |
+ if (optd->span->backtrace[i] == optd->span->backtrace[j]) { |
+ present = 1; |
+ break; |
+ } |
+ } |
+ if (present) |
+ continue; |
+ /* Not already in array; add it. */ |
+ if (depspan->backtrace_size >= depspan_bt_alloc) |
+ { |
+ depspan_bt_alloc *= 2; |
+ depspan->backtrace = |
+ yasm_xrealloc(depspan->backtrace, |
+ depspan_bt_alloc*sizeof(yasm_span *)); |
+ } |
+ depspan->backtrace[depspan->backtrace_size] = optd->span->backtrace[i]; |
+ depspan->backtrace_size++; |
+ } |
+ |
+ /* Add ourselves. */ |
+ if (depspan->backtrace_size >= depspan_bt_alloc) |
+ { |
+ depspan_bt_alloc++; |
+ depspan->backtrace = |
+ yasm_xrealloc(depspan->backtrace, |
+ depspan_bt_alloc*sizeof(yasm_span *)); |
+ } |
+ depspan->backtrace[depspan->backtrace_size] = optd->span; |
+ depspan->backtrace_size++; |
} |
static void |