Skip to content

Commit cd6a5d3

Browse files
committed
Find the .text segment when it isn't first in the binary
Currently, LD assumes that the first PT_LOAD segment in the binary is the .text. This used to be the case in older compilers (and is usually the case), but the latest nightly version of rust actually puts a RO segment before the .text segment, containing various misc metadata. This patch properly changes the method of finding the .text by looking for PT_LOAD segments that are executable.
1 parent 1eb9ced commit cd6a5d3

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

unwind/src/find_cfi/ld.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct Phdr64 {
4040

4141
const PT_GNU_EH_FRAME: u32 = 0x6474e550;
4242
const PT_LOAD: u32 = 1;
43+
const PF_X: u32 = 1;
4344

4445
type PhdrCb = extern "C" fn(info: *const DlPhdrInfo, size: usize, data: *mut c_void) -> c_int;
4546
extern "C" {
@@ -56,7 +57,7 @@ extern "C" fn callback(info: *const DlPhdrInfo, size: usize, data: *mut c_void)
5657

5758
let phdr = slice::from_raw_parts((*info).phdr, (*info).phnum as usize);
5859

59-
if let Some(text) = phdr.iter().filter(|x| x.type_ == PT_LOAD).next() {
60+
if let Some(text) = phdr.iter().filter(|x| x.type_ == PT_LOAD && x.flags & PF_X != 0).next() {
6061
if let Some(eh_frame) = phdr.iter().filter(|x| x.type_ == PT_GNU_EH_FRAME).next() {
6162
let start_addr = (*info).addr + text.vaddr;
6263
let cfi_start = (*info).addr + eh_frame.vaddr;

0 commit comments

Comments
 (0)