Skip to content

Commit dda5ea8

Browse files
committed
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 rust-lang#303
1 parent 75c24b9 commit dda5ea8

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

src/backend.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::HashMap;
2+
use std::convert::TryFrom;
23

34
use rustc::session::Session;
45

@@ -122,8 +123,13 @@ impl WriteDebugInfo for ObjectProduct {
122123
id: SectionId,
123124
data: Vec<u8>,
124125
) -> (object::write::SectionId, object::write::SymbolId) {
126+
let name = if self.object.format() == target_lexicon::BinaryFormat::Macho {
127+
id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
128+
} else {
129+
id.name().to_string()
130+
}.into_bytes();
131+
125132
let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
126-
let name = id.name().as_bytes().to_vec();
127133
let section_id = self.object.add_section(segment, name, SectionKind::Debug);
128134
self.object.section_mut(section_id).set_data(data, 1);
129135
let symbol_id = self.object.section_symbol(section_id);
@@ -137,10 +143,19 @@ impl WriteDebugInfo for ObjectProduct {
137143
from: &Self::SectionId,
138144
reloc: &DebugReloc,
139145
) {
140-
let symbol = match reloc.name {
141-
DebugRelocName::Section(id) => section_map.get(&id).unwrap().1,
146+
let (symbol, symbol_offset) = match reloc.name {
147+
DebugRelocName::Section(id) => {
148+
(section_map.get(&id).unwrap().1, 0)
149+
}
142150
DebugRelocName::Symbol(id) => {
143-
self.function_symbol(*symbol_map.get_index(id).unwrap().0)
151+
let symbol_id = self.function_symbol(*symbol_map.get_index(id).unwrap().0);
152+
let symbol = self.object.symbol(symbol_id);
153+
154+
// A symbol gets a section assigned when `add_symbol_data` is called.
155+
let section = symbol.section.expect("Symbol not defined");
156+
let symbol_offset = symbol.value;
157+
158+
(self.object.section_symbol(section), symbol_offset)
144159
}
145160
};
146161
self.object.add_relocation(from.0, Relocation {
@@ -149,7 +164,7 @@ impl WriteDebugInfo for ObjectProduct {
149164
kind: RelocationKind::Absolute,
150165
encoding: RelocationEncoding::Generic,
151166
size: reloc.size * 8,
152-
addend: reloc.addend,
167+
addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
153168
}).unwrap();
154169
}
155170
}

src/driver.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,7 @@ fn run_aot(
184184

185185
let mut module = new_module("some_file".to_string());
186186

187-
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None
188-
// macOS debuginfo doesn't work yet (see #303)
189-
&& !tcx.sess.target.target.options.is_like_osx
190-
{
187+
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None {
191188
let debug = DebugContext::new(
192189
tcx,
193190
module.target_config().pointer_type().bytes() as u8,

0 commit comments

Comments
 (0)