From dda5ea883a2191b16e08ba1a455a5776acbe57d0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 19 Oct 2019 15:37:07 +0200 Subject: [PATCH] Fix debuginfo for machO This only fixes it when using object::write as backend, and not when using faerie. There were two problems: * object::write doesn't replace .debug_info with __debug_info, unlike faerie * machO requires section relative relocations, and not symbol relative relocations. When using symbol relative relocations, the linker interprets the relocations as section relative. Thus writing the wrong values to the debug sections. Fixes #303 --- src/backend.rs | 25 ++++++++++++++++++++----- src/driver.rs | 5 +---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index ccb95624bad..3ed6e08f497 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::convert::TryFrom; use rustc::session::Session; @@ -122,8 +123,13 @@ impl WriteDebugInfo for ObjectProduct { id: SectionId, data: Vec, ) -> (object::write::SectionId, object::write::SymbolId) { + let name = if self.object.format() == target_lexicon::BinaryFormat::Macho { + id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info + } else { + id.name().to_string() + }.into_bytes(); + let segment = self.object.segment_name(StandardSegment::Debug).to_vec(); - let name = id.name().as_bytes().to_vec(); let section_id = self.object.add_section(segment, name, SectionKind::Debug); self.object.section_mut(section_id).set_data(data, 1); let symbol_id = self.object.section_symbol(section_id); @@ -137,10 +143,19 @@ impl WriteDebugInfo for ObjectProduct { from: &Self::SectionId, reloc: &DebugReloc, ) { - let symbol = match reloc.name { - DebugRelocName::Section(id) => section_map.get(&id).unwrap().1, + let (symbol, symbol_offset) = match reloc.name { + DebugRelocName::Section(id) => { + (section_map.get(&id).unwrap().1, 0) + } DebugRelocName::Symbol(id) => { - self.function_symbol(*symbol_map.get_index(id).unwrap().0) + let symbol_id = self.function_symbol(*symbol_map.get_index(id).unwrap().0); + let symbol = self.object.symbol(symbol_id); + + // A symbol gets a section assigned when `add_symbol_data` is called. + let section = symbol.section.expect("Symbol not defined"); + let symbol_offset = symbol.value; + + (self.object.section_symbol(section), symbol_offset) } }; self.object.add_relocation(from.0, Relocation { @@ -149,7 +164,7 @@ impl WriteDebugInfo for ObjectProduct { kind: RelocationKind::Absolute, encoding: RelocationEncoding::Generic, size: reloc.size * 8, - addend: reloc.addend, + addend: i64::try_from(symbol_offset).unwrap() + reloc.addend, }).unwrap(); } } diff --git a/src/driver.rs b/src/driver.rs index 215ae071c3f..22271460b02 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -184,10 +184,7 @@ fn run_aot( let mut module = new_module("some_file".to_string()); - let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None - // macOS debuginfo doesn't work yet (see #303) - && !tcx.sess.target.target.options.is_like_osx - { + let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None { let debug = DebugContext::new( tcx, module.target_config().pointer_type().bytes() as u8,