Skip to content

Commit 212e2cd

Browse files
committed
feat(arch):support thumbv6m
1 parent f05bcb5 commit 212e2cd

File tree

22 files changed

+374
-345
lines changed

22 files changed

+374
-345
lines changed

Cargo.lock

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ authors = ["wzhao <1207410841@qq.com>"]
1717
edition = "2024"
1818
repository = "https://github.com/weizhiao/elf_loader"
1919
license = "MIT/Apache-2.0"
20-
rust-version = "1.88.0"
20+
rust-version = "1.93.0"
2121

2222
[workspace]
2323
members = ["crates/windows-elf-loader", "crates/mini-loader", "tools/gen-elf"]
@@ -73,7 +73,7 @@ optional = true
7373
features = ["alloc"]
7474

7575
[dependencies.spin]
76-
version = "0.9"
76+
version = "0.10"
7777
default-features = false
7878
features = ["mutex", "rwlock", "spin_mutex"]
7979

@@ -110,7 +110,11 @@ version = []
110110
# Enable logging.
111111
log = ["dep:log"]
112112
# support target without native pointer size atomic operation
113-
portable-atomic = ["dep:portable-atomic", "dep:portable-atomic-util"]
113+
portable-atomic = [
114+
"dep:portable-atomic",
115+
"dep:portable-atomic-util",
116+
"spin/portable_atomic",
117+
]
114118

115119
[[example]]
116120
name = "relocate_dylib"

src/arch/arm.rs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub const REL_COPY: u32 = R_ARM_COPY;
3030
/// TLS TPOFF relocation type - set to TLS offset relative to thread pointer.
3131
pub const REL_TPOFF: u32 = R_ARM_TLS_TPOFF32;
3232
/// TLSDESC relocation type - set to a function pointer and an argument.
33-
pub const REL_TLSDESC: u32 = 0;
33+
pub const REL_TLSDESC: u32 = 0xffff_ffff;
3434

3535
/// Get the current thread pointer using architecture-specific register.
3636
#[inline(always)]
@@ -62,56 +62,44 @@ pub(crate) const RESOLVE_FUNCTION_OFFSET: usize = 2;
6262
/// # Safety
6363
/// This function uses naked assembly and must be called with the correct
6464
/// stack layout set up by the PLT stub code.
65-
#[cfg(target_feature = "vfp2")]
6665
#[unsafe(naked)]
6766
pub(crate) extern "C" fn dl_runtime_resolve() {
6867
core::arch::naked_asm!(
6968
"
7069
// sp has original lr (4 bytes)
7170
// push r0-r4 (5 regs, 20 bytes). sp aligned to 8 bytes (aligned - 24).
7271
push {{r0, r1, r2, r3, r4}}
73-
vpush {{d0, d1, d2, d3, d4, d5, d6, d7}}
74-
72+
",
73+
#[cfg(target_feature = "vfp2")]
74+
"vpush {{d0, d1, d2, d3, d4, d5, d6, d7}}",
75+
"
7576
// r0 = link_map (GOT[1])
76-
ldr r0, [lr, #-4]
77+
// Case for thumb-1 compatibility: mov + sub + ldr
78+
mov r0, lr
79+
subs r0, r0, #4
80+
ldr r0, [r0]
7781
7882
// r1 = index
79-
add r1, lr, #4
80-
sub r1, ip, r1
81-
lsr r1, r1, #2
83+
mov r1, lr
84+
adds r1, r1, #4
85+
mov r2, ip
86+
subs r1, r2, r1
87+
lsrs r1, r1, #2
8288
83-
blx {0}
89+
bl {fixup}
8490
8591
mov ip, r0
86-
87-
vpop {{d0, d1, d2, d3, d4, d5, d6, d7}}
88-
pop {{r0, r1, r2, r3, r4, lr}}
89-
bx ip
9092
",
91-
sym crate::relocation::dl_fixup,
92-
)
93-
}
94-
95-
#[cfg(not(target_feature = "vfp2"))]
96-
#[unsafe(naked)]
97-
pub(crate) extern "C" fn dl_runtime_resolve() {
98-
core::arch::naked_asm!(
93+
#[cfg(target_feature = "vfp2")]
94+
"vpop {{d0, d1, d2, d3, d4, d5, d6, d7}}",
9995
"
100-
push {{r0, r1, r2, r3, r4}}
101-
102-
ldr r0, [lr, #-4]
103-
104-
add r1, lr, #4
105-
sub r1, ip, r1
106-
lsr r1, r1, #2
107-
108-
blx {0}
109-
110-
mov ip, r0
111-
pop {{r0, r1, r2, r3, r4, lr}}
96+
pop {{r0, r1, r2, r3, r4}}
97+
// pop original lr into r2 then move to lr
98+
pop {{r2}}
99+
mov lr, r2
112100
bx ip
113101
",
114-
sym crate::relocation::dl_fixup,
102+
fixup = sym crate::relocation::dl_fixup,
115103
)
116104
}
117105

src/arch/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ pub(crate) fn prepare_lazy_bind(got: *mut usize, dylib: usize) {
6464
unsafe {
6565
got.add(DYLIB_OFFSET).write(dylib);
6666
got.add(RESOLVE_FUNCTION_OFFSET)
67-
.write(dl_runtime_resolve as usize);
67+
.write(dl_runtime_resolve as *const () as usize);
6868
}
6969
}

src/arch/riscv32.rs

Lines changed: 87 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -45,107 +45,94 @@ pub(crate) unsafe fn get_thread_pointer() -> *mut u8 {
4545
pub(crate) const DYLIB_OFFSET: usize = 1;
4646
pub(crate) const RESOLVE_FUNCTION_OFFSET: usize = 0;
4747

48-
macro_rules! riscv32_dl_runtime_resolve {
49-
($save_fprs:expr, $restore_fprs:expr) => {
50-
#[unsafe(naked)]
51-
pub(crate) extern "C" fn dl_runtime_resolve() {
52-
core::arch::naked_asm!(
53-
"
54-
// 保存整数参数寄存器
55-
// ra, a0-a7: 9 * 4 = 36 bytes
56-
// 栈帧总大小设为 112 字节以保持 16 字节对齐
57-
addi sp,sp,-112
58-
sw ra,0(sp)
59-
sw a0,4(sp)
60-
sw a1,8(sp)
61-
sw a2,12(sp)
62-
sw a3,16(sp)
63-
sw a4,20(sp)
64-
sw a5,24(sp)
65-
sw a6,28(sp)
66-
sw a7,32(sp)
67-
",
68-
$save_fprs,
69-
"
70-
// 这两个是plt代码设置的
71-
mv a0,t0
72-
srli a1,t1,3
73-
// 调用重定位函数
74-
call {0}
75-
// 恢复参数寄存器
76-
mv t1,a0
77-
lw ra,0(sp)
78-
lw a0,4(sp)
79-
lw a1,8(sp)
80-
lw a2,12(sp)
81-
lw a3,16(sp)
82-
lw a4,20(sp)
83-
lw a5,24(sp)
84-
lw a6,28(sp)
85-
lw a7,32(sp)
86-
",
87-
$restore_fprs,
88-
"
89-
addi sp,sp,112
90-
// 执行真正的函数
91-
jr t1
92-
",
93-
sym crate::relocation::dl_fixup,
94-
)
95-
}
96-
};
48+
#[unsafe(naked)]
49+
pub(crate) extern "C" fn dl_runtime_resolve() {
50+
core::arch::naked_asm!(
51+
"
52+
// 保存整数参数寄存器
53+
// ra, a0-a7: 9 * 4 = 36 bytes
54+
// 栈帧总大小设为 112 字节以保持 16 字节对齐
55+
addi sp,sp,-112
56+
sw ra,0(sp)
57+
sw a0,4(sp)
58+
sw a1,8(sp)
59+
sw a2,12(sp)
60+
sw a3,16(sp)
61+
sw a4,20(sp)
62+
sw a5,24(sp)
63+
sw a6,28(sp)
64+
sw a7,32(sp)
65+
",
66+
#[cfg(target_feature = "d")]
67+
"
68+
fsd fa0,40(sp)
69+
fsd fa1,48(sp)
70+
fsd fa2,56(sp)
71+
fsd fa3,64(sp)
72+
fsd fa4,72(sp)
73+
fsd fa5,80(sp)
74+
fsd fa6,88(sp)
75+
fsd fa7,96(sp)
76+
",
77+
#[cfg(all(target_feature = "f", not(target_feature = "d")))]
78+
"
79+
fsw fa0,40(sp)
80+
fsw fa1,44(sp)
81+
fsw fa2,48(sp)
82+
fsw fa3,52(sp)
83+
fsw fa4,56(sp)
84+
fsw fa5,60(sp)
85+
fsw fa6,64(sp)
86+
fsw fa7,68(sp)
87+
",
88+
"
89+
// 这两个是plt代码设置的
90+
mv a0,t0
91+
srli a1,t1,3
92+
// 调用重定位函数
93+
call {0}
94+
// 恢复参数寄存器
95+
mv t1,a0
96+
lw ra,0(sp)
97+
lw a0,4(sp)
98+
lw a1,8(sp)
99+
lw a2,12(sp)
100+
lw a3,16(sp)
101+
lw a4,20(sp)
102+
lw a5,24(sp)
103+
lw a6,28(sp)
104+
lw a7,32(sp)
105+
",
106+
#[cfg(target_feature = "d")]
107+
"
108+
fld fa0,40(sp)
109+
fld fa1,48(sp)
110+
fld fa2,56(sp)
111+
fld fa3,64(sp)
112+
fld fa4,72(sp)
113+
fld fa5,80(sp)
114+
fld fa6,88(sp)
115+
fld fa7,96(sp)
116+
",
117+
#[cfg(all(target_feature = "f", not(target_feature = "d")))]
118+
"
119+
flw fa0,40(sp)
120+
flw fa1,44(sp)
121+
flw fa2,48(sp)
122+
flw fa3,52(sp)
123+
flw fa4,56(sp)
124+
flw fa5,60(sp)
125+
flw fa6,64(sp)
126+
flw fa7,68(sp)
127+
",
128+
"
129+
addi sp,sp,112
130+
// 执行真正的函数
131+
jr t1
132+
",
133+
sym crate::relocation::dl_fixup,
134+
)
97135
}
98-
99-
#[cfg(target_feature = "d")]
100-
riscv32_dl_runtime_resolve!(
101-
"
102-
fsd fa0,40(sp)
103-
fsd fa1,48(sp)
104-
fsd fa2,56(sp)
105-
fsd fa3,64(sp)
106-
fsd fa4,72(sp)
107-
fsd fa5,80(sp)
108-
fsd fa6,88(sp)
109-
fsd fa7,96(sp)
110-
",
111-
"
112-
fld fa0,40(sp)
113-
fld fa1,48(sp)
114-
fld fa2,56(sp)
115-
fld fa3,64(sp)
116-
fld fa4,72(sp)
117-
fld fa5,80(sp)
118-
fld fa6,88(sp)
119-
fld fa7,96(sp)
120-
"
121-
);
122-
123-
#[cfg(all(target_feature = "f", not(target_feature = "d")))]
124-
riscv32_dl_runtime_resolve!(
125-
"
126-
fsw fa0,40(sp)
127-
fsw fa1,44(sp)
128-
fsw fa2,48(sp)
129-
fsw fa3,52(sp)
130-
fsw fa4,56(sp)
131-
fsw fa5,60(sp)
132-
fsw fa6,64(sp)
133-
fsw fa7,68(sp)
134-
",
135-
"
136-
flw fa0,40(sp)
137-
flw fa1,44(sp)
138-
flw fa2,48(sp)
139-
flw fa3,52(sp)
140-
flw fa4,56(sp)
141-
flw fa5,60(sp)
142-
flw fa6,64(sp)
143-
flw fa7,68(sp)
144-
"
145-
);
146-
147-
#[cfg(not(target_feature = "f"))]
148-
riscv32_dl_runtime_resolve!("", "");
149136
/// Static TLSDESC resolver dummy for RISC-V 32.
150137
pub(crate) extern "C" fn tlsdesc_resolver_static() {
151138
unimplemented!("TLSDESC is not supported on RISC-V 32 yet");

0 commit comments

Comments
 (0)