From 1c1af76ef604feed4dc0bdfeec8c8f2f1d57cbe9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 9 Sep 2023 17:35:34 -0700 Subject: [PATCH] Move the ELF bindings to linux-raw-sys. (#817) There are uses for the ELF bindings outside of this crate, so move them into the linux-raw-sys crate. --- Cargo.toml | 2 +- src/backend/linux_raw/elf.rs | 184 ----------------------- src/backend/linux_raw/mod.rs | 7 - src/backend/linux_raw/param/auxv.rs | 16 +- src/backend/linux_raw/param/init.rs | 15 +- src/backend/linux_raw/param/libc_auxv.rs | 2 +- src/backend/linux_raw/runtime/tls.rs | 2 +- src/backend/linux_raw/vdso.rs | 23 +-- 8 files changed, 18 insertions(+), 233 deletions(-) delete mode 100644 src/backend/linux_raw/elf.rs diff --git a/Cargo.toml b/Cargo.toml index bedcaaf2f..2128a7cba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ once_cell = { version = "1.5.2", optional = true } # libc backend can be selected via adding `--cfg=rustix_use_libc` to # `RUSTFLAGS` or enabling the `use-libc` cargo feature. [target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies] -linux-raw-sys = { version = "0.4.3", default-features = false, features = ["general", "errno", "ioctl", "no_std"] } +linux-raw-sys = { version = "0.4.7", default-features = false, features = ["general", "errno", "ioctl", "no_std", "elf"] } libc_errno = { package = "errno", version = "0.3.1", default-features = false, optional = true } libc = { version = "0.2.147", default-features = false, features = ["extra_traits"], optional = true } diff --git a/src/backend/linux_raw/elf.rs b/src/backend/linux_raw/elf.rs deleted file mode 100644 index 53223e170..000000000 --- a/src/backend/linux_raw/elf.rs +++ /dev/null @@ -1,184 +0,0 @@ -//! The ELF ABI. 🧝 - -#![allow(non_snake_case)] -#![cfg_attr( - all( - not(feature = "use-explicitly-provided-auxv"), - feature = "use-libc-auxv" - ), - allow(dead_code) -)] - -pub(super) const SELFMAG: usize = 4; -pub(super) const ELFMAG: [u8; SELFMAG] = [0x7f, b'E', b'L', b'F']; -pub(super) const EI_CLASS: usize = 4; -pub(super) const EI_DATA: usize = 5; -pub(super) const EI_VERSION: usize = 6; -pub(super) const EI_OSABI: usize = 7; -pub(super) const EI_ABIVERSION: usize = 8; -pub(super) const EV_CURRENT: u8 = 1; -#[cfg(target_pointer_width = "32")] -pub(super) const ELFCLASS: u8 = 1; // ELFCLASS32 -#[cfg(target_pointer_width = "64")] -pub(super) const ELFCLASS: u8 = 2; // ELFCLASS64 -#[cfg(target_endian = "little")] -pub(super) const ELFDATA: u8 = 1; // ELFDATA2LSB -#[cfg(target_endian = "big")] -pub(super) const ELFDATA: u8 = 2; // ELFDATA2MSB -pub(super) const ELFOSABI_SYSV: u8 = 0; -pub(super) const ELFOSABI_LINUX: u8 = 3; -// At present all of our supported platforms use 0. -pub(super) const ELFABIVERSION: u8 = 0; -pub(super) const ET_DYN: u16 = 3; -pub(super) const EI_NIDENT: usize = 16; -pub(super) const SHN_UNDEF: u16 = 0; -pub(super) const SHN_ABS: u16 = 0xfff1; -pub(super) const PN_XNUM: u16 = 0xffff; -pub(super) const PT_LOAD: u32 = 1; -pub(super) const PT_DYNAMIC: u32 = 2; -pub(super) const PT_INTERP: u32 = 3; -pub(super) const PT_PHDR: u32 = 6; -pub(super) const PT_TLS: u32 = 7; -pub(super) const PT_GNU_STACK: u32 = 0x6474_e551; -pub(super) const PT_GNU_RELRO: u32 = 0x6474_e552; -pub(super) const PF_X: u32 = 1; -pub(super) const PF_W: u32 = 2; -pub(super) const PF_R: u32 = 4; -pub(super) const DT_NULL: i32 = 0; -pub(super) const DT_HASH: i32 = 4; -pub(super) const DT_STRTAB: i32 = 5; -pub(super) const DT_SYMTAB: i32 = 6; -pub(super) const DT_SYMENT: i32 = 11; -pub(super) const DT_VERSYM: i32 = 0x6fff_fff0; -pub(super) const DT_VERDEF: i32 = 0x6fff_fffc; -pub(super) const STB_WEAK: u8 = 2; -pub(super) const STB_GLOBAL: u8 = 1; -pub(super) const STT_NOTYPE: u8 = 0; -pub(super) const STT_FUNC: u8 = 2; -pub(super) const STN_UNDEF: u32 = 0; -pub(super) const VER_FLG_BASE: u16 = 0x1; -pub(super) const VER_DEF_CURRENT: u16 = 1; -pub(super) const STV_DEFAULT: u8 = 0; -#[cfg(target_arch = "arm")] -pub(super) const EM_CURRENT: u16 = 40; // EM_ARM -#[cfg(target_arch = "x86")] -pub(super) const EM_CURRENT: u16 = 3; // EM_386 -#[cfg(target_arch = "powerpc64")] -pub(super) const EM_CURRENT: u16 = 21; // EM_PPC64 -#[cfg(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" -))] -pub(super) const EM_CURRENT: u16 = 8; // EM_MIPS -#[cfg(target_arch = "x86_64")] -pub(super) const EM_CURRENT: u16 = 62; // EM_X86_64 -#[cfg(target_arch = "aarch64")] -pub(super) const EM_CURRENT: u16 = 183; // EM_AARCH64 -#[cfg(target_arch = "riscv64")] -pub(super) const EM_CURRENT: u16 = 243; // EM_RISCV - -#[inline] -pub(super) const fn ELF_ST_VISIBILITY(o: u8) -> u8 { - o & 0x03 -} - -#[inline] -pub(super) const fn ELF_ST_BIND(val: u8) -> u8 { - val >> 4 -} - -#[inline] -pub(super) const fn ELF_ST_TYPE(val: u8) -> u8 { - val & 0xf -} - -#[repr(C)] -pub(super) struct Elf_Ehdr { - pub(super) e_ident: [u8; EI_NIDENT], - pub(super) e_type: u16, - pub(super) e_machine: u16, - pub(super) e_version: u32, - pub(super) e_entry: usize, - pub(super) e_phoff: usize, - pub(super) e_shoff: usize, - pub(super) e_flags: u32, - pub(super) e_ehsize: u16, - pub(super) e_phentsize: u16, - pub(super) e_phnum: u16, - pub(super) e_shentsize: u16, - pub(super) e_shnum: u16, - pub(super) e_shstrndx: u16, -} - -#[cfg(target_pointer_width = "32")] -#[repr(C)] -pub(super) struct Elf_Phdr { - pub(super) p_type: u32, - pub(super) p_offset: usize, - pub(super) p_vaddr: usize, - pub(super) p_paddr: usize, - pub(super) p_filesz: usize, - pub(super) p_memsz: usize, - pub(super) p_flags: u32, - pub(super) p_align: usize, -} - -#[cfg(target_pointer_width = "64")] -#[repr(C)] -pub(super) struct Elf_Phdr { - pub(super) p_type: u32, - pub(super) p_flags: u32, - pub(super) p_offset: usize, - pub(super) p_vaddr: usize, - pub(super) p_paddr: usize, - pub(super) p_filesz: usize, - pub(super) p_memsz: usize, - pub(super) p_align: usize, -} - -#[cfg(target_pointer_width = "32")] -#[repr(C)] -pub(super) struct Elf_Sym { - pub(super) st_name: u32, - pub(super) st_value: usize, - pub(super) st_size: usize, - pub(super) st_info: u8, - pub(super) st_other: u8, - pub(super) st_shndx: u16, -} - -#[cfg(target_pointer_width = "64")] -#[repr(C)] -pub(super) struct Elf_Sym { - pub(super) st_name: u32, - pub(super) st_info: u8, - pub(super) st_other: u8, - pub(super) st_shndx: u16, - pub(super) st_value: usize, - pub(super) st_size: usize, -} - -#[repr(C)] -pub(super) struct Elf_Dyn { - pub(super) d_tag: i32, - pub(super) d_val: usize, -} - -#[repr(C)] -pub(super) struct Elf_Verdef { - pub(super) vd_version: u16, - pub(super) vd_flags: u16, - pub(super) vd_ndx: u16, - pub(super) vd_cnt: u16, - pub(super) vd_hash: u32, - pub(super) vd_aux: u32, - pub(super) vd_next: u32, -} - -#[repr(C)] -pub(super) struct Elf_Verdaux { - pub(super) vda_name: u32, - pub(super) _vda_next: u32, -} diff --git a/src/backend/linux_raw/mod.rs b/src/backend/linux_raw/mod.rs index d682c57cd..9a07467f4 100644 --- a/src/backend/linux_raw/mod.rs +++ b/src/backend/linux_raw/mod.rs @@ -17,13 +17,6 @@ #[macro_use] mod arch; mod conv; -#[cfg(any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86" -))] -mod elf; mod reg; #[cfg(any(feature = "time", target_arch = "x86"))] mod vdso; diff --git a/src/backend/linux_raw/param/auxv.rs b/src/backend/linux_raw/param/auxv.rs index fefdbf438..8b0423ae4 100644 --- a/src/backend/linux_raw/param/auxv.rs +++ b/src/backend/linux_raw/param/auxv.rs @@ -6,7 +6,6 @@ #![allow(unsafe_code)] use crate::backend::c; -use crate::backend::elf::*; use crate::fd::OwnedFd; #[cfg(feature = "param")] use crate::ffi::CStr; @@ -14,11 +13,11 @@ use crate::fs::{Mode, OFlags}; use crate::utils::{as_ptr, check_raw_pointer}; #[cfg(feature = "alloc")] use alloc::vec::Vec; -use core::ffi::c_void; use core::mem::size_of; use core::ptr::{null_mut, read_unaligned, NonNull}; use core::sync::atomic::Ordering::Relaxed; use core::sync::atomic::{AtomicPtr, AtomicUsize}; +use linux_raw_sys::elf::*; use linux_raw_sys::general::{ AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; @@ -382,19 +381,6 @@ unsafe fn check_elf_base(base: *const Elf_Ehdr) -> Option> { Some(NonNull::new_unchecked(as_ptr(hdr) as *mut _)) } -// ELF ABI - -#[repr(C)] -#[derive(Copy, Clone)] -struct Elf_auxv_t { - a_type: usize, - - // Some of the values in the auxv array are pointers, so we make `a_val` a - // pointer, in order to preserve their provenance. For the values which are - // integers, we cast this to `usize`. - a_val: *const c_void, -} - // Aux reading utilities // Read auxv records from an array in memory. diff --git a/src/backend/linux_raw/param/init.rs b/src/backend/linux_raw/param/init.rs index bf8888750..46aae009a 100644 --- a/src/backend/linux_raw/param/init.rs +++ b/src/backend/linux_raw/param/init.rs @@ -6,12 +6,12 @@ #![allow(unsafe_code)] use crate::backend::c; -use crate::backend::elf::*; #[cfg(feature = "param")] use crate::ffi::CStr; use core::ffi::c_void; use core::ptr::{null_mut, read, NonNull}; use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; +use linux_raw_sys::elf::*; use linux_raw_sys::general::{ AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; @@ -147,16 +147,3 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { auxp = auxp.add(1); } } - -// ELF ABI - -#[repr(C)] -#[derive(Copy, Clone)] -struct Elf_auxv_t { - a_type: usize, - - // Some of the values in the auxv array are pointers, so we make `a_val` a - // pointer, in order to preserve their provenance. For the values which are - // integers, we cast this to `usize`. - a_val: *mut c_void, -} diff --git a/src/backend/linux_raw/param/libc_auxv.rs b/src/backend/linux_raw/param/libc_auxv.rs index 83429971a..0e6ca6ed5 100644 --- a/src/backend/linux_raw/param/libc_auxv.rs +++ b/src/backend/linux_raw/param/libc_auxv.rs @@ -6,11 +6,11 @@ #![allow(unsafe_code)] use crate::backend::c; -use crate::backend::elf::*; #[cfg(feature = "param")] use crate::ffi::CStr; #[cfg(not(feature = "runtime"))] use core::ptr::null; +use linux_raw_sys::elf::*; // `getauxval` wasn't supported in glibc until 2.16. Also this lets us use // `*mut` as the return type to preserve strict provenance. diff --git a/src/backend/linux_raw/runtime/tls.rs b/src/backend/linux_raw/runtime/tls.rs index 4a57a39a1..ad1634894 100644 --- a/src/backend/linux_raw/runtime/tls.rs +++ b/src/backend/linux_raw/runtime/tls.rs @@ -7,9 +7,9 @@ #![allow(unsafe_code)] use crate::backend::c; -use crate::backend::elf::*; use crate::backend::param::auxv::exe_phdrs; use core::ptr::{null, NonNull}; +use linux_raw_sys::elf::*; /// For use with [`set_thread_area`]. /// diff --git a/src/backend/linux_raw/vdso.rs b/src/backend/linux_raw/vdso.rs index 52e365a4e..2934293a0 100644 --- a/src/backend/linux_raw/vdso.rs +++ b/src/backend/linux_raw/vdso.rs @@ -13,12 +13,12 @@ #![allow(unsafe_code)] use super::c; -use super::elf::*; use crate::ffi::CStr; use crate::utils::check_raw_pointer; use core::ffi::c_void; use core::mem::size_of; use core::ptr::{null, null_mut}; +use linux_raw_sys::elf::*; pub(super) struct Vdso { // Load information @@ -143,28 +143,31 @@ fn init_from_sysinfo_ehdr() -> Option { match d.d_tag { DT_STRTAB => { vdso.symstrings = - check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + check_raw_pointer::(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? + .as_ptr(); } DT_SYMTAB => { vdso.symtab = - check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)? + check_raw_pointer::(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? .as_ptr(); } DT_HASH => { - hash = - check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + hash = check_raw_pointer::(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? + .as_ptr(); } DT_VERSYM => { vdso.versym = - check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + check_raw_pointer::(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? + .as_ptr(); } DT_VERDEF => { - vdso.verdef = - check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)? - .as_ptr(); + vdso.verdef = check_raw_pointer::( + vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _, + )? + .as_ptr(); } DT_SYMENT => { - if d.d_val != size_of::() { + if d.d_un.d_val != size_of::() as _ { return None; // Failed } }