From 2bf601f355493c5cfde52096cfd8d3732c8d4c34 Mon Sep 17 00:00:00 2001 From: Krishna Soni Date: Thu, 11 Jun 2026 17:54:24 +0530 Subject: [PATCH 1/3] Fix "I/O error: raw read" on Windows - (systemc-components\common\include\loader.h): add O_BINARY flag for Windows to prevent binary file corruption -On Windows (MSYS2/MinGW), open() defaults to text mode which can corrupt binary files such as .so and .skel.so during ELF loading. Adding O_BINARY forces raw binary reads and resolves the raw read errors observed on Windows. - The flag is guarded with #ifdef _WIN32 as it is Windows-specific and not applicable on other platforms. Signed-off-by: Krishna Soni Signed-off-by: krison-qualcomm --- systemc-components/common/include/loader.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/systemc-components/common/include/loader.h b/systemc-components/common/include/loader.h index a16c6b7e..9a11d92f 100644 --- a/systemc-components/common/include/loader.h +++ b/systemc-components/common/include/loader.h @@ -644,8 +644,16 @@ class loader : public sc_core::sc_module : m_send(_send), m_filename(path), m_fd(-1), m_entry(0), m_machine(0), m_endian(ENDIAN_UNKNOWN) { if (elf_version(EV_CURRENT) == EV_NONE) SCP_FATAL("elf_reader") << "failed to read libelf version"; + + + #ifdef _WIN32 + // On Windows, open() defaults to text mode which can corrupt binary files (e.g. .so, .skel.so) during ELF loading. + // O_BINARY forces raw binary reads to prevent this. + m_fd = open(filename(), O_RDONLY | O_BINARY, 0); + #else + m_fd = open(filename(), O_RDONLY, 0); + #endif - m_fd = open(filename(), O_RDONLY, 0); if (m_fd < 0) SCP_FATAL("elf_reader") << "cannot open elf file " << filename(); Elf* elf = elf_begin(m_fd, ELF_C_READ, nullptr); From 2ddd34eae35ae1d6accc3a00fa9077ecceb8cafe Mon Sep 17 00:00:00 2001 From: krison-qualcomm Date: Tue, 23 Jun 2026 13:19:31 +0530 Subject: [PATCH 2/3] Adding test case to reproduce raw read error Signed-off-by: krison-qualcomm --- .github/workflows/windows-builds.yml | 2 +- systemc-components/common/include/loader.h | 8 +------- tests/components/loader/loader-test.cc | 8 ++++++++ tests/components/loader/src/loader-test.asm | 1 + tests/components/loader/src/loader-test.bin | 2 +- tests/components/loader/src/loader-test.elf | Bin 65988 -> 4552 bytes 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/windows-builds.yml b/.github/workflows/windows-builds.yml index 34534ced..1b4b5b0b 100644 --- a/.github/workflows/windows-builds.yml +++ b/.github/workflows/windows-builds.yml @@ -41,4 +41,4 @@ jobs: - name: Test # Disable parallel test runs on GitHub runners due to resource constraints - run: ctest --preset=${{ matrix.preset }} --parallel 1 + run: ctest --preset=${{ matrix.preset }} --parallel 1 \ No newline at end of file diff --git a/systemc-components/common/include/loader.h b/systemc-components/common/include/loader.h index 9a11d92f..53812d92 100644 --- a/systemc-components/common/include/loader.h +++ b/systemc-components/common/include/loader.h @@ -646,13 +646,7 @@ class loader : public sc_core::sc_module if (elf_version(EV_CURRENT) == EV_NONE) SCP_FATAL("elf_reader") << "failed to read libelf version"; - #ifdef _WIN32 - // On Windows, open() defaults to text mode which can corrupt binary files (e.g. .so, .skel.so) during ELF loading. - // O_BINARY forces raw binary reads to prevent this. - m_fd = open(filename(), O_RDONLY | O_BINARY, 0); - #else - m_fd = open(filename(), O_RDONLY, 0); - #endif + m_fd = open(filename(), O_RDONLY, 0); if (m_fd < 0) SCP_FATAL("elf_reader") << "cannot open elf file " << filename(); diff --git a/tests/components/loader/loader-test.cc b/tests/components/loader/loader-test.cc index 36f651c3..d268b0b9 100644 --- a/tests/components/loader/loader-test.cc +++ b/tests/components/loader/loader-test.cc @@ -25,6 +25,14 @@ TEST_BENCH(LoaderTest, SimpleReadELFFile) ASSERT_EQ(m_initiator.do_read(0x0000, data), tlm::TLM_OK_RESPONSE); ASSERT_EQ(data, 0xaf); + + /* CRLF bytes at offset 0x0004-0x0005: without O_BINARY on Windows, 0x0D 0x0A + * is collapsed to 0x0A by the CRT text-mode translation, corrupting the data. */ + ASSERT_EQ(m_initiator.do_read(0x0004, data), tlm::TLM_OK_RESPONSE); + ASSERT_EQ(data, 0x0d); + + ASSERT_EQ(m_initiator.do_read(0x0005, data), tlm::TLM_OK_RESPONSE); + ASSERT_EQ(data, 0x0a); } TEST_BENCH(LoaderTest, SimpleReadData) diff --git a/tests/components/loader/src/loader-test.asm b/tests/components/loader/src/loader-test.asm index 690834fa..563a64fb 100644 --- a/tests/components/loader/src/loader-test.asm +++ b/tests/components/loader/src/loader-test.asm @@ -1,2 +1,3 @@ .section .data .word 0xdeadbeaf +.byte 0x0D, 0x0A /* CRLF: collapsed to 0x0A in Windows text mode without O_BINARY */ diff --git a/tests/components/loader/src/loader-test.bin b/tests/components/loader/src/loader-test.bin index b296cb08..47ebc34e 100755 --- a/tests/components/loader/src/loader-test.bin +++ b/tests/components/loader/src/loader-test.bin @@ -1 +1 @@ -¯¾­Þ \ No newline at end of file +¯¾­Þ diff --git a/tests/components/loader/src/loader-test.elf b/tests/components/loader/src/loader-test.elf index 60b5298ff9dff8406138120a739404af4d49af0a..daaba7aa907c2b8944566b61c77984f8e89c43b5 100755 GIT binary patch delta 149 zcmX@o%yL3`f`ZWo0R{#JCI(g$1_cI21`P&w1~woK1R!xJU<1-H%pkBaaUK5@MiwSs zuBj}HCR5EA*RufCvP~CcWE7tIhf#o;O@LuKKO>_mD;H2)1S~$?hY={D0F;OaN-!5d SRESQW0~BU00V=ZuD+2(UBNP7s delta 204 zcmX@1e59FWf`aiH21W)3CI(g$1_dBXgMpoa4I}~t5E8^Whf~pb)K$VtY JH$VuO3ju^&EWiK& From e5942ff4c0c2b1b9987091c6bf8a148570a6e8c2 Mon Sep 17 00:00:00 2001 From: krison-qualcomm Date: Tue, 23 Jun 2026 14:39:50 +0530 Subject: [PATCH 3/3] Fix the raw read error for the failing test cases now Signed-off-by: Krishna Soni Signed-off-by: krison-qualcomm --- systemc-components/common/include/loader.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/systemc-components/common/include/loader.h b/systemc-components/common/include/loader.h index 53812d92..e3adc5e1 100644 --- a/systemc-components/common/include/loader.h +++ b/systemc-components/common/include/loader.h @@ -644,9 +644,14 @@ class loader : public sc_core::sc_module : m_send(_send), m_filename(path), m_fd(-1), m_entry(0), m_machine(0), m_endian(ENDIAN_UNKNOWN) { if (elf_version(EV_CURRENT) == EV_NONE) SCP_FATAL("elf_reader") << "failed to read libelf version"; - - + +#ifdef _WIN32 + // On Windows, open() defaults to text mode which can corrupt binary files (e.g. .so, .skel.so) during ELF loading. + // O_BINARY forces raw binary reads to prevent this. + m_fd = open(filename(), O_RDONLY | O_BINARY, 0); +#else m_fd = open(filename(), O_RDONLY, 0); +#endif if (m_fd < 0) SCP_FATAL("elf_reader") << "cannot open elf file " << filename();