Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integers are formatted incorrectly when cross-compiling to armv5te

When compiling the following program on my computer, it outputs the expected value:

fn main() {
    let number = 42;
    println!("number is {}", number);
}

number is 42

When cross-compiled for armv5te and run on the target, it outputs the following result:

number is 14

I believe that the implementation of Display for i32 is not working as expected. In particular, it seems that the characters printed are taken at the wrong index in the following array (found in libcore/fmt/num.rs):

const DEC_DIGITS_LUT: &'static[u8] =
    b"0001020304050607080910111213141516171819\
      2021222324252627282930313233343536373839\
      4041424344454647484950515253545556575859\
      6061626364656667686970717273747576777879\
      8081828384858687888990919293949596979899";

The two digits displayed are taken on the table at an offset of 1 byte to the left compared with the right place. I verified this hypothesis by testing with some other numbers (10 -> 91, 11 -> 01 for instance).

Other formats ({:b}, {:o}, {:x}) all give the expected result on my computer and on the target.


I am using a self compiled version of Rust (1.13.0, 2c6933acc 2016-11-07) for the successful test on my computer and the unsuccessful one on my ARM device. Here is the diff of the modifications I had to do:

diff --git a/mk/cfg/arm-unknown-linux-gnueabi.mk b/mk/cfg/arm-unknown-linux-gnueabi.mk
index f66ad04..b9e4157 100644
--- a/mk/cfg/arm-unknown-linux-gnueabi.mk
+++ b/mk/cfg/arm-unknown-linux-gnueabi.mk
@@ -1,5 +1,5 @@
 # arm-unknown-linux-gnueabi configuration
-CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-linux-gnueabi-
+CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-unknown-linux-uclibcgnueabi-
 CC_arm-unknown-linux-gnueabi=gcc
 CXX_arm-unknown-linux-gnueabi=g++
 CPP_arm-unknown-linux-gnueabi=gcc -E
@@ -8,8 +8,8 @@ CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
 CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
 CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
 CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
-CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -Darm -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
-CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -Darm -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
+CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -Darm -mfloat-abi=soft $(CFLAGS) -fno-stack-protector -march=armv5te -mtune=arm926ej-s
+CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -Darm -mfloat-abi=soft $(CFLAGS) -fno-stack-protector -march=armv5te -mtune=arm926ej-s
 CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
 CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
 CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
index e666a84..8af2596 100644
--- a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
+++ b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
 target_vendor: "unknown".to_string(),

 options: TargetOptions {
-            features: "+v6".to_string(),
+            features: "+v5te".to_string(),
 .. base
 },
 })
like image 951
Nicolas Jean Avatar asked Dec 28 '16 16:12

Nicolas Jean


1 Answers

I finally found a solution to this problem!
The problem was that LLVM was not properly configured and was generating code performing unaligned accesses. To fix this, I added the strict-align feature flag in src/librustc_back/target/arm_unknown_linux_gnueabi.rs
Here is the final diff with all the modifications I had to do:

diff --git a/mk/cfg/arm-unknown-linux-gnueabi.mk b/mk/cfg/arm-unknown-linux-gnueabi.mk
index f66ad04..b9e4157 100644
--- a/mk/cfg/arm-unknown-linux-gnueabi.mk
+++ b/mk/cfg/arm-unknown-linux-gnueabi.mk
@@ -1,5 +1,5 @@
 # arm-unknown-linux-gnueabi configuration
-CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-linux-gnueabi-
+CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-unknown-linux-uclibcgnueabi-
 CC_arm-unknown-linux-gnueabi=gcc
 CXX_arm-unknown-linux-gnueabi=g++
 CPP_arm-unknown-linux-gnueabi=gcc -E
@@ -8,8 +8,8 @@ CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
 CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
 CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
 CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
-CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
-CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfloat-abi=soft $(CFLAGS) -march=armv6 -marm
+CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfloat-abi=soft $(CFLAGS) -fno-stack-protector -march=armv5te -mtune=arm926ej-s
+CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfloat-abi=soft $(CFLAGS) -fno-stack-protector -march=armv5te -mtune=arm926ej-s
 CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
 CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
 CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
index e666a84..551bba0 100644
--- a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
+++ b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         target_vendor: "unknown".to_string(),

         options: TargetOptions {
-            features: "+v6".to_string(),
+            features: "+v5te,+strict-align".to_string(),
             .. base
         },
     })
like image 101
Nicolas Jean Avatar answered Sep 28 '22 05:09

Nicolas Jean