Skip to content

Commit

Permalink
Fix debuginfo for machO
Browse files Browse the repository at this point in the history
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 rust-lang#303
  • Loading branch information
bjorn3 committed Oct 19, 2019
1 parent 75c24b9 commit dda5ea8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
25 changes: 20 additions & 5 deletions src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::convert::TryFrom;

use rustc::session::Session;

Expand Down Expand Up @@ -122,8 +123,13 @@ impl WriteDebugInfo for ObjectProduct {
id: SectionId,
data: Vec<u8>,
) -> (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);
Expand All @@ -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 {
Expand All @@ -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();
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit dda5ea8

Please sign in to comment.