11use crate :: {
22 RelocReason , Result ,
33 arch:: riscv64:: relocation:: RiscV64Arch ,
4- elf:: { ElfHashTable , ElfRelType , ElfRelocationType } ,
5- object:: layout:: { GotEntry , ObjectRelocKey , PltEntry , PltGotSection } ,
4+ elf:: { ElfHashTable , ElfRelType , ElfRelocationType , ElfShdr } ,
5+ object:: {
6+ layout:: { GotEntry , ObjectRelocKey , PltEntry , PltGotSection } ,
7+ object_relocation_addend, object_relocation_entries, object_relocation_sections,
8+ } ,
69 observer:: RelocationObserver ,
710 os:: { ImageMemory , RegionAccess , VmAddr , VmOffset } ,
811 relocation:: { ObjectRelocationArch , RelocHelper , RelocationHandler , reloc_error} ,
@@ -85,7 +88,7 @@ impl ObjectRelocationArch for RiscV64Arch {
8588 fn prepare_object_relocation < D , R , PreH , PostH , Obs , H , Memory > (
8689 state : & mut Self :: ObjectRelocationState ,
8790 helper : & mut RelocHelper < ' _ , D , Self , R , PreH , PostH , Obs , H , Memory > ,
88- sections : & [ & ' static [ ElfRelType < Self > ] ] ,
91+ shdrs : & [ ElfShdr < < Self as crate :: relocation :: RelocationArch > :: Layout > ] ,
8992 ) -> Result < ( ) >
9093 where
9194 D : ' static ,
@@ -96,7 +99,7 @@ impl ObjectRelocationArch for RiscV64Arch {
9699 Obs : RelocationObserver < Self > + ?Sized ,
97100 Memory : ImageMemory ,
98101 {
99- Self :: prepare_object_relocation_impl ( state, helper, sections )
102+ Self :: prepare_object_relocation_impl ( state, helper, shdrs )
100103 }
101104
102105 #[ allow( private_bounds) ]
@@ -105,6 +108,7 @@ impl ObjectRelocationArch for RiscV64Arch {
105108 state : & mut Self :: ObjectRelocationState ,
106109 helper : & mut RelocHelper < ' _ , D , Self , R , PreH , PostH , Obs , H , Memory > ,
107110 rel : & ElfRelType < Self > ,
111+ target : & ElfShdr < <Self as crate :: relocation:: RelocationArch >:: Layout > ,
108112 pltgot : & mut PltGotSection ,
109113 ) -> Result < ( ) >
110114 where
@@ -116,7 +120,7 @@ impl ObjectRelocationArch for RiscV64Arch {
116120 Obs : RelocationObserver < Self > + ?Sized ,
117121 Memory : ImageMemory ,
118122 {
119- Self :: relocate_object_impl ( state, helper, rel, pltgot)
123+ Self :: relocate_object_impl ( state, helper, rel, target , pltgot)
120124 }
121125
122126 #[ inline]
@@ -134,7 +138,7 @@ impl RiscV64Arch {
134138 pub ( crate ) fn prepare_object_relocation_impl < D , R , PreH , PostH , Obs , H , Memory > (
135139 state : & mut RiscV64ObjectRelocationState ,
136140 helper : & mut RelocHelper < ' _ , D , Self , R , PreH , PostH , Obs , H , Memory > ,
137- sections : & [ & ' static [ ElfRelType < Self > ] ] ,
141+ shdrs : & [ ElfShdr < < Self as crate :: relocation :: RelocationArch > :: Layout > ] ,
138142 ) -> Result < ( ) >
139143 where
140144 D : ' static ,
@@ -145,20 +149,20 @@ impl RiscV64Arch {
145149 Obs : RelocationObserver < Self > + ?Sized ,
146150 Memory : ImageMemory ,
147151 {
148- let base = helper. core . base ( ) ;
149152 state. hi20_cache . clear ( ) ;
150153
151- for reloc_section in sections {
152- for rel in * reloc_section {
154+ for ( target, relocation_shdr) in object_relocation_sections :: < Self > ( shdrs) {
155+ let rels = object_relocation_entries :: < Self , _ > ( helper. memory ( ) , relocation_shdr) ?;
156+ for rel in rels {
153157 let r_type = rel. r_type ( ) . raw ( ) ;
154158 if r_type == R_RISCV_PCREL_HI20 || r_type == R_RISCV_GOT_HI20 {
155159 let addend = if r_type == R_RISCV_GOT_HI20 {
156160 0
157161 } else {
158- rel . r_addend ( base )
162+ object_relocation_addend :: < Self , _ > ( helper . memory ( ) , target , rel ) ?
159163 } ;
160164 state. hi20_cache . insert (
161- base . wrapping_add ( rel. r_offset ( ) ) ,
165+ VmAddr :: new ( target . sh_addr ( ) ) + rel. r_offset ( ) ,
162166 Hi20Relocation {
163167 symbol : rel. r_symbol ( ) ,
164168 addend,
@@ -178,6 +182,7 @@ impl RiscV64Arch {
178182 state : & mut RiscV64ObjectRelocationState ,
179183 helper : & mut RelocHelper < ' _ , D , Self , R , PreH , PostH , Obs , H , Memory > ,
180184 rel : & ElfRelType < Self > ,
185+ target : & ElfShdr < <Self as crate :: relocation:: RelocationArch >:: Layout > ,
181186 pltgot : & mut PltGotSection ,
182187 ) -> Result < ( ) >
183188 where
@@ -190,38 +195,28 @@ impl RiscV64Arch {
190195 Memory : ImageMemory ,
191196 {
192197 let r_type = rel. r_type ( ) . raw ( ) ;
193- let core = helper. core ;
194- let base = core. base ( ) ;
195- let addend = rel. r_addend ( base) ;
196- let place = base. wrapping_add ( rel. r_offset ( ) ) ;
197- let unknown_symbol =
198- || reloc_error :: < Self , _ , R , H > ( rel, RelocReason :: UnknownSymbol , helper. core ) ;
198+ let addend = object_relocation_addend :: < Self , _ > ( helper. memory ( ) , target, rel) ?;
199+ let place = VmAddr :: new ( target. sh_addr ( ) ) + rel. r_offset ( ) ;
199200 let value_error = |reason| reloc_error :: < Self , _ , R , H > ( rel, reason, helper. core ) ;
200201
201202 match r_type {
202203 R_RISCV_NONE | R_RISCV_RELAX => { }
203204 R_RISCV_64 => {
204- let Some ( sym) = helper. find_symbol ( rel) ? else {
205- return Err ( unknown_symbol ( ) ) ;
206- } ;
205+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
207206 unsafe {
208207 helper
209208 . memory ( )
210209 . write_value ( place, sym. wrapping_add_signed ( addend) . get ( ) ) ?
211210 } ;
212211 }
213212 R_RISCV_32 => {
214- let Some ( sym) = helper. find_symbol ( rel) ? else {
215- return Err ( unknown_symbol ( ) ) ;
216- } ;
213+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
217214 let value = u32:: try_from ( sym. wrapping_add_signed ( addend) . get ( ) )
218215 . map_err ( |_| value_error ( RelocReason :: IntConversionOutOfRange ) ) ?;
219216 unsafe { helper. memory ( ) . write_value ( place, value) ? } ;
220217 }
221218 R_RISCV_32_PCREL => {
222- let Some ( sym) = helper. find_symbol ( rel) ? else {
223- return Err ( unknown_symbol ( ) ) ;
224- } ;
219+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
225220 let value = i32:: try_from (
226221 sym. wrapping_add_signed ( addend) . get ( ) as i128 - place. get ( ) as i128 ,
227222 )
@@ -245,9 +240,7 @@ impl RiscV64Arch {
245240 } ;
246241 }
247242 R_RISCV_CALL | R_RISCV_CALL_PLT => {
248- let Some ( sym) = helper. find_symbol ( rel) ? else {
249- return Err ( unknown_symbol ( ) ) ;
250- } ;
243+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
251244 let mut target = sym;
252245 let direct_off = signed_offset ( target, addend, place) ;
253246 if r_type == R_RISCV_CALL_PLT
@@ -267,9 +260,7 @@ impl RiscV64Arch {
267260 if addend != 0 {
268261 return Err ( value_error ( RelocReason :: Unsupported ) ) ;
269262 }
270- let Some ( sym) = helper. find_symbol ( rel) ? else {
271- return Err ( unknown_symbol ( ) ) ;
272- } ;
263+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
273264 let key = ObjectRelocKey :: new :: < Self > ( rel) ;
274265 let got_addr = Self :: ensure_got_entry ( pltgot, key, sym) ;
275266 let hi20 = ( got_addr. get ( ) as i64 - place. get ( ) as i64 + 0x800 ) >> 12 ;
@@ -280,9 +271,7 @@ impl RiscV64Arch {
280271 } ;
281272 }
282273 R_RISCV_PCREL_HI20 => {
283- let Some ( sym) = helper. find_symbol ( rel) ? else {
284- return Err ( unknown_symbol ( ) ) ;
285- } ;
274+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
286275 let off = signed_offset ( sym, addend, place) ;
287276 let hi20 = ( off + 0x800 ) >> 12 ;
288277 unsafe {
@@ -292,7 +281,7 @@ impl RiscV64Arch {
292281 } ;
293282 }
294283 R_RISCV_PCREL_LO12_I | R_RISCV_PCREL_LO12_S => {
295- let lo12 = Self :: resolve_pcrel_lo12 ( state, helper, rel, pltgot) ?;
284+ let lo12 = Self :: resolve_pcrel_lo12 ( state, helper, rel, target , pltgot) ?;
296285 let imm_type = if r_type == R_RISCV_PCREL_LO12_I {
297286 ImmType :: I
298287 } else {
@@ -305,9 +294,7 @@ impl RiscV64Arch {
305294 } ;
306295 }
307296 R_RISCV_HI20 => {
308- let Some ( sym) = helper. find_symbol ( rel) ? else {
309- return Err ( unknown_symbol ( ) ) ;
310- } ;
297+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
311298 let hi20 = ( sym. wrapping_add_signed ( addend) . get ( ) as i64 + 0x800 ) >> 12 ;
312299 unsafe {
313300 helper. memory ( ) . update_value :: < u32 > ( place, |insn| {
@@ -316,9 +303,7 @@ impl RiscV64Arch {
316303 } ;
317304 }
318305 R_RISCV_LO12_I | R_RISCV_LO12_S => {
319- let Some ( sym) = helper. find_symbol ( rel) ? else {
320- return Err ( unknown_symbol ( ) ) ;
321- } ;
306+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
322307 let lo12 = sym. wrapping_add_signed ( addend) . get ( ) as i64 & 0xfff ;
323308 let imm_type = if r_type == R_RISCV_LO12_I {
324309 ImmType :: I
@@ -333,9 +318,7 @@ impl RiscV64Arch {
333318 }
334319 R_RISCV_ADD8 | R_RISCV_ADD16 | R_RISCV_ADD32 | R_RISCV_ADD64 | R_RISCV_SUB8
335320 | R_RISCV_SUB16 | R_RISCV_SUB32 | R_RISCV_SUB64 => {
336- let Some ( sym) = helper. find_symbol ( rel) ? else {
337- return Err ( unknown_symbol ( ) ) ;
338- } ;
321+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
339322 let value = sym. wrapping_add_signed ( addend) . get ( ) ;
340323 let is_add = matches ! (
341324 r_type,
@@ -370,9 +353,7 @@ impl RiscV64Arch {
370353 }
371354 }
372355 R_RISCV_SUB6 => {
373- let Some ( sym) = helper. find_symbol ( rel) ? else {
374- return Err ( unknown_symbol ( ) ) ;
375- } ;
356+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
376357 let value = sym. wrapping_add_signed ( addend) . get ( ) as u8 ;
377358 unsafe {
378359 helper. memory ( ) . update_value :: < u8 > ( place, |old| {
@@ -381,9 +362,7 @@ impl RiscV64Arch {
381362 } ;
382363 }
383364 R_RISCV_SET6 => {
384- let Some ( sym) = helper. find_symbol ( rel) ? else {
385- return Err ( unknown_symbol ( ) ) ;
386- } ;
365+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
387366 let value = sym. wrapping_add_signed ( addend) . get ( ) as u8 ;
388367 unsafe {
389368 helper
@@ -471,6 +450,7 @@ impl RiscV64Arch {
471450 state : & RiscV64ObjectRelocationState ,
472451 helper : & mut RelocHelper < ' _ , D , Self , R , PreH , PostH , Obs , H , Memory > ,
473452 rel : & ElfRelType < Self > ,
453+ target : & ElfShdr < <Self as crate :: relocation:: RelocationArch >:: Layout > ,
474454 pltgot : & mut PltGotSection ,
475455 ) -> Result < i64 >
476456 where
@@ -482,13 +462,7 @@ impl RiscV64Arch {
482462 Obs : RelocationObserver < Self > + ?Sized ,
483463 Memory : ImageMemory ,
484464 {
485- let Some ( auipc_addr) = helper. find_symbol ( rel) ? else {
486- return Err ( reloc_error :: < Self , _ , R , H > (
487- rel,
488- RelocReason :: UnknownSymbol ,
489- helper. core ,
490- ) ) ;
491- } ;
465+ let auipc_addr = helper. symbol_addr ( rel. r_symbol ( ) ) ;
492466 let Some ( hi20) = state. hi20_cache . get ( & auipc_addr) . copied ( ) else {
493467 return Err ( reloc_error :: < Self , _ , R , H > (
494468 rel,
@@ -498,29 +472,17 @@ impl RiscV64Arch {
498472 } ;
499473
500474 let off = if hi20. r_type == R_RISCV_GOT_HI20 {
501- let Some ( sym) = helper. find_symdef ( hi20. symbol ) . map ( |sym| sym. convert ( ) ) else {
502- return Err ( reloc_error :: < Self , _ , R , H > (
503- rel,
504- RelocReason :: UnknownSymbol ,
505- helper. core ,
506- ) ) ;
507- } ;
475+ let sym = helper. symbol_addr ( hi20. symbol ) ;
508476 let key = hi20
509477 . got_key
510478 . expect ( "R_RISCV_GOT_HI20 relocation must carry a GOT key" ) ;
511479 let got_addr = Self :: ensure_got_entry ( pltgot, key, sym) ;
512480 got_addr. get ( ) as i64 - auipc_addr. get ( ) as i64
513481 } else {
514- let Some ( sym) = helper. find_symdef ( hi20. symbol ) . map ( |sym| sym. convert ( ) ) else {
515- return Err ( reloc_error :: < Self , _ , R , H > (
516- rel,
517- RelocReason :: UnknownSymbol ,
518- helper. core ,
519- ) ) ;
520- } ;
521- let target = sym
522- . wrapping_add_signed ( hi20. addend )
523- . wrapping_add_signed ( rel. r_addend ( helper. core . base ( ) ) ) ;
482+ let sym = helper. symbol_addr ( hi20. symbol ) ;
483+ let target = sym. wrapping_add_signed ( hi20. addend ) . wrapping_add_signed (
484+ object_relocation_addend :: < Self , _ > ( helper. memory ( ) , target, rel) ?,
485+ ) ;
524486 target. get ( ) as i64 - auipc_addr. get ( ) as i64
525487 } ;
526488
@@ -582,13 +544,7 @@ impl RiscV64Arch {
582544 Obs : RelocationObserver < Self > + ?Sized ,
583545 Memory : ImageMemory ,
584546 {
585- let Some ( sym) = helper. find_symbol ( rel) ? else {
586- return Err ( reloc_error :: < Self , _ , R , H > (
587- rel,
588- RelocReason :: UnknownSymbol ,
589- helper. core ,
590- ) ) ;
591- } ;
547+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
592548 unsafe {
593549 helper. memory ( ) . write_value (
594550 place,
@@ -678,13 +634,7 @@ where
678634 Obs : RelocationObserver < RiscV64Arch > + ?Sized ,
679635 Memory : ImageMemory ,
680636{
681- let Some ( sym) = helper. find_symbol ( rel) ? else {
682- return Err ( reloc_error :: < RiscV64Arch , _ , R , H > (
683- rel,
684- RelocReason :: UnknownSymbol ,
685- helper. core ,
686- ) ) ;
687- } ;
637+ let sym = helper. symbol_addr ( rel. r_symbol ( ) ) ;
688638 let off = signed_offset ( sym, addend, place) ;
689639 if off & 1 != 0 || off < -range || off >= range {
690640 return Err ( reloc_error :: < RiscV64Arch , _ , R , H > (
0 commit comments