1
1
//! Linking for Universal-compiled code.
2
2
3
3
use crate :: trampoline:: get_libcall_trampoline;
4
+ use std:: collections:: HashMap ;
4
5
use std:: ptr:: { read_unaligned, write_unaligned} ;
5
6
use wasmer_compiler:: {
6
7
JumpTable , JumpTableOffsets , Relocation , RelocationKind , RelocationTarget , Relocations ,
@@ -19,6 +20,7 @@ fn apply_relocation(
19
20
allocated_sections : & PrimaryMap < SectionIndex , SectionBodyPtr > ,
20
21
libcall_trampolines : SectionIndex ,
21
22
libcall_trampoline_len : usize ,
23
+ riscv_pcrel_hi20s : & mut HashMap < usize , u32 > ,
22
24
) {
23
25
let target_func_address: usize = match r. reloc_target {
24
26
RelocationTarget :: LocalFunc ( index) => * allocated_functions[ index] . ptr as usize ,
@@ -107,6 +109,32 @@ fn apply_relocation(
107
109
| read_unaligned ( reloc_address as * mut u32 ) ;
108
110
write_unaligned ( reloc_address as * mut u32 , reloc_delta) ;
109
111
} ,
112
+ RelocationKind :: RiscvPCRelHi20 => unsafe {
113
+ let ( reloc_address, reloc_delta) = r. for_address ( body, target_func_address as u64 ) ;
114
+
115
+ // save for later reference with RiscvPCRelLo12I
116
+ riscv_pcrel_hi20s. insert ( reloc_address, reloc_delta as u32 ) ;
117
+
118
+ let reloc_delta = ( ( reloc_delta. wrapping_add ( 0x800 ) & 0xfffff000 ) as u32 )
119
+ | read_unaligned ( reloc_address as * mut u32 ) ;
120
+ write_unaligned ( reloc_address as * mut u32 , reloc_delta) ;
121
+ } ,
122
+ RelocationKind :: RiscvPCRelLo12I => unsafe {
123
+ let ( reloc_address, reloc_abs) = r. for_address ( body, target_func_address as u64 ) ;
124
+ let reloc_delta = ( ( riscv_pcrel_hi20s. get ( & ( reloc_abs as usize ) ) . expect (
125
+ "R_RISCV_PCREL_LO12_I relocation target must be a symbol with R_RISCV_PCREL_HI20" ,
126
+ ) & 0xfff )
127
+ << 20 )
128
+ | read_unaligned ( reloc_address as * mut u32 ) ;
129
+ write_unaligned ( reloc_address as * mut u32 , reloc_delta) ;
130
+ } ,
131
+ RelocationKind :: RiscvCall => unsafe {
132
+ let ( reloc_address, reloc_delta) = r. for_address ( body, target_func_address as u64 ) ;
133
+ let reloc_delta = ( ( reloc_delta & 0xfff ) << 52 )
134
+ | ( reloc_delta. wrapping_add ( 0x800 ) & 0xfffff000 )
135
+ | read_unaligned ( reloc_address as * mut u64 ) ;
136
+ write_unaligned ( reloc_address as * mut u64 , reloc_delta) ;
137
+ } ,
110
138
kind => panic ! (
111
139
"Relocation kind unsupported in the current architecture {}" ,
112
140
kind
@@ -126,6 +154,8 @@ pub fn link_module(
126
154
libcall_trampolines : SectionIndex ,
127
155
trampoline_len : usize ,
128
156
) {
157
+ let mut riscv_pcrel_hi20s: HashMap < usize , u32 > = HashMap :: new ( ) ;
158
+
129
159
for ( i, section_relocs) in section_relocations. iter ( ) {
130
160
let body = * allocated_sections[ i] as usize ;
131
161
for r in section_relocs {
@@ -137,6 +167,7 @@ pub fn link_module(
137
167
allocated_sections,
138
168
libcall_trampolines,
139
169
trampoline_len,
170
+ & mut riscv_pcrel_hi20s,
140
171
) ;
141
172
}
142
173
}
@@ -151,6 +182,7 @@ pub fn link_module(
151
182
allocated_sections,
152
183
libcall_trampolines,
153
184
trampoline_len,
185
+ & mut riscv_pcrel_hi20s,
154
186
) ;
155
187
}
156
188
}
0 commit comments