2020-04-05 14:01:02 +02:00
|
|
|
use rustc_data_structures::fx::FxHashMap;
|
2019-10-18 17:19:13 +02:00
|
|
|
|
2020-10-01 10:38:23 +02:00
|
|
|
use cranelift_module::FuncId;
|
2021-08-20 21:43:53 +02:00
|
|
|
use cranelift_object::ObjectProduct;
|
2019-10-16 21:21:20 +02:00
|
|
|
|
2021-08-20 21:38:17 +02:00
|
|
|
use object::write::{Relocation, StandardSegment};
|
|
|
|
|
use object::{RelocationEncoding, SectionKind};
|
2019-10-19 10:56:35 +02:00
|
|
|
|
2019-10-16 21:21:20 +02:00
|
|
|
use gimli::SectionId;
|
|
|
|
|
|
|
|
|
|
use crate::debuginfo::{DebugReloc, DebugRelocName};
|
|
|
|
|
|
2021-08-20 21:43:53 +02:00
|
|
|
pub(super) trait WriteDebugInfo {
|
2020-04-25 18:23:31 +02:00
|
|
|
type SectionId: Copy;
|
2019-10-16 21:21:20 +02:00
|
|
|
|
|
|
|
|
fn add_debug_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
|
|
|
|
|
fn add_debug_reloc(
|
|
|
|
|
&mut self,
|
2020-04-05 14:01:02 +02:00
|
|
|
section_map: &FxHashMap<SectionId, Self::SectionId>,
|
2019-10-16 21:21:20 +02:00
|
|
|
from: &Self::SectionId,
|
|
|
|
|
reloc: &DebugReloc,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl WriteDebugInfo for ObjectProduct {
|
|
|
|
|
type SectionId = (object::write::SectionId, object::write::SymbolId);
|
|
|
|
|
|
|
|
|
|
fn add_debug_section(
|
|
|
|
|
&mut self,
|
|
|
|
|
id: SectionId,
|
|
|
|
|
data: Vec<u8>,
|
|
|
|
|
) -> (object::write::SectionId, object::write::SymbolId) {
|
2020-06-16 10:38:12 +02:00
|
|
|
let name = if self.object.format() == object::BinaryFormat::MachO {
|
2019-10-19 15:37:07 +02:00
|
|
|
id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
|
|
|
|
|
} else {
|
|
|
|
|
id.name().to_string()
|
2020-08-28 12:10:48 +02:00
|
|
|
}
|
|
|
|
|
.into_bytes();
|
2019-10-19 15:37:07 +02:00
|
|
|
|
2019-10-16 21:21:20 +02:00
|
|
|
let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
|
2020-09-23 10:00:09 +02:00
|
|
|
// FIXME use SHT_X86_64_UNWIND for .eh_frame
|
2020-10-01 10:38:23 +02:00
|
|
|
let section_id = self.object.add_section(
|
|
|
|
|
segment,
|
2020-10-28 21:46:08 +01:00
|
|
|
name,
|
2021-03-05 11:21:44 +01:00
|
|
|
if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
|
2020-10-01 10:38:23 +02:00
|
|
|
);
|
|
|
|
|
self.object
|
|
|
|
|
.section_mut(section_id)
|
|
|
|
|
.set_data(data, if id == SectionId::EhFrame { 8 } else { 1 });
|
2019-10-16 21:21:20 +02:00
|
|
|
let symbol_id = self.object.section_symbol(section_id);
|
|
|
|
|
(section_id, symbol_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn add_debug_reloc(
|
|
|
|
|
&mut self,
|
2020-04-05 14:01:02 +02:00
|
|
|
section_map: &FxHashMap<SectionId, Self::SectionId>,
|
2019-10-16 21:21:20 +02:00
|
|
|
from: &Self::SectionId,
|
|
|
|
|
reloc: &DebugReloc,
|
|
|
|
|
) {
|
2019-10-19 15:37:07 +02:00
|
|
|
let (symbol, symbol_offset) = match reloc.name {
|
2020-08-28 12:10:48 +02:00
|
|
|
DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
|
2019-10-16 21:21:20 +02:00
|
|
|
DebugRelocName::Symbol(id) => {
|
2020-05-01 19:21:29 +02:00
|
|
|
let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
|
2020-08-28 12:10:48 +02:00
|
|
|
self.object
|
|
|
|
|
.symbol_section_and_offset(symbol_id)
|
|
|
|
|
.expect("Debug reloc for undef sym???")
|
2019-10-16 21:21:20 +02:00
|
|
|
}
|
|
|
|
|
};
|
2020-08-28 12:10:48 +02:00
|
|
|
self.object
|
|
|
|
|
.add_relocation(
|
|
|
|
|
from.0,
|
|
|
|
|
Relocation {
|
|
|
|
|
offset: u64::from(reloc.offset),
|
|
|
|
|
symbol,
|
2020-09-23 10:00:09 +02:00
|
|
|
kind: reloc.kind,
|
2020-08-28 12:10:48 +02:00
|
|
|
encoding: RelocationEncoding::Generic,
|
|
|
|
|
size: reloc.size * 8,
|
|
|
|
|
addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2019-10-16 21:21:20 +02:00
|
|
|
}
|
|
|
|
|
}
|