Skip to content

Commit 939d287

Browse files
committed
refactor: rework object section memory handling
1 parent 5f46d61 commit 939d287

32 files changed

Lines changed: 1161 additions & 775 deletions

src/arch/riscv64/object.rs

Lines changed: 39 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use 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

Comments
 (0)