|
3 | 3 | use anyhow::anyhow; |
4 | 4 | use cranelift_codegen::binemit::{Addend, CodeOffset, Reloc}; |
5 | 5 | use cranelift_codegen::entity::SecondaryMap; |
| 6 | +use cranelift_codegen::ir; |
6 | 7 | use cranelift_codegen::isa::{OwnedTargetIsa, TargetIsa}; |
7 | | -use cranelift_codegen::{ir, FinalizedMachReloc}; |
8 | 8 | use cranelift_control::ControlPlane; |
9 | 9 | use cranelift_module::{ |
10 | 10 | DataDescription, DataId, FuncId, Init, Linkage, Module, ModuleDeclarations, ModuleError, |
@@ -345,65 +345,29 @@ impl Module for ObjectModule { |
345 | 345 | let res = ctx.compile(self.isa(), ctrl_plane)?; |
346 | 346 | let alignment = res.buffer.alignment as u64; |
347 | 347 |
|
348 | | - self.define_function_bytes( |
349 | | - func_id, |
350 | | - &ctx.func, |
351 | | - alignment, |
352 | | - ctx.compiled_code().unwrap().code_buffer(), |
353 | | - ctx.compiled_code().unwrap().buffer.relocs(), |
354 | | - ) |
| 348 | + let buffer = &ctx.compiled_code().unwrap().buffer; |
| 349 | + let relocs = buffer |
| 350 | + .relocs() |
| 351 | + .iter() |
| 352 | + .map(|reloc| { |
| 353 | + self.process_reloc(&ModuleReloc::from_mach_reloc(&reloc, &ctx.func, func_id)) |
| 354 | + }) |
| 355 | + .collect::<Vec<_>>(); |
| 356 | + self.define_function_inner(func_id, alignment, buffer.data(), relocs) |
355 | 357 | } |
356 | 358 |
|
357 | 359 | fn define_function_bytes( |
358 | 360 | &mut self, |
359 | 361 | func_id: FuncId, |
360 | | - func: &ir::Function, |
361 | 362 | alignment: u64, |
362 | 363 | bytes: &[u8], |
363 | | - relocs: &[FinalizedMachReloc], |
| 364 | + relocs: &[ModuleReloc], |
364 | 365 | ) -> ModuleResult<()> { |
365 | | - info!("defining function {} with bytes", func_id); |
366 | | - let decl = self.declarations.get_function_decl(func_id); |
367 | | - let decl_name = decl.linkage_name(func_id); |
368 | | - if !decl.linkage.is_definable() { |
369 | | - return Err(ModuleError::InvalidImportDefinition(decl_name.into_owned())); |
370 | | - } |
371 | | - |
372 | | - let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap(); |
373 | | - if *defined { |
374 | | - return Err(ModuleError::DuplicateDefinition(decl_name.into_owned())); |
375 | | - } |
376 | | - *defined = true; |
377 | | - |
378 | | - let align = alignment |
379 | | - .max(self.isa.function_alignment().minimum.into()) |
380 | | - .max(self.isa.symbol_alignment()); |
381 | | - let section = if self.per_function_section { |
382 | | - // FIXME pass empty symbol name once add_subsection produces `.text` as section name |
383 | | - // instead of `.text.` when passed an empty symbol name. (object#748) Until then pass |
384 | | - // `subsection` to produce `.text.subsection` as section name to reduce confusion. |
385 | | - self.object |
386 | | - .add_subsection(StandardSection::Text, b"subsection") |
387 | | - } else { |
388 | | - self.object.section_id(StandardSection::Text) |
389 | | - }; |
390 | | - let offset = self.object.add_symbol_data(symbol, section, bytes, align); |
391 | | - |
392 | | - if !relocs.is_empty() { |
393 | | - let relocs = relocs |
394 | | - .iter() |
395 | | - .map(|record| { |
396 | | - self.process_reloc(&ModuleReloc::from_mach_reloc(&record, func, func_id)) |
397 | | - }) |
398 | | - .collect(); |
399 | | - self.relocs.push(SymbolRelocs { |
400 | | - section, |
401 | | - offset, |
402 | | - relocs, |
403 | | - }); |
404 | | - } |
405 | | - |
406 | | - Ok(()) |
| 366 | + let relocs = relocs |
| 367 | + .iter() |
| 368 | + .map(|reloc| self.process_reloc(reloc)) |
| 369 | + .collect(); |
| 370 | + self.define_function_inner(func_id, alignment, bytes, relocs) |
407 | 371 | } |
408 | 372 |
|
409 | 373 | fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> { |
@@ -511,6 +475,51 @@ impl Module for ObjectModule { |
511 | 475 | } |
512 | 476 |
|
513 | 477 | impl ObjectModule { |
| 478 | + fn define_function_inner( |
| 479 | + &mut self, |
| 480 | + func_id: FuncId, |
| 481 | + alignment: u64, |
| 482 | + bytes: &[u8], |
| 483 | + relocs: Vec<ObjectRelocRecord>, |
| 484 | + ) -> Result<(), ModuleError> { |
| 485 | + info!("defining function {} with bytes", func_id); |
| 486 | + let decl = self.declarations.get_function_decl(func_id); |
| 487 | + let decl_name = decl.linkage_name(func_id); |
| 488 | + if !decl.linkage.is_definable() { |
| 489 | + return Err(ModuleError::InvalidImportDefinition(decl_name.into_owned())); |
| 490 | + } |
| 491 | + |
| 492 | + let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap(); |
| 493 | + if *defined { |
| 494 | + return Err(ModuleError::DuplicateDefinition(decl_name.into_owned())); |
| 495 | + } |
| 496 | + *defined = true; |
| 497 | + |
| 498 | + let align = alignment |
| 499 | + .max(self.isa.function_alignment().minimum.into()) |
| 500 | + .max(self.isa.symbol_alignment()); |
| 501 | + let section = if self.per_function_section { |
| 502 | + // FIXME pass empty symbol name once add_subsection produces `.text` as section name |
| 503 | + // instead of `.text.` when passed an empty symbol name. (object#748) Until then pass |
| 504 | + // `subsection` to produce `.text.subsection` as section name to reduce confusion. |
| 505 | + self.object |
| 506 | + .add_subsection(StandardSection::Text, b"subsection") |
| 507 | + } else { |
| 508 | + self.object.section_id(StandardSection::Text) |
| 509 | + }; |
| 510 | + let offset = self.object.add_symbol_data(symbol, section, bytes, align); |
| 511 | + |
| 512 | + if !relocs.is_empty() { |
| 513 | + self.relocs.push(SymbolRelocs { |
| 514 | + section, |
| 515 | + offset, |
| 516 | + relocs, |
| 517 | + }); |
| 518 | + } |
| 519 | + |
| 520 | + Ok(()) |
| 521 | + } |
| 522 | + |
514 | 523 | /// Finalize all relocations and output an object. |
515 | 524 | pub fn finish(mut self) -> ObjectProduct { |
516 | 525 | let symbol_relocs = mem::take(&mut self.relocs); |
|
0 commit comments