Compare commits

...

5 Commits

Author SHA1 Message Date
Hans Baier 8294aeb68d
Merge pull request #6 from cavearr/fix/bitread-dangling-span
bitread: keep the bitstream bytes alive until they are parsed
2026-08-17 11:32:07 +07:00
Carlos Venegas Arrabé 89cad4ca98
bitread: keep the bitstream bytes alive until they are parsed
fcd561fb ('fix build with recent gcc') turned in_bytes from a copying
std::vector into an absl::Span, but left both byte owners scoped to
their if/else blocks: the MemoryMappedFile was destroyed (munmap) and
the stdin vector freed before absl::visit parsed the bitstream.  Every
bitread invocation since then crashes with SIGSEGV in the sync-word
search over unmapped memory -- which also takes bit2fasm down with it.

Hoist the owners to function scope so they outlive the parse.
2026-08-11 21:33:10 +02:00
Hans Baier 15fa018ea0 Merge remote-tracking branch 'upstream/master' 2026-08-08 15:16:22 +07:00
Karol Gugala c9f02d8576
Merge pull request #2550 from openXC7/oserdes-datawidths
036-iob-ologic: Also fuzz DATA_WIDTH 10 and 14
2025-06-05 17:15:54 +02:00
Hans Baier 2f08afa6ef 036-iob-ologic: Also fuzz DATA_WIDTH 10 and 14
Signed-off-by: Hans Baier <foss@hans-baier.de>
2025-06-05 05:46:36 +07:00
4 changed files with 16 additions and 7 deletions

View File

@ -42,7 +42,7 @@ def no_oserdes(segmk, site):
widths = [2, 3, 4, 5, 6, 7, 8] widths = [2, 3, 4, 5, 6, 7, 8]
else: else:
assert mode == 'DDR' assert mode == 'DDR'
widths = [4, 6, 8] widths = [4, 6, 8, 10, 14]
for opt in widths: for opt in widths:
segmk.add_site_tag( segmk.add_site_tag(

View File

@ -94,6 +94,8 @@ proc run {} {
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_property IS_ENABLED 0 [get_drc_checks {REQP-79}] set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-144}] set_property IS_ENABLED 0 [get_drc_checks {REQP-144}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-150}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-152}]
write_checkpoint -force design_pre_place.dcp write_checkpoint -force design_pre_place.dcp

View File

@ -64,7 +64,7 @@ def use_oserdese2(p, luts, connects):
if verilog.unquote(p['DATA_RATE_OQ']) == 'SDR': if verilog.unquote(p['DATA_RATE_OQ']) == 'SDR':
data_widths = [2, 3, 4, 5, 6, 7, 8] data_widths = [2, 3, 4, 5, 6, 7, 8]
else: else:
data_widths = [4, 6, 8] data_widths = [4, 6, 8, 10, 14]
p['DATA_WIDTH'] = random.choice(data_widths) p['DATA_WIDTH'] = random.choice(data_widths)

View File

@ -319,11 +319,18 @@ int main(int argc, char** argv) {
frame_range_end = strtol(p.second.c_str(), nullptr, 0) + 1; frame_range_end = strtol(p.second.c_str(), nullptr, 0) + 1;
} }
// The owners of the bytes the span views: they must outlive the
// absl::visit below. fcd561fb turned in_bytes from a copying
// std::vector into a Span but left both owners scoped to their
// if/else blocks -- the mapping was unmapped (and the stdin vector
// freed) before the bitstream was parsed, and every invocation
// crashed in the sync-word search (use-after-free).
std::unique_ptr<prjxray::MemoryMappedFile> in_file;
std::vector<uint8_t> stdin_bytes;
absl::Span<uint8_t> in_bytes; absl::Span<uint8_t> in_bytes;
if (argc == 2) { if (argc == 2) {
auto in_file_name = argv[1]; auto in_file_name = argv[1];
auto in_file = in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
prjxray::MemoryMappedFile::InitWithFile(in_file_name);
if (!in_file) { if (!in_file) {
std::cerr << "Can't open input file '" << in_file_name std::cerr << "Can't open input file '" << in_file_name
<< "' for reading!" << std::endl; << "' for reading!" << std::endl;
@ -336,15 +343,15 @@ int main(int argc, char** argv) {
in_bytes = absl::Span<uint8_t>( in_bytes = absl::Span<uint8_t>(
static_cast<uint8_t*>(in_file->data()), in_file->size()); static_cast<uint8_t*>(in_file->data()), in_file->size());
} else { } else {
std::vector<uint8_t> t;
while (1) { while (1) {
int c = getchar(); int c = getchar();
if (c == EOF) if (c == EOF)
break; break;
t.push_back(c); stdin_bytes.push_back(c);
} }
in_bytes = absl::Span<uint8_t>( in_bytes = absl::Span<uint8_t>(
static_cast<uint8_t*>(t.data()), t.size()); static_cast<uint8_t*>(stdin_bytes.data()),
stdin_bytes.size());
std::cout << "Bitstream size: " << in_bytes.size() << " bytes" std::cout << "Bitstream size: " << in_bytes.size() << " bytes"
<< std::endl; << std::endl;