Repository: rust
Issue: Code compiled with rwpi relocation model is linked to `alloc` crate with static relocation model.
Labels: A-linkage,O-Arm,C-bug

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

I'm working on ARM Cortex-m4 and buiding my code with `ropi-rwpi` relocation model. Register R9 should be reserved as the data segment base pointer under `rwpi`. By default, the compiled code is linked to pre-compiled `core` and `alloc` crate. These two pre-compiled crate should also be compiled with `ropi-rwpi`, but are not. I believe that my `ropi-rwpi` object file is linked to the `static` version of `core` and `alloc`. The evidence is that the code in `alloc` still treats R9 as a free-to-use register.

I have a minimal example as follows.

```rust
#![no_main]
#![no_std]
#![feature(start)]
#![feature(default_alloc_error_handler)]

extern crate alloc;
use alloc::{format, alloc::{GlobalAlloc, Layout}};
use core::panic::PanicInfo;

/// Just to have an allocator so that we can compile the code.
/// It doesn't do anything correct but only gets the code compile.
struct DummyAllocator;

unsafe impl GlobalAlloc for DummyAllocator {
    unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
        return 0x2001000 as *mut u8;
    }

    unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}

#[global_allocator]
static DUMMY_ALLOCATOR: DummyAllocator = DummyAllocator;

#[start]
#[export_name = "ENTRY_FUNC"]
pub extern "C" fn main() {
    // Here the problem occurs. The code in `alloc` crate will
    // change R9 register.
    let _s = format!("{}", "boom!");
    loop {}
}

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}
```

If we compile the code and examine one of the function belonging to `format!`, we can see that the instruction at `0x8000d94` is modifying the R9 register.
```
08000d82 _ZN4core3fmt9Formatter3pad17h508d4338e51c22a9E:
 8000d82: f0 b5                         push    {r4, r5, r6, r7, lr}
 8000d84: 03 af                         add     r7, sp, #12
 8000d86: 2d e9 00 0f                   push.w  {r8, r9, r10, r11}
 8000d8a: 83 b0                         sub     sp, #12
 8000d8c: 0c 46                         mov     r4, r1
 8000d8e: d0 f8 08 e0                   ldr.w   lr, [r0, #8]
 8000d92: 01 69                         ldr     r1, [r0, #16]
 8000d94: 91 46                         mov     r9, r2 ; Things go wrong starting from here...
 8000d96: be f1 01 0f                   cmp.w   lr, #1
 8000d9a: 13 d1                         bne     #38 <_ZN4core3fmt9Formatter3pad17h508d4338e5
1c22a9E+0x46>
 8000d9c: 01 29                         cmp     r1, #1
... ... ... ...
```

I find a workaround, that is to build the `core` and `alloc` crate locally, by `cargo build -Z build-std=core,alloc`. Then, it will no longer modify the R9 register.

So it seems that when `rwpi` is used, `cargo` should either compile `core` and `alloc` locally or download the pre-compiled version in `rwpi`. Linking to the `static` version just wouldn't work.

My minimal code example is here: https://github.com/Acciente717/rwpi-wrong-link

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.53.0-nightly (7af1f55ae 2021-04-15)
binary: rustc
commit-hash: 7af1f55ae359e731c2c303f5d98e42a1a8163af0
commit-date: 2021-04-15
host: x86_64-apple-darwin
release: 1.53.0-nightly
LLVM version: 12.0.0
```