#![allow(dead_code)]
use core::ffi::{c_char, c_int, c_uint, c_void};
pub(crate) type Status = c_int;
pub(crate) const STATUS_OK: Status = 0;
pub(crate) const STATUS_NO_SYMS: Status = 1;
pub(crate) const STATUS_BAD_HANDLE: Status = 2;
pub(crate) const STATUS_ERR: Status = 3;
pub(crate) const API_VERSION: c_int = 1;
pub(crate) const GNU_LD_VERSION: c_int = 244;
pub(crate) const LINKER_API_V0: c_int = 0;
pub(crate) const LINKER_API_V1: c_int = 1;
pub(crate) mod tag {
use core::ffi::c_int;
pub(crate) const NULL: c_int = 0;
pub(crate) const API_VERSION: c_int = 1;
pub(crate) const GOLD_VERSION: c_int = 2;
pub(crate) const LINKER_OUTPUT: c_int = 3;
pub(crate) const OPTION: c_int = 4;
pub(crate) const REGISTER_CLAIM_FILE_HOOK: c_int = 5;
pub(crate) const REGISTER_ALL_SYMBOLS_READ_HOOK: c_int = 6;
pub(crate) const REGISTER_CLEANUP_HOOK: c_int = 7;
pub(crate) const ADD_SYMBOLS: c_int = 8;
pub(crate) const GET_SYMBOLS: c_int = 9;
pub(crate) const ADD_INPUT_FILE: c_int = 10;
pub(crate) const MESSAGE: c_int = 11;
pub(crate) const GET_INPUT_FILE: c_int = 12;
pub(crate) const RELEASE_INPUT_FILE: c_int = 13;
pub(crate) const ADD_INPUT_LIBRARY: c_int = 14;
pub(crate) const OUTPUT_NAME: c_int = 15;
pub(crate) const SET_EXTRA_LIBRARY_PATH: c_int = 16;
pub(crate) const GNU_LD_VERSION: c_int = 17;
pub(crate) const GET_VIEW: c_int = 18;
pub(crate) const GET_INPUT_SECTION_COUNT: c_int = 19;
pub(crate) const GET_INPUT_SECTION_TYPE: c_int = 20;
pub(crate) const GET_INPUT_SECTION_NAME: c_int = 21;
pub(crate) const GET_INPUT_SECTION_CONTENTS: c_int = 22;
pub(crate) const UPDATE_SECTION_ORDER: c_int = 23;
pub(crate) const ALLOW_SECTION_ORDERING: c_int = 24;
pub(crate) const GET_SYMBOLS_V2: c_int = 25;
pub(crate) const ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS: c_int = 26;
pub(crate) const UNIQUE_SEGMENT_FOR_SECTIONS: c_int = 27;
pub(crate) const GET_SYMBOLS_V3: c_int = 28;
pub(crate) const GET_INPUT_SECTION_ALIGNMENT: c_int = 29;
pub(crate) const GET_INPUT_SECTION_SIZE: c_int = 30;
pub(crate) const REGISTER_NEW_INPUT_HOOK: c_int = 31;
pub(crate) const GET_WRAP_SYMBOLS: c_int = 32;
pub(crate) const ADD_SYMBOLS_V2: c_int = 33;
pub(crate) const GET_API_VERSION: c_int = 34;
pub(crate) const REGISTER_CLAIM_FILE_HOOK_V2: c_int = 35;
}
pub(crate) type OffT = i64;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct RawInputFile {
pub(crate) name: *const c_char,
pub(crate) fd: c_int,
pub(crate) offset: OffT,
pub(crate) filesize: OffT,
pub(crate) handle: *mut c_void,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct RawSymbol {
pub(crate) name: *mut c_char,
pub(crate) version: *mut c_char,
#[cfg(target_endian = "little")]
pub(crate) def: u8,
#[cfg(target_endian = "little")]
pub(crate) symbol_type: u8,
#[cfg(target_endian = "little")]
pub(crate) section_kind: u8,
#[cfg(target_endian = "little")]
pub(crate) unused: u8,
#[cfg(target_endian = "big")]
pub(crate) unused: u8,
#[cfg(target_endian = "big")]
pub(crate) section_kind: u8,
#[cfg(target_endian = "big")]
pub(crate) symbol_type: u8,
#[cfg(target_endian = "big")]
pub(crate) def: u8,
pub(crate) visibility: c_int,
pub(crate) size: u64,
pub(crate) comdat_key: *mut c_char,
pub(crate) resolution: c_int,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub(crate) struct RawSection {
pub(crate) handle: *const c_void,
pub(crate) shndx: c_uint,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub(crate) union TvValue {
pub(crate) val: c_int,
pub(crate) string: *const c_char,
pub(crate) function: *const c_void,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub(crate) struct Tv {
pub(crate) tag: c_int,
pub(crate) value: TvValue,
}
pub(crate) type OnloadFn = unsafe extern "C" fn(tv: *mut Tv) -> Status;
pub(crate) type ClaimFileFn =
unsafe extern "C" fn(file: *const RawInputFile, claimed: *mut c_int) -> Status;
pub(crate) type ClaimFileV2Fn = unsafe extern "C" fn(
file: *const RawInputFile,
claimed: *mut c_int,
known_used: c_int,
) -> Status;
pub(crate) type VoidHandlerFn = unsafe extern "C" fn() -> Status;
pub(crate) type NewInputFn = unsafe extern "C" fn(file: *const RawInputFile) -> Status;
#[cfg(test)]
mod tests {
use super::*;
use core::mem::{align_of, offset_of, size_of};
#[test]
#[cfg(target_pointer_width = "64")]
fn layouts_match_the_lp64_abi() {
assert_eq!(size_of::<RawInputFile>(), 40);
assert_eq!(offset_of!(RawInputFile, fd), 8);
assert_eq!(offset_of!(RawInputFile, offset), 16);
assert_eq!(offset_of!(RawInputFile, filesize), 24);
assert_eq!(offset_of!(RawInputFile, handle), 32);
assert_eq!(size_of::<RawSymbol>(), 48);
assert_eq!(offset_of!(RawSymbol, version), 8);
assert_eq!(offset_of!(RawSymbol, visibility), 20);
assert_eq!(offset_of!(RawSymbol, size), 24);
assert_eq!(offset_of!(RawSymbol, comdat_key), 32);
assert_eq!(offset_of!(RawSymbol, resolution), 40);
assert_eq!(size_of::<RawSection>(), 16);
assert_eq!(size_of::<Tv>(), 16);
assert_eq!(align_of::<Tv>(), 8);
assert_eq!(offset_of!(Tv, value), 8);
}
#[test]
#[cfg(target_endian = "little")]
fn def_byte_overlays_the_old_int_field() {
assert_eq!(offset_of!(RawSymbol, def), 16);
assert_eq!(offset_of!(RawSymbol, symbol_type), 17);
assert_eq!(offset_of!(RawSymbol, section_kind), 18);
}
}