about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2024-03-27 15:00:41 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2024-03-27 15:01:25 +0000
commitf086e7abaf2fc954a2801231bfe3aa4508b8f424 (patch)
treee3b7ca977fcb7e7d60f473eaf238761fb40b263c
parent1f75f0fcad63b577ed38d5cf10b62c5af47a3269 (diff)
downloadrust-f086e7abaf2fc954a2801231bfe3aa4508b8f424.tar.gz
rust-f086e7abaf2fc954a2801231bfe3aa4508b8f424.zip
Allow debuginfo to reference global variables
-rw-r--r--src/debuginfo/emit.rs15
-rw-r--r--src/debuginfo/line_info.rs18
-rw-r--r--src/debuginfo/mod.rs19
-rw-r--r--src/debuginfo/object.rs13
-rw-r--r--src/debuginfo/unwind.rs10
5 files changed, 39 insertions, 36 deletions
diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs
index 81b819a5546..d376766966d 100644
--- a/src/debuginfo/emit.rs
+++ b/src/debuginfo/emit.rs
@@ -1,5 +1,6 @@
 //! Write the debuginfo into an object file.
 
+use cranelift_module::{DataId, FuncId};
 use cranelift_object::ObjectProduct;
 use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
 use gimli::{RunTimeEndian, SectionId};
@@ -8,6 +9,19 @@ use rustc_data_structures::fx::FxHashMap;
 use super::object::WriteDebugInfo;
 use super::DebugContext;
 
+pub(super) fn address_for_func(func_id: FuncId) -> Address {
+    let symbol = func_id.as_u32();
+    assert!(symbol & 1 << 31 == 0);
+    Address::Symbol { symbol: symbol as usize, addend: 0 }
+}
+
+#[allow(dead_code)]
+pub(super) fn address_for_data(data_id: DataId) -> Address {
+    let symbol = data_id.as_u32();
+    assert!(symbol & 1 << 31 == 0);
+    Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 }
+}
+
 impl DebugContext {
     pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
         let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
@@ -171,6 +185,7 @@ impl Writer for WriterRelocate {
                 gimli::DW_EH_PE_pcrel => {
                     let size = match eh_pe.format() {
                         gimli::DW_EH_PE_sdata4 => 4,
+                        gimli::DW_EH_PE_sdata8 => 8,
                         _ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
                     };
                     self.relocs.push(DebugReloc {
diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs
index 916abf31869..380eba437c2 100644
--- a/src/debuginfo/line_info.rs
+++ b/src/debuginfo/line_info.rs
@@ -5,13 +5,12 @@ use std::path::{Component, Path};
 
 use cranelift_codegen::binemit::CodeOffset;
 use cranelift_codegen::MachSrcLoc;
-use gimli::write::{
-    Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
-};
+use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
 use rustc_span::{
     FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
 };
 
+use crate::debuginfo::emit::address_for_func;
 use crate::debuginfo::FunctionDebugContext;
 use crate::prelude::*;
 
@@ -143,7 +142,7 @@ impl FunctionDebugContext {
     pub(super) fn create_debug_lines(
         &mut self,
         debug_context: &mut DebugContext,
-        symbol: usize,
+        func_id: FuncId,
         context: &Context,
     ) -> CodeOffset {
         let create_row_for_span =
@@ -156,11 +155,7 @@ impl FunctionDebugContext {
                 debug_context.dwarf.unit.line_program.generate_row();
             };
 
-        debug_context
-            .dwarf
-            .unit
-            .line_program
-            .begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
+        debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id)));
 
         let mut func_end = 0;
 
@@ -183,10 +178,7 @@ impl FunctionDebugContext {
         assert_ne!(func_end, 0);
 
         let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
-        entry.set(
-            gimli::DW_AT_low_pc,
-            AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
-        );
+        entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
         entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
 
         func_end
diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs
index 172e72c0e26..3bf75e989c5 100644
--- a/src/debuginfo/mod.rs
+++ b/src/debuginfo/mod.rs
@@ -20,6 +20,7 @@ use rustc_span::{SourceFileHash, StableSourceFileId};
 
 pub(crate) use self::emit::{DebugReloc, DebugRelocName};
 pub(crate) use self::unwind::UnwindContext;
+use crate::debuginfo::emit::address_for_func;
 use crate::prelude::*;
 
 pub(crate) fn producer(sess: &Session) -> String {
@@ -174,7 +175,6 @@ impl DebugContext {
     ) -> FunctionDebugContext {
         let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span);
 
-        // FIXME: add to appropriate scope instead of root
         let scope = self.item_namespace(tcx, tcx.parent(instance.def_id()));
 
         let mut name = String::new();
@@ -240,21 +240,16 @@ impl FunctionDebugContext {
         func_id: FuncId,
         context: &Context,
     ) {
-        let symbol = func_id.as_u32() as usize;
+        let end = self.create_debug_lines(debug_context, func_id, context);
 
-        let end = self.create_debug_lines(debug_context, symbol, context);
-
-        debug_context.unit_range_list.0.push(Range::StartLength {
-            begin: Address::Symbol { symbol, addend: 0 },
-            length: u64::from(end),
-        });
+        debug_context
+            .unit_range_list
+            .0
+            .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) });
 
         let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
         // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
-        func_entry.set(
-            gimli::DW_AT_low_pc,
-            AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
-        );
+        func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
         // Using Udata for DW_AT_high_pc requires at least DWARF4
         func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
     }
diff --git a/src/debuginfo/object.rs b/src/debuginfo/object.rs
index f1840a7bf73..27eabd8a0a6 100644
--- a/src/debuginfo/object.rs
+++ b/src/debuginfo/object.rs
@@ -1,4 +1,4 @@
-use cranelift_module::FuncId;
+use cranelift_module::{DataId, FuncId};
 use cranelift_object::ObjectProduct;
 use gimli::SectionId;
 use object::write::{Relocation, StandardSegment};
@@ -57,10 +57,13 @@ impl WriteDebugInfo for ObjectProduct {
         let (symbol, symbol_offset) = match reloc.name {
             DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
             DebugRelocName::Symbol(id) => {
-                let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
-                self.object
-                    .symbol_section_and_offset(symbol_id)
-                    .expect("Debug reloc for undef sym???")
+                let id = id.try_into().unwrap();
+                let symbol_id = if id & 1 << 31 == 0 {
+                    self.function_symbol(FuncId::from_u32(id))
+                } else {
+                    self.data_symbol(DataId::from_u32(id & !(1 << 31)))
+                };
+                self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0))
             }
         };
         self.object
diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs
index 35278e6fb29..96ab7a29205 100644
--- a/src/debuginfo/unwind.rs
+++ b/src/debuginfo/unwind.rs
@@ -3,9 +3,10 @@
 use cranelift_codegen::ir::Endianness;
 use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
 use cranelift_object::ObjectProduct;
-use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
+use gimli::write::{CieId, EhFrame, FrameTable, Section};
 use gimli::RunTimeEndian;
 
+use super::emit::address_for_func;
 use super::object::WriteDebugInfo;
 use crate::prelude::*;
 
@@ -47,11 +48,8 @@ impl UnwindContext {
 
         match unwind_info {
             UnwindInfo::SystemV(unwind_info) => {
-                self.frame_table.add_fde(
-                    self.cie_id.unwrap(),
-                    unwind_info
-                        .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
-                );
+                self.frame_table
+                    .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id)));
             }
             UnwindInfo::WindowsX64(_) => {
                 // FIXME implement this