<div dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 1, 2018 at 5:27 AM, Martin Pelikán <span dir="ltr"><<a href="mailto:mpel@google.com" target="_blank">mpel@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">After bebe3d626e5, b->fail_jump is prepared after vtn_create_builder<br>
which can longjmp(3) to it through its vtx_assert()s. This corrupts<br>
the stack and creates confusing core dumps, so we need to avoid it.<br>
<br>
While there, I decided to print the offending values for debugability.<br>
---<br>
</span> src/compiler/spirv/spirv_to_<wbr>nir.c | 39 +++++++++++++++++++++++++++---<wbr>-<br>
src/compiler/spirv/vtn_<wbr>private.h | 4 ++++<br>
2 files changed, 38 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/src/compiler/spirv/spirv_to_<wbr>nir.c b/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
index 78437428aa..1685ddc34b 100644<br>
--- a/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
+++ b/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
@@ -129,6 +129,18 @@ _vtn_warn(struct vtn_builder *b, const char *file, unsigned line,<br>
va_end(args);<br>
}<br>
<br>
+void<br>
+_vtn_err(struct vtn_builder *b, const char *file, unsigned line,<br>
+ const char *fmt, ...)<br>
+{<br>
+ va_list args;<br>
+<br>
+ va_start(args, fmt);<br>
+ vtn_log_err(b, NIR_SPIRV_DEBUG_LEVEL_ERROR, "SPIR-V ERROR:\n",<br>
+ file, line, fmt, args);<br>
+ va_end(args);<br>
+}<br>
+<br>
void<br>
_vtn_fail(struct vtn_builder *b, const char *file, unsigned line,<br>
const char *fmt, ...)<br>
@@ -4011,19 +4023,36 @@ vtn_create_builder(const uint32_t *words, size_t word_count,<br>
<span class=""> b->entry_point_name = entry_point_name;<br>
b->options = options;<br>
<br>
- /* Handle the SPIR-V header (first 4 dwords) */<br>
- vtn_assert(word_count > 5);<br>
+ /*<br>
+ * Handle the SPIR-V header (first 4 dwords).<br>
+ * Can't use vtx_assert() as the setjmp(3) target isn't initialized yet.<br>
+ */<br>
+ if (word_count <= 5)<br>
+ goto fail;<br>
</span>+<br>
<span class="">+ if (words[0] != SpvMagicNumber) {<br>
</span>+ vtn_err("words[0] was 0x%x, want 0x%x", words[0], SpvMagicNumber);<br>
<span class="">+ goto fail;<br>
+ }<br>
+ if (words[1] < 0x10000) {<br>
</span>+ vtn_err("words[1] was 0x%x, want >= 0x10000", words[1]);<br>
+ goto fail;<br>
+ }<br>
<br>
<span class="">- vtn_assert(words[0] == SpvMagicNumber);<br>
- vtn_assert(words[1] >= 0x10000);<br>
</span><span class=""> /* words[2] == generator magic */<br>
unsigned value_id_bound = words[3];<br>
- vtn_assert(words[4] == 0);<br>
+ if (words[4] != 0) {<br>
</span>+ vtn_err("words[4] was %u, want 0", words[4]);<br>
<span class="">+ goto fail;<br>
+ }<br>
<br>
b->value_id_bound = value_id_bound;<br>
b->values = rzalloc_array(b, struct vtn_value, value_id_bound);<br>
<br>
return b;<br>
+ fail:<br>
+ ralloc_free(b);<br>
+ return NULL;<br>
}<br>
<br>
nir_function *<br>
</span>diff --git a/src/compiler/spirv/vtn_<wbr>private.h b/src/compiler/spirv/vtn_<wbr>private.h<br>
index b501bbf9b4..3146d8eeb5 100644<br>
--- a/src/compiler/spirv/vtn_<wbr>private.h<br>
+++ b/src/compiler/spirv/vtn_<wbr>private.h<br>
@@ -51,6 +51,10 @@ void _vtn_warn(struct vtn_builder *b, const char *file, unsigned line,<br>
const char *fmt, ...) PRINTFLIKE(4, 5);<br>
#define vtn_warn(...) _vtn_warn(b, __FILE__, __LINE__, __VA_ARGS__)<br>
<br>
+void _vtn_err(struct vtn_builder *b, const char *file, unsigned line,<br>
+ const char *fmt, ...) PRINTFLIKE(4, 5);<br>
+#define vtn_err(...) _vtn_err(b, __FILE__, __LINE__, __VA_ARGS__)<br>
+<br>
/** Fail SPIR-V parsing<br>
*<br>
* This function logs an error and then bails out of the shader compile using<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.17.0.921.gf22659ad46-goog<br>
<br>
</font></span></blockquote></div><br></div>