Skip to content

Commit eb69f2b

Browse files
fix: More robust code to get line numbers from debug info (#1923)
Also fixed 64 bit relocation sizes for riscv64 and loongarch64, which are used in debug info.
1 parent 3dbac6b commit eb69f2b

4 files changed

Lines changed: 55 additions & 16 deletions

File tree

libwild/src/dwarf_address_info.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::platform::RelocationSequence as _;
1212
use crate::platform::SourceInfo;
1313
use crate::platform::SourceInfoDetails;
1414
use anyhow::Context;
15+
use linker_utils::elf::RelocationKind;
1516
use object::LittleEndian;
1617
use object::read::elf::Crel;
1718
use object::read::elf::RelocationSections;
@@ -144,30 +145,39 @@ fn apply_section_relocations<A: Arch<Platform = crate::elf::Elf>, R: Relocation>
144145
.get(LittleEndian)
145146
.wrapping_add(rel.addend() as u64);
146147

147-
let section_index = object
148-
.symbol_section(symbol, sym_index)?
149-
.context("Relocation for undefined symbol")?;
148+
let Some(section_index) = object.symbol_section(symbol, sym_index)? else {
149+
// Ignore undefined symbols.
150+
continue;
151+
};
150152
let symbol_section = object.section(section_index)?;
151153

152154
let data_offset = rel.offset() as usize;
153155

154-
if symbol_section.sh_offset.get(LittleEndian)
155-
== section_of_interest.sh_offset.get(LittleEndian)
156-
{
157-
value += SECTION_LOAD_ADDRESS;
158-
}
159-
160156
let r_type = A::relocation_from_raw(rel.raw_type())?;
161157

162158
let linker_utils::elf::RelocationSize::ByteSize(num_bytes) = r_type.size else {
163159
continue;
164160
};
165161

166-
if r_type.kind == linker_utils::elf::RelocationKind::Absolute {
167-
section_data
168-
.get_mut(data_offset..data_offset + num_bytes)
169-
.context("Invalid relocation offset")?
170-
.copy_from_slice(&value.to_le_bytes()[..num_bytes]);
162+
let rel_out = section_data
163+
.get_mut(data_offset..data_offset + num_bytes)
164+
.context("Invalid relocation offset")?;
165+
166+
match r_type.kind {
167+
RelocationKind::Absolute => {
168+
let in_section_of_interest = symbol_section.sh_offset.get(LittleEndian)
169+
== section_of_interest.sh_offset.get(LittleEndian);
170+
171+
if in_section_of_interest {
172+
value += SECTION_LOAD_ADDRESS;
173+
}
174+
175+
r_type.write_to_buffer(value, rel_out)?;
176+
}
177+
RelocationKind::AbsoluteAddition | RelocationKind::AbsoluteSubtraction => {
178+
r_type.write_to_buffer(value, rel_out)?;
179+
}
180+
_ => {}
171181
}
172182
}
173183
Ok(())

linker-utils/src/loongarch64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub const fn relocation_type_from_raw(r_type: u32) -> Option<RelocationKindInfo>
6969
),
7070
object::elf::R_LARCH_64 => (
7171
RelocationKind::Absolute,
72-
RelocationSize::ByteSize(4),
72+
RelocationSize::ByteSize(8),
7373
None,
7474
AllowedRange::no_check(),
7575
1,

linker-utils/src/riscv64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ pub const fn relocation_type_from_raw(r_type: u32) -> Option<RelocationKindInfo>
145145
),
146146
object::elf::R_RISCV_64 => (
147147
RelocationKind::Absolute,
148-
RelocationSize::ByteSize(4),
148+
RelocationSize::ByteSize(8),
149149
None,
150150
AllowedRange::no_check(),
151151
1,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Tests that we're able to report the line number of an undefined symbol
2+
// reference using debug info.
3+
4+
//#AbstractConfig:default
5+
//#Object:runtime.c
6+
//#ExpectError:source-info-from-debug.*27
7+
8+
//#Config:non-lto:default
9+
//#CompArgs:-g
10+
// GNU ld reports incorrect line numbers.
11+
//#SkipLinker:ld
12+
13+
//#Config:lto:default
14+
//#RequiresLinkerPlugin:true
15+
//#LinkerDriver:gcc
16+
//#CompArgs:-g -flto -fPIC
17+
//#LinkArgs:-flto -nostdlib -fPIC
18+
// GNU ld tries to generate a PLT, then errors
19+
//#SkipLinker:ld
20+
21+
#include "../common/runtime.h"
22+
23+
void foo(void);
24+
25+
void _start(void) {
26+
runtime_init();
27+
foo();
28+
exit_syscall(42);
29+
}

0 commit comments

Comments
 (0)