@@ -332,9 +332,18 @@ def write_vectors_h(path: str, token_count: int, dim: int, incbin_path: str):
332332
333333
334334def write_blob_s (path : str , incbin_path : str ):
335- """Write assembler .incbin directive."""
336- with open (path , "w" ) as f :
337- f .write (f"""/* nomic-embed-code vector blob embedded via assembler. */
335+ """Write the assembler .incbin wrapper for every target object format.
336+
337+ Must stay byte-identical to the tracked vendored/nomic/code_vectors_blob.S:
338+ tests/test_nomic_blob_generator_contract.sh fails if the two drift. The ELF
339+ branch's .note.GNU-stack is load-bearing -- regenerating without it puts an
340+ executable stack back into every Linux release binary.
341+ """
342+ with open (path , "w" , encoding = "utf-8" ) as f :
343+ f .write (f"""/* nomic-embed-code vector blob embedded via assembler.
344+ * Cross-platform: macOS (Mach-O) vs Linux (ELF) vs Windows (COFF). */
345+
346+ #if defined(__APPLE__)
338347 .section __DATA,__const
339348 .globl _PRETRAINED_VECTOR_BLOB
340349 .globl _PRETRAINED_VECTOR_BLOB_LEN
@@ -347,6 +356,46 @@ def write_blob_s(path: str, incbin_path: str):
347356 .p2align 2
348357_PRETRAINED_VECTOR_BLOB_LEN:
349358 .long _PRETRAINED_VECTOR_BLOB_END - _PRETRAINED_VECTOR_BLOB
359+
360+ #elif defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
361+ .section .rdata,"dr"
362+ .globl PRETRAINED_VECTOR_BLOB
363+ .globl PRETRAINED_VECTOR_BLOB_LEN
364+ .p2align 4
365+ PRETRAINED_VECTOR_BLOB:
366+ .incbin "{ incbin_path } "
367+ PRETRAINED_VECTOR_BLOB_END:
368+
369+ .section .rdata,"dr"
370+ .p2align 2
371+ PRETRAINED_VECTOR_BLOB_LEN:
372+ .long PRETRAINED_VECTOR_BLOB_END - PRETRAINED_VECTOR_BLOB
373+
374+ #else
375+ /* WHY: an ELF object that carries no .note.GNU-stack tells the linker
376+ * nothing about its stack requirement, and GNU ld then assumes the WORST
377+ * for the whole link — every Linux release binary shipped GNU_STACK RWE
378+ * because of this one omission. This is the only assembly source in the
379+ * build, so it alone decided that property. The note must stay even though
380+ * a blob of constant data obviously never executes: absence is the signal,
381+ * not the contents. -Wl,-z,noexecstack in the link flags enforces the
382+ * outcome, and scripts/ci/check-binary-composition.sh fails the release if
383+ * an executable stack ever comes back. */
384+ .section .note.GNU-stack,"",@progbits
385+
386+ .section .rodata,"a",@progbits
387+ .globl PRETRAINED_VECTOR_BLOB
388+ .globl PRETRAINED_VECTOR_BLOB_LEN
389+ .p2align 4
390+ PRETRAINED_VECTOR_BLOB:
391+ .incbin "{ incbin_path } "
392+ PRETRAINED_VECTOR_BLOB_END:
393+
394+ .section .rodata,"a",@progbits
395+ .p2align 2
396+ PRETRAINED_VECTOR_BLOB_LEN:
397+ .long PRETRAINED_VECTOR_BLOB_END - PRETRAINED_VECTOR_BLOB
398+ #endif
350399""" )
351400 print (f" { path } : written" )
352401
0 commit comments