Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page fault in Rust Eapp #462

Open
mdrssv opened this issue Aug 22, 2024 · 4 comments
Open

Page fault in Rust Eapp #462

mdrssv opened this issue Aug 22, 2024 · 4 comments

Comments

@mdrssv
Copy link

mdrssv commented Aug 22, 2024

Describe the bug
Page fault when using certain Rust libraries in an eapp

Build Failure
If you ran into build problems, please add these information
(1) Results of git submodule status
(2) Your Linux distribution (e.g., Ubuntu 14.04)
(3) The branch you're working on (e.g., master or dev)

Screenshots or Error Log
If applicable, add screenshots/error logs to help explain your problem.

[debug] Creating new elf file struct
 (elf.c:16)
[debug] Check elf file
 (elf.c:26)
[debug] Check elf file 32
 (elf.c:75)
[debug] Check program header
 (elf.c:32)
[debug] Check section table
 (elf.c:40)
[debug] Finished validating elf
 (elf.c:48)
[debug] ROOT PAGE TABLE: 0xffffffff00007000 (boot.c:98)
[debug] UTM : 0x82c6c000-0x82c6e000 (8 KB) (boot.c:99)
[debug] DRAM: 0xf0000000-0xf2653000 (39244 KB) (boot.c:100)
[debug] USER: 0xf002d000-0xf0655000 (6304 KB) (boot.c:101)
[debug] FREE: 0xf0655000-0xf2653000 (32760 KB), va 0xffffffff00655000 (boot.c:108)
[debug] Creating new elf file struct
 (elf.c:16)
[debug] Check elf file
 (elf.c:26)
[debug] Check elf file 32
 (elf.c:75)
[debug] Check program header
 (elf.c:32)
[debug] Check section table
 (elf.c:40)
[debug] Finished validating elf
 (elf.c:48)
[debug] eyrie boot finished. drop to the user land ... (boot.c:140)
[runtime] page fault at 0x12dcc on 0x3feffff0 (scause: 0xf)

0x12d90 is memset, 0x3feffff0 is at the end of my 1M stack

GDB stepthrough
377             let pk = PrivateKeyInfo::from_der(key);
(gdb) s
der::decode::Decode::from_der<pkcs8::private_key_info::PrivateKeyInfo> (bytes=...) at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/decode.rs:25
25              let mut reader = SliceReader::new(bytes)?;
(gdb)
der::reader::slice::SliceReader::new (bytes=...) at src/reader/slice.rs:22
22                  bytes: BytesRef::new(bytes)?,
(gdb)
21              Ok(Self {
(gdb)
26          }
(gdb)
der::decode::Decode::from_der<pkcs8::private_key_info::PrivateKeyInfo> (bytes=...) at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/decode.rs:25
25              let mut reader = SliceReader::new(bytes)?;
(gdb)
core::result::{impl#26}::branch<der::reader::slice::SliceReader, der::error::Error> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1976
1976            match self {
(gdb)
1977                Ok(v) => ControlFlow::Continue(v),
(gdb)
memcpy (dest=0x3ffffa24, src=<optimized out>, len=<optimized out>) at string.c:10
10        if ((((uintptr_t)dest | (uintptr_t)src) & (sizeof(uintptr_t) - 1)) == 0) {
(gdb)
18        while (d < (char*)(dest + len)) *d++ = *s++;
(gdb)
20        return dest;
(gdb)
der::decode::Decode::from_der<pkcs8::private_key_info::PrivateKeyInfo> (bytes=...) at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/decode.rs:25
25              let mut reader = SliceReader::new(bytes)?;
(gdb)
26              let result = Self::decode(&mut reader)?;
(gdb)
der::decode::{impl#0}::decode<pkcs8::private_key_info::PrivateKeyInfo, der::reader::slice::SliceReader> (reader=0x3ffffa00) at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/decode.rs:36
36              let header = Header::decode(reader)?;
(gdb)
der::header::{impl#1}::decode<der::reader::slice::SliceReader> (reader=0x3ffffa00) at src/header.rs:28
28              let tag = Tag::decode(reader)?;
(gdb)
der::tag::{impl#5}::decode<der::reader::slice::SliceReader> (reader=0x3ffffa00) at src/tag.rs:319
319             reader.read_byte().and_then(Self::try_from)
(gdb)
der::reader::Reader::read_byte<der::reader::slice::SliceReader> (self=0x3ffffa00) at src/reader.rs:109
109             let mut buf = [0];
(gdb)
110             self.read_into(&mut buf)?;
(gdb)
der::reader::Reader::read_into<der::reader::slice::SliceReader> (self=0x3ffffa00, buf=...) at src/reader.rs:121
121             let input = self.read_slice(buf.len().try_into()?)?;
(gdb)
core::convert::{impl#6}::try_into<usize, der::length::Length> (self=<optimized out>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:798
798             U::try_from(self)
(gdb)
der::length::{impl#13}::try_from (len=<optimized out>) at src/length.rs:195
195             u32::try_from(len)
(gdb)
core::result::Result<u32, core::num::error::TryFromIntError>::map_err<u32, core::num::error::TryFromIntError, der::error::ErrorKind, der::length::{impl#13}::try_from::{closure_env#0}> (self=..., op=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:852
852             match self {
(gdb)
der::reader::Reader::read_into<der::reader::slice::SliceReader> (self=0x3ffffa00, buf=...) at src/reader.rs:121
121             let input = self.read_slice(buf.len().try_into()?)?;
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:79
79              if self.is_failed() {
(gdb)
der::reader::slice::SliceReader::is_failed (self=<optimized out>) at src/reader/slice.rs:42
42              self.failed
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:79
79              if self.is_failed() {
(gdb)
83              match self.remaining()?.get(..len.try_into()?) {
(gdb)
der::reader::slice::SliceReader::remaining (self=0x3ffffa00) at src/reader/slice.rs:48
48              if self.is_failed() {
(gdb)
51                  self.bytes
(gdb)
der::bytes_ref::BytesRef::as_slice (self=0x3ffffa00) at src/bytes_ref.rs:40
40              self.inner
(gdb)
der::reader::slice::SliceReader::remaining (self=0x3ffffa00) at src/reader/slice.rs:53
53                      .get(self.position.try_into()?..)
(gdb)
51                  self.bytes
(gdb)
core::option::Option<&[u8]>::ok_or_else<&[u8], der::error::Error, der::reader::slice::{impl#0}::remaining::{closure_env#0}> (err=..., self=<error reading variable: Cannot access memory at address 0x0>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1265
1265            match self {
(gdb)
51                  self.bytes
(gdb)
core::slice::{impl#0}::get<u8, core::ops::range::RangeFrom<usize>> (self=..., index=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/mod.rs:616
616             index.get(self)
(gdb)
core::slice::index::{impl#6}::get<u8> (self=..., slice=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:523
523             (self.start..slice.len()).get(slice)
(gdb)
core::slice::index::{impl#4}::get<u8> (self=..., slice=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:386
386             if let Some(new_len) = usize::checked_sub(self.end, self.start)
(gdb)
core::num::{impl#11}::checked_sub (self=48, rhs=0)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:621
621                 if self < rhs {
(gdb)
der::reader::slice::SliceReader::remaining (self=<optimized out>) at src/reader/slice.rs:51
51                  self.bytes
(gdb)
core::option::Option<&[u8]>::ok_or_else<&[u8], der::error::Error, der::reader::slice::{impl#0}::remaining::{closure_env#0}> (err=..., self=<error reading variable: Cannot access memory at address 0x0>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1266
1266                Some(v) => Ok(v),
(gdb)
der::reader::slice::SliceReader::remaining (self=<optimized out>) at src/reader/slice.rs:56
56          }
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:83
83              match self.remaining()?.get(..len.try_into()?) {
(gdb)
core::result::{impl#26}::branch<&[u8], der::error::Error> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1976
1976            match self {
(gdb)
0x000000000001d0d4 in der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...)
(gdb)
der::length::{impl#1}::add (self=..., other=...) at src/length.rs:95
95              self.0
(gdb)
core::num::{impl#8}::checked_add (self=<optimized out>, rhs=<optimized out>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:458
458                 let (a, b) = self.overflowing_add(rhs);
(gdb)
core::num::{impl#8}::overflowing_add (self=<optimized out>, rhs=<optimized out>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:2089
2089                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:83
83              match self.remaining()?.get(..len.try_into()?) {
(gdb)
core::result::{impl#26}::branch<&[u8], der::error::Error> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1977
1977                Ok(v) => ControlFlow::Continue(v),
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:83
83              match self.remaining()?.get(..len.try_into()?) {
(gdb)
core::convert::{impl#6}::try_into<der::length::Length, usize> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:798
798             U::try_from(self)
(gdb)
der::length::{impl#14}::try_from (len=...) at src/length.rs:205
205             len.0.try_into().map_err(|_| ErrorKind::Overflow.into())
(gdb)
core::convert::{impl#6}::try_into<u32, usize> (self=1)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:798
798             U::try_from(self)
(gdb)
core::convert::num::ptr_try_from_impls::{impl#20}::try_from (value=1)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/num.rs:216
216                     Ok(value as Self)
(gdb)
0x000000000001d0de in der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...)
(gdb)
der::length::{impl#1}::add (self=..., other=...) at src/length.rs:95
95              self.0
(gdb)
core::num::{impl#8}::checked_add (self=<optimized out>, rhs=<optimized out>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:458
458                 let (a, b) = self.overflowing_add(rhs);
(gdb)
core::num::{impl#8}::overflowing_add (self=<optimized out>, rhs=<optimized out>)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:2089
2089                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
(gdb)
der::length::{impl#1}::add (self=..., other=...) at src/length.rs:95
95              self.0
(gdb)
core::option::Option<u32>::ok_or_else<u32, der::error::Error, der::length::{impl#1}::add::{closure_env#0}> (
    self=<error reading variable: Cannot access memory at address 0x0>, err=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1265
1265            match self {
(gdb)
der::reader::slice::{impl#1}::read_slice (self=0x3ffffa00, len=...) at src/reader/slice.rs:83
83              match self.remaining()?.get(..len.try_into()?) {
(gdb)
85                      self.position = (self.position + len)?;
(gdb)
der::length::{impl#1}::add (self=..., other=...) at src/length.rs:95
95              self.0
(gdb)
core::option::Option<u32>::ok_or_else<u32, der::error::Error, der::length::{impl#1}::add::{closure_env#0}> (
    self=..., err=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1265
1265            match self {
(gdb)
85                      self.position = (self.position + len)?;
(gdb)
86                      Ok(result)
(gdb)
93          }
(gdb)
der::reader::Reader::read_into<der::reader::slice::SliceReader> (self=<optimized out>, buf=...) at src/reader.rs:121
121             let input = self.read_slice(buf.len().try_into()?)?;
(gdb)
core::result::{impl#26}::branch<&[u8], der::error::Error> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1976
1976            match self {
(gdb)
1977                Ok(v) => ControlFlow::Continue(v),
(gdb)
der::reader::Reader::read_into<der::reader::slice::SliceReader> (self=<optimized out>, buf=...) at src/reader.rs:122
122             buf.copy_from_slice(input);
(gdb)
core::slice::{impl#0}::copy_from_slice<u8> (self=..., src=...) at src/slice/mod.rs:3670
3670            if self.len() != src.len() {
(gdb)
3678                ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
(gdb)
core::intrinsics::copy_nonoverlapping<u8> (src=0x243a8, dst=0x3ffff807, count=1) at src/ub_checks.rs:75
75                      precondition_check($($arg,)*);
(gdb)
core::intrinsics::copy_nonoverlapping::precondition_check (src=0x243a8, dst=0x3ffff807, size=1, align=1, count=1) at src/intrinsics.rs:2951
2951            ub_checks::is_aligned_and_not_null(src, align)
(gdb)
core::ub_checks::is_aligned_and_not_null (ptr=0x243a8, align=1) at src/ub_checks.rs:119
119         !ptr.is_null() && ptr.is_aligned_to(align)
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to<()> (self=0x243a8, align=1) at src/ptr/const_ptr.rs:1675
1675            if !align.is_power_of_two() {
(gdb)
core::num::{impl#11}::is_power_of_two (self=1) at src/num/uint_macros.rs:2803
2803                self.count_ones() == 1
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to<()> (self=0x243a8, align=<optimized out>) at src/ptr/const_ptr.rs:1675
1675            if !align.is_power_of_two() {
(gdb)
1693            const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl)
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to::runtime_impl (ptr=0x243a8, align=<optimized out>)
    at src/ptr/const_ptr.rs:1681
1681                ptr.addr() & (align - 1) == 0
(gdb)
core::ub_checks::is_aligned_and_not_null (ptr=<optimized out>, align=<optimized out>) at src/ub_checks.rs:120
120     }
(gdb)
core::intrinsics::copy_nonoverlapping::precondition_check (src=0x243a8, dst=0x3ffff807, size=1, align=1, count=1) at src/intrinsics.rs:2952
2952                && ub_checks::is_aligned_and_not_null(dst, align)
(gdb)
core::ub_checks::is_aligned_and_not_null (ptr=0x3ffff807, align=1) at src/ub_checks.rs:119
119         !ptr.is_null() && ptr.is_aligned_to(align)
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to<()> (self=0x3ffff807, align=1) at src/ptr/const_ptr.rs:1675
1675            if !align.is_power_of_two() {
(gdb)
core::num::{impl#11}::is_power_of_two (self=1) at src/num/uint_macros.rs:2803
2803                self.count_ones() == 1
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to<()> (self=0x3ffff807, align=<optimized out>) at src/ptr/const_ptr.rs:1675
1675            if !align.is_power_of_two() {
(gdb)
1693            const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl)
(gdb)
core::ptr::const_ptr::{impl#0}::is_aligned_to::runtime_impl (ptr=0x3ffff807, align=<optimized out>)
    at src/ptr/const_ptr.rs:1681
1681                ptr.addr() & (align - 1) == 0
(gdb)
core::ub_checks::is_aligned_and_not_null (ptr=<optimized out>, align=<optimized out>) at src/ub_checks.rs:120
120     }
(gdb)
core::intrinsics::copy_nonoverlapping::precondition_check (src=0x243a8, dst=0x3ffff807, size=1, align=1, count=1) at src/intrinsics.rs:2953
2953                && ub_checks::is_nonoverlapping(src, dst, size, count)
(gdb)
core::ub_checks::is_nonoverlapping (src=0x243a8, dst=0x3ffff807, size=1, count=1) at src/ub_checks.rs:161
161         const_eval_select((src, dst, size, count), comptime, runtime)
(gdb)
core::ub_checks::is_nonoverlapping::runtime (src=0x243a8, dst=0x3ffff807, size=1, count=1)
    at src/ub_checks.rs:144
144             let Some(size) = size.checked_mul(count) else {
(gdb)
core::num::{impl#11}::checked_mul (self=1, rhs=1) at src/num/uint_macros.rs:746
746                 let (a, b) = self.overflowing_mul(rhs);
(gdb)
core::num::{impl#11}::overflowing_mul (self=1, rhs=1) at src/num/uint_macros.rs:2287
2287                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
(gdb)
core::ub_checks::is_nonoverlapping::runtime (src=0x243a8, dst=0x3ffff807, size=1, count=1) at src/ub_checks.rs:144
144             let Some(size) = size.checked_mul(count) else {
(gdb)
149             let diff = src_usize.abs_diff(dst_usize);
(gdb)
core::num::{impl#11}::abs_diff (self=148392, other=1073739783) at src/num/uint_macros.rs:2256
2256                    if self < other {
(gdb)
core::intrinsics::copy_nonoverlapping::precondition_check (src=0x243a8, dst=<optimized out>, size=1, align=1, count=1) at src/intrinsics.rs:2953
2953                && ub_checks::is_nonoverlapping(src, dst, size, count)
(gdb)
72                  }
(gdb)
core::intrinsics::copy_nonoverlapping<u8> (src=0x243a8, dst=0x3ffff807, count=1) at src/intrinsics.rs:2958
2958        unsafe { copy_nonoverlapping(src, dst, count) }
(gdb)
memcpy (dest=0x3ffff807, src=<optimized out>, len=<optimized out>) at string.c:10
10        if ((((uintptr_t)dest | (uintptr_t)src) & (sizeof(uintptr_t) - 1)) == 0) {
(gdb)
18        while (d < (char*)(dest + len)) *d++ = *s++;
(gdb)
20        return dest;
(gdb)
der::reader::Reader::read_into<der::reader::slice::SliceReader> (self=<optimized out>, buf=...) at src/reader.rs:123
123             Ok(buf)
(gdb)
124         }
(gdb)
der::reader::Reader::read_byte<der::reader::slice::SliceReader> (self=<optimized out>) at src/reader.rs:110
110             self.read_into(&mut buf)?;
(gdb)
core::result::{impl#26}::branch<&[u8], der::error::Error> (self=...)
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1976
1976            match self {
(gdb)
der::reader::Reader::read_byte<der::reader::slice::SliceReader> (self=<optimized out>) at src/reader.rs:111
111             Ok(buf[0])
(gdb)
112         }
(gdb)
core::result::Result<u8, der::error::Error>::and_then<u8, der::error::Error, der::tag::Tag, fn(u8) -> core::result::Result<der::tag::Tag, der::error::Error>> (self=..., op=<optimized out>) at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1345
1345            match self {
(gdb)
1346                Ok(t) => op(t),
(gdb)
core::ops::function::FnOnce::call_once<fn(u8) -> core::result::Result<der::tag::Tag, der::error::Error>, (u8)> ()
    at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250
250         extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
(gdb)
der::tag::{impl#2}::try_from (byte=48) at src/tag.rs:265
265             let number = TagNumber::try_from(byte & TagNumber::MASK)?;
(gdb)
267             match byte {
(gdb)
302         }
(gdb)
core::result::Result<u8, der::error::Error>::and_then<u8, der::error::Error, der::tag::Tag, fn(u8) -> core::result::Result<der::tag::Tag, der::error::Error>> (self=..., op=<optimized out>) at /home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1349
1349        }
(gdb)
der::tag::{impl#5}::decode<der::reader::slice::SliceReader> (reader=<optimized out>) at src/tag.rs:320
320         }
(gdb)

I've tested all functions which page fault in keystone in the RISCV Qemu VM as well as on my Machine where they executae as expected. Therefor I believe there must be something special about keystone which breaks these particular functions.

The function in particular should be fairly harmless, since it is just loading an DER encoded ed25519 private key which shoudln't use much stack and no heap.

Are there any special compiler flags I should be aware of which might help?

@shimunn
Copy link

shimunn commented Aug 30, 2024

This might actually be an compiler bug, if I disable optimizations for memset no fault occurs. Here is the asm for the optimized memset and the unoptimised memset:

0000000000013f78 <memset>:
   13f78:       fb010113                addi    sp,sp,-80
   13f7c:       04813423                sd      s0,72(sp)
   13f80:       05010413                addi    s0,sp,80
   13f84:       fca43423                sd      a0,-56(s0)
   13f88:       00058793                mv      a5,a1
   13f8c:       fac43c23                sd      a2,-72(s0)
   13f90:       fcf42223                sw      a5,-60(s0)
   13f94:       fc843703                ld      a4,-56(s0)
   13f98:       fb843783                ld      a5,-72(s0)
   13f9c:       00f767b3                or      a5,a4,a5
   13fa0:       0077f793                andi    a5,a5,7
   13fa4:       08079263                bnez    a5,14028 <memset+0xb0>
   13fa8:       fc442783                lw      a5,-60(s0)
   13fac:       0ff7f793                zext.b  a5,a5
   13fb0:       fcf43c23                sd      a5,-40(s0)
   13fb4:       fd843783                ld      a5,-40(s0)
   13fb8:       00879793                slli    a5,a5,0x8
   13fbc:       fd843703                ld      a4,-40(s0)
   13fc0:       00f767b3                or      a5,a4,a5
   13fc4:       fcf43c23                sd      a5,-40(s0)
   13fc8:       fd843783                ld      a5,-40(s0)
   13fcc:       01079793                slli    a5,a5,0x10
   13fd0:       fd843703                ld      a4,-40(s0)
   13fd4:       00f767b3                or      a5,a4,a5
   13fd8:       fcf43c23                sd      a5,-40(s0)
   13fdc:       fd843783                ld      a5,-40(s0)
   13fe0:       02079793                slli    a5,a5,0x20
   13fe4:       fd843703                ld      a4,-40(s0)
   13fe8:       00f767b3                or      a5,a4,a5
   13fec:       fcf43c23                sd      a5,-40(s0)
   13ff0:       fc843783                ld      a5,-56(s0)
   13ff4:       fef43423                sd      a5,-24(s0)
   13ff8:       0180006f                j       14010 <memset+0x98>
   13ffc:       fe843783                ld      a5,-24(s0)
   14000:       00878713                addi    a4,a5,8
   14004:       fee43423                sd      a4,-24(s0)
   14008:       fd843703                ld      a4,-40(s0)
   1400c:       00e7b023                sd      a4,0(a5)
   14010:       fc843703                ld      a4,-56(s0)
   14014:       fb843783                ld      a5,-72(s0)
   14018:       00f707b3                add     a5,a4,a5
   1401c:       fe843703                ld      a4,-24(s0)
   14020:       fcf76ee3                bltu    a4,a5,13ffc <memset+0x84>
   14024:       03c0006f                j       14060 <memset+0xe8>
   14028:       fc843783                ld      a5,-56(s0)
   1402c:       fef43023                sd      a5,-32(s0)
   1402c:       fef43023                sd      a5,-32(s0)
   14030:       01c0006f                j       1404c <memset+0xd4>
   14034:       fe043783                ld      a5,-32(s0)
   14038:       00178713                addi    a4,a5,1
   1403c:       fee43023                sd      a4,-32(s0)
   14040:       fc442703                lw      a4,-60(s0)
   14044:       0ff77713                zext.b  a4,a4
   14048:       00e78023                sb      a4,0(a5)
   1404c:       fc843703                ld      a4,-56(s0)
   14050:       fb843783                ld      a5,-72(s0)
   14054:       00f707b3                add     a5,a4,a5
   14058:       fe043703                ld      a4,-32(s0)
   1405c:       fcf76ce3                bltu    a4,a5,14034 <memset+0xbc>
   14060:       fc843783                ld      a5,-56(s0)
   14064:       00078513                mv      a0,a5
   14068:       04813403                ld      s0,72(sp)
   1406c:       05010113                addi    sp,sp,80
   14070:       00008067                ret

optimised

0000000000014090 <memset>:
   14090:       fe010113                addi    sp,sp,-32
   14094:       00813823                sd      s0,16(sp)
   14098:       00913423                sd      s1,8(sp)
   1409c:       00113c23                sd      ra,24(sp)
   140a0:       02010413                addi    s0,sp,32
   140a4:       00c567b3                or      a5,a0,a2
   140a8:       0077f793                andi    a5,a5,7
   140ac:       00050493                mv      s1,a0
   140b0:       00c50733                add     a4,a0,a2
   140b4:       02078463                beqz    a5,140dc <memset+0x4c>
   140b8:       00e57663                bgeu    a0,a4,140c4 <memset+0x34>
   140bc:       0ff5f593                zext.b  a1,a1
   140c0:       fd1ff0ef                jal     ra,14090 <memset>
   140c4:       01813083                ld      ra,24(sp)
   140c8:       01013403                ld      s0,16(sp)
   140cc:       00048513                mv      a0,s1
   140d0:       00813483                ld      s1,8(sp)
   140d4:       02010113                addi    sp,sp,32
   140d8:       00008067                ret
   140dc:       0ff5f593                zext.b  a1,a1
   140e0:       00859693                slli    a3,a1,0x8
   140e4:       00b6e6b3                or      a3,a3,a1
   140e8:       01069793                slli    a5,a3,0x10
   140ec:       00d7e7b3                or      a5,a5,a3
   140f0:       02079693                slli    a3,a5,0x20
   140f4:       00f6e6b3                or      a3,a3,a5
   140f8:       fce576e3                bgeu    a0,a4,140c4 <memset+0x34>
   140fc:       00050793                mv      a5,a0
   14100:       00878793                addi    a5,a5,8
   14104:       fed7bc23                sd      a3,-8(a5)
   14108:       fee7ece3                bltu    a5,a4,14100 <memset+0x70>
   1410c:       01813083                ld      ra,24(sp)
   14110:       01013403                ld      s0,16(sp)
   14114:       00048513                mv      a0,s1
   14118:       00813483                ld      s1,8(sp)
   1411c:       02010113                addi    sp,sp,32
   14120:       00008067                ret

@shirinebadi
Copy link

Hi @shimunn. I also have the same problem with memset used in libsodium. Can you tell me how you disabled optimization? I'm using Compile flag but it seems like it's being overriden since I see no changes.

@mdrssv
Copy link
Author

mdrssv commented Oct 23, 2024

Just used pragmas around the memset function

diff --git a/sdk/src/app/string.c b/sdk/src/app/string.c
index 249f3ba..ae45f58 100644
--- a/sdk/src/app/string.c
+++ b/sdk/src/app/string.c
@@ -31,6 +31,9 @@ strlen(char* str) {
   return len;
 }

+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+
 void*
 memset(void* dest, int byte, size_t len) {
   if ((((uintptr_t)dest | len) & (sizeof(uintptr_t) - 1)) == 0) {
@@ -47,6 +50,7 @@ memset(void* dest, int byte, size_t len) {
   }
   return dest;
 }
+#pragma GCC pop_options

 int
 memcmp(const void* s1, const void* s2, size_t n) {

@shirinebadi
Copy link

thanks. I also tried volatile pointer and it works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants