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

weak memcpy et al (take 3) #16

Closed
wants to merge 1 commit into from
Closed

weak memcpy et al (take 3) #16

wants to merge 1 commit into from

Conversation

japaric
Copy link
Member

@japaric japaric commented Aug 8, 2016

@Amanieu

place weak versions of mem* in a separate crate which is compiled to a staticlib. Then link that staticlib into rustc-builtins.

I tried to do this but I think I got something wrong because I'm getting infinite recursion with or without LTO. Here are some part of the output (LTO enabled):

$ xargo rustc --release --verbose --bin 05-init-data -- -Z print-link-args
   Compiling rustc_builtins v0.1.0 (file:///home/japaric/rust/rustc-builtins)
   Compiling rlibc v0.1.0 (file:///home/japaric/rust/rustc-builtins/rlibc)
     Running `rustc /home/japaric/rust/rustc-builtins/build.rs --crate-name build_script_build --crate-type bin -C opt-level=3 -C metadata=82b68e925bf22b83 --out-dir /home/japaric/rust/cu/target/release/build/rustc_builtins-82b68e925bf22b83 --emit=dep-info,link -L dependency=/home/japaric/rust/cu/target/release/deps`
     Running `rustc /home/japaric/rust/rustc-builtins/rlibc/src/lib.rs --crate-name rlibc --crate-type staticlib -C opt-level=3 -C lto -C metadata=f1bfe029934b1881 --out-dir /home/japaric/rust/cu/target/cortex-m3/release/deps --emit=dep-info,link --target cortex-m3 -L dependency=/home/japaric/rust/cu/target/cortex-m3/release/deps --sysroot=/home/japaric/.xargo`
     Running `/home/japaric/rust/cu/target/release/build/rustc_builtins-82b68e925bf22b83/build-script-build`
     Running `rustc /home/japaric/rust/rustc-builtins/src/lib.rs --crate-name rustc_builtins --crate-type lib -C opt-level=3 -C metadata=82b68e925bf22b83 --out-dir /home/japaric/rust/cu/target/cortex-m3/release/deps --emit=dep-info,link --target cortex-m3 -L dependency=/home/japaric/rust/cu/target/cortex-m3/release/deps --sysroot=/home/japaric/.xargo -L native=/home/japaric/rust/cu/target/cortex-m3/release/deps -l static=rlibc`
   Compiling cu v0.1.0 (file:///home/japaric/rust/cu)
     Running `rustc src/lib.rs --crate-name cu --crate-type lib -C opt-level=3 -C metadata=fc950a7ec6dc0646 --out-dir /home/japaric/rust/cu/target/cortex-m3/release/deps --emit=dep-info,link --target cortex-m3 -L dependency=/home/japaric/rust/cu/target/cortex-m3/release/deps --extern rustc_builtins=/home/japaric/rust/cu/target/cortex-m3/release/deps/librustc_builtins.rlib --sysroot=/home/japaric/.xargo -L native=/home/japaric/rust/cu/target/cortex-m3/release/deps`
     Running `rustc src/bin/05-init-data.rs --crate-name 05_init_data --crate-type bin -C opt-level=3 -C lto -Z print-link-args -C metadata=fc950a7ec6dc0646 --out-dir /home/japaric/rust/cu/target/cortex-m3/release --emit=dep-info,link --target cortex-m3 -L dependency=/home/japaric/rust/cu/target/cortex-m3/release/deps --extern rustc_builtins=/home/japaric/rust/cu/target/cortex-m3/release/deps/librustc_builtins.rlib --extern cu=/home/japaric/rust/cu/target/cortex-m3/release/deps/libcu.rlib --sysroot=/home/japaric/.xargo -L native=/home/japaric/rust/cu/target/cortex-m3/release/deps`
"arm-none-eabi-gcc" "-Wl,-(" "-Tstm32f100.ld" "-nostartfiles" "-L" "/home/japaric/.xargo/lib/rustlib/cortex-m3/lib" "/home/japaric/rust/cu/target/cortex-m3/release/05_init_data.0.o" "-o" "/home/japaric/rust/cu/target/cortex-m3/release/05_init_data" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "/home/japaric/rust/cu/target/cortex-m3/release/deps" "-L" "/home/japaric/rust/cu/target/cortex-m3/release/deps" "-L" "/home/japaric/.xargo/lib/rustlib/cortex-m3/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/tmp/rustc.570xljiAIXm6/librustc_builtins.rlib" "-Wl,-)"
$ arm-none-eabi-objdump -Cd target/cortex-m3/release/05-init-data
08000120 <start>:
 8000120:       b580            push    {r7, lr}
 8000122:       f240 0000       movw    r0, #0
 8000126:       f240 0100       movw    r1, #0
 800012a:       f2c2 0000       movt    r0, #8192       ; 0x2000
 800012e:       f2c2 0100       movt    r1, #8192       ; 0x2000
 8000132:       1a09            subs    r1, r1, r0
 8000134:       f021 0203       bic.w   r2, r1, #3
 8000138:       f240 1150       movw    r1, #336        ; 0x150
 800013c:       f6c0 0100       movt    r1, #2048       ; 0x800
 8000140:       f000 f804       bl      800014c <__aeabi_memcpy4>
 8000144:       e7fe            b.n     8000144 <start+0x24>

08000146 <__default_handler>:
 8000146:       be00            bkpt    0x0000
 8000148:       4770            bx      lr

0800014a <__aeabi_memcpy>:
 800014a:       e7fe            b.n     800014a <__aeabi_memcpy>

0800014c <__aeabi_memcpy4>:
 800014c:       f7ff bffd       b.w     800014a <__aeabi_memcpy>
$ tree target
target
├── cortex-m3
│   └── release
│       ├── deps
│       │   ├── libcu.rlib
│       │   ├── librlibc.a
│       │   └── librustc_builtins.rlib
$ arm-none-eabi-objdump -Cd target/cortex-m3/release/deps/librlibc.a
00000000 <memcpy>:
   0:   2a00            cmp     r2, #0
   2:   bf08            it      eq
   4:   4770            bxeq    lr
   6:   4684            mov     ip, r0
   8:   f811 3b01       ldrb.w  r3, [r1], #1
   c:   3a01            subs    r2, #1
   e:   f80c 3b01       strb.w  r3, [ip], #1
  12:   d1f9            bne.n   8 <memcpy+0x8>
  14:   4770            bx      lr

Disassembly of section .text.memmove:

00000000 <memmove>:
   0:   4281            cmp     r1, r0
   2:   d20c            bcs.n   1e <memmove+0x1e>
   4:   2a00            cmp     r2, #0
   6:   bf08            it      eq
   8:   4770            bxeq    lr
   a:   188b            adds    r3, r1, r2
   c:   eb00 0c02       add.w   ip, r0, r2
  10:   3a01            subs    r2, #1
  12:   f813 3c01       ldrb.w  r3, [r3, #-1]
  16:   f80c 3c01       strb.w  r3, [ip, #-1]
  1a:   d1f6            bne.n   a <memmove+0xa>
  1c:   e007            b.n     2e <memmove+0x2e>
  1e:   b132            cbz     r2, 2e <memmove+0x2e>
  20:   4684            mov     ip, r0
  22:   f811 3b01       ldrb.w  r3, [r1], #1
  26:   3a01            subs    r2, #1
  28:   f80c 3b01       strb.w  r3, [ip], #1
  2c:   d1f9            bne.n   22 <memmove+0x22>
  2e:   4770            bx      lr

Disassembly of section .text.memset:

00000000 <memset>:
   0:   2a00            cmp     r2, #0
   2:   bf08            it      eq
   4:   4770            bxeq    lr
   6:   4603            mov     r3, r0
   8:   f803 1b01       strb.w  r1, [r3], #1
   c:   3a01            subs    r2, #1
   e:   d1fb            bne.n   8 <memset+0x8>
  10:   4770            bx      lr
$ arm-none-eabi-objdump -Cd target/cortex-m3/release/deps/librustc_builtins.rlib
00000000 <__aeabi_memcpy>:
   0:   e7fe            b.n     0 <__aeabi_memcpy>

Disassembly of section .text.__aeabi_memcpy4:

00000000 <__aeabi_memcpy4>:
   0:   f7ff bffe       b.w     0 <__aeabi_memcpy4>

@Amanieu
Copy link
Member

Amanieu commented Aug 8, 2016

OK, I tried this on my end and it worked. You need to move the ARM __aeabi_mem* functions into the rlibc sub-crate. Basically just move arm.rs into rlibc/src. This gives me the following results:

target/cortex-m3/release/05-init-data:     file format elf32-littlearm


Disassembly of section .text:

08000120 <start>:
 8000120:   b580        push    {r7, lr}
 8000122:   f240 0000   movw    r0, #0
 8000126:   f240 0100   movw    r1, #0
 800012a:   f2c2 0000   movt    r0, #8192   ; 0x2000
 800012e:   f2c2 0100   movt    r1, #8192   ; 0x2000
 8000132:   1a09        subs    r1, r1, r0
 8000134:   f021 0203   bic.w   r2, r1, #3
 8000138:   f240 1164   movw    r1, #356    ; 0x164
 800013c:   f6c0 0100   movt    r1, #2048   ; 0x800
 8000140:   f000 f80e   bl  8000160 <__aeabi_memcpy4>
 8000144:   e7fe        b.n 8000144 <start+0x24>

08000146 <__default_handler>:
 8000146:   be00        bkpt    0x0000
 8000148:   4770        bx  lr

0800014a <memcpy>:
 800014a:   2a00        cmp r2, #0
 800014c:   bf08        it  eq
 800014e:   4770        bxeq    lr
 8000150:   4684        mov ip, r0
 8000152:   f811 3b01   ldrb.w  r3, [r1], #1
 8000156:   3a01        subs    r2, #1
 8000158:   f80c 3b01   strb.w  r3, [ip], #1
 800015c:   d1f9        bne.n   8000152 <memcpy+0x8>
 800015e:   4770        bx  lr

08000160 <__aeabi_memcpy4>:
 8000160:   f7ff bff3   b.w 800014a <memcpy>

@Amanieu
Copy link
Member

Amanieu commented Aug 8, 2016

Actually I think we could do this for the entire crate: build rustc_builtins_inner as a staticlib (with #![no_builtins]) containing all the builtin functions, and then have rustc_builtins as a rlib which links to the staticlib.

@japaric
Copy link
Member Author

japaric commented Aug 12, 2016

I really dislike this hack 😞. Let's punt this until rust-lang/rust#35540 is fixed. In the meantime, one can use the rlibc crate to get memcpy et al, but not with LTO enabled because then one hits the recursive call problem observed here.

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

Successfully merging this pull request may close these issues.

2 participants