debug: Support big-endian architectures

This fixes some hard-coded assumptions in the debug crate that
the native ELF files being accessed are little-endian; specifically
in create_gdbjit_image as well as in emit_dwarf.

In addition, data in WebAssembly memory always uses little-endian
byte order.  Therefore, if the native architecture is big-endian,
all references to base types need to be marked as little-endian
using the DW_AT_endianity attribute, so that the debugger will
be able to correctly access them.
This commit is contained in:
Ulrich Weigand
2021-04-21 14:14:59 +02:00
parent 1243cea455
commit 801358333d
4 changed files with 79 additions and 39 deletions

View File

@@ -2,6 +2,7 @@ pub use crate::transform::transform_dwarf;
use gimli::write::{Address, Dwarf, EndianVec, FrameTable, Result, Sections, Writer};
use gimli::{RunTimeEndian, SectionId};
use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::ir::Endianness;
use wasmtime_environ::isa::{unwind::UnwindInfo, TargetIsa};
use wasmtime_environ::{CompiledFunctions, DebugInfoData, ModuleMemoryOffset};
@@ -26,10 +27,19 @@ pub struct DwarfSection {
}
fn emit_dwarf_sections(
isa: &dyn TargetIsa,
mut dwarf: Dwarf,
frames: Option<FrameTable>,
) -> anyhow::Result<Vec<DwarfSection>> {
let mut sections = Sections::new(WriterRelocate::default());
let endian = match isa.endianness() {
Endianness::Little => RunTimeEndian::Little,
Endianness::Big => RunTimeEndian::Big,
};
let writer = WriterRelocate {
relocs: Vec::new(),
writer: EndianVec::new(endian),
};
let mut sections = Sections::new(writer);
dwarf.write(&mut sections)?;
if let Some(frames) = frames {
frames.write_debug_frame(&mut sections.debug_frame)?;
@@ -54,15 +64,6 @@ pub struct WriterRelocate {
writer: EndianVec<RunTimeEndian>,
}
impl Default for WriterRelocate {
fn default() -> Self {
WriterRelocate {
relocs: Vec::new(),
writer: EndianVec::new(RunTimeEndian::Little),
}
}
}
impl Writer for WriterRelocate {
type Endian = RunTimeEndian;
@@ -156,6 +157,6 @@ pub fn emit_dwarf<'a>(
) -> anyhow::Result<Vec<DwarfSection>> {
let dwarf = transform_dwarf(isa, debuginfo_data, funcs, memory_offset)?;
let frame_table = create_frame_table(isa, funcs);
let sections = emit_dwarf_sections(dwarf, frame_table)?;
let sections = emit_dwarf_sections(isa, dwarf, frame_table)?;
Ok(sections)
}