mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #25819 from jacobly0/elfv2-emit-obj
This commit is contained in:
commit
f3309a96a7
@ -3971,7 +3971,7 @@ pub const dl_phdr_info = switch (native_os) {
|
||||
/// Module name.
|
||||
name: ?[*:0]const u8,
|
||||
/// Pointer to module's phdr.
|
||||
phdr: [*]std.elf.Phdr,
|
||||
phdr: [*]std.elf.ElfN.Phdr,
|
||||
/// Number of entries in phdr.
|
||||
phnum: u16,
|
||||
/// Total number of loads.
|
||||
@ -3984,7 +3984,7 @@ pub const dl_phdr_info = switch (native_os) {
|
||||
.illumos => extern struct {
|
||||
addr: std.elf.Addr,
|
||||
name: ?[*:0]const u8,
|
||||
phdr: [*]std.elf.Phdr,
|
||||
phdr: [*]std.elf.ElfN.Phdr,
|
||||
phnum: std.elf.Half,
|
||||
/// Incremented when a new object is mapped into the process.
|
||||
adds: u64,
|
||||
@ -3995,7 +3995,7 @@ pub const dl_phdr_info = switch (native_os) {
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .serenity => extern struct {
|
||||
addr: usize,
|
||||
name: ?[*:0]const u8,
|
||||
phdr: [*]std.elf.Phdr,
|
||||
phdr: [*]std.elf.ElfN.Phdr,
|
||||
phnum: std.elf.Half,
|
||||
},
|
||||
else => void,
|
||||
|
||||
@ -441,11 +441,11 @@ const DlIterContext = struct {
|
||||
|
||||
// Populate `build_id` and `gnu_eh_frame`
|
||||
for (info.phdr[0..info.phnum]) |phdr| {
|
||||
switch (phdr.p_type) {
|
||||
std.elf.PT_NOTE => {
|
||||
switch (phdr.type) {
|
||||
.NOTE => {
|
||||
// Look for .note.gnu.build-id
|
||||
const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.p_vaddr);
|
||||
var r: std.Io.Reader = .fixed(segment_ptr[0..phdr.p_memsz]);
|
||||
const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.vaddr);
|
||||
var r: std.Io.Reader = .fixed(segment_ptr[0..phdr.memsz]);
|
||||
const name_size = r.takeInt(u32, native_endian) catch continue;
|
||||
const desc_size = r.takeInt(u32, native_endian) catch continue;
|
||||
const note_type = r.takeInt(u32, native_endian) catch continue;
|
||||
@ -455,9 +455,9 @@ const DlIterContext = struct {
|
||||
const desc = r.take(desc_size) catch continue;
|
||||
build_id = desc;
|
||||
},
|
||||
std.elf.PT_GNU_EH_FRAME => {
|
||||
const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.p_vaddr);
|
||||
gnu_eh_frame = segment_ptr[0..phdr.p_memsz];
|
||||
std.elf.PT.GNU_EH_FRAME => {
|
||||
const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.vaddr);
|
||||
gnu_eh_frame = segment_ptr[0..phdr.memsz];
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -478,11 +478,11 @@ const DlIterContext = struct {
|
||||
});
|
||||
|
||||
for (info.phdr[0..info.phnum]) |phdr| {
|
||||
if (phdr.p_type != std.elf.PT_LOAD) continue;
|
||||
if (phdr.type != .LOAD) continue;
|
||||
try context.si.ranges.append(gpa, .{
|
||||
// Overflowing addition handles VSDOs having p_vaddr = 0xffffffffff700000
|
||||
.start = info.addr +% phdr.p_vaddr,
|
||||
.len = phdr.p_memsz,
|
||||
.start = info.addr +% phdr.vaddr,
|
||||
.len = phdr.memsz,
|
||||
.module_index = module_index,
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,8 +92,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn linkmap_iterator(phdrs: []const elf.Phdr) error{InvalidExe}!LinkMap.Iterator {
|
||||
_ = phdrs;
|
||||
pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator {
|
||||
const _DYNAMIC = get_DYNAMIC() orelse {
|
||||
// No PT_DYNAMIC means this is a statically-linked non-PIE program.
|
||||
return .{ .current = null };
|
||||
|
||||
328
lib/std/elf.zig
328
lib/std/elf.zig
@ -50,6 +50,7 @@ pub const AT_L2_CACHESIZE = 44;
|
||||
pub const AT_L2_CACHEGEOMETRY = 45;
|
||||
pub const AT_L3_CACHESIZE = 46;
|
||||
pub const AT_L3_CACHEGEOMETRY = 47;
|
||||
pub const AT_MINSIGSTKSZ = 51;
|
||||
|
||||
pub const DT_NULL = 0;
|
||||
pub const DT_NEEDED = 1;
|
||||
@ -286,105 +287,111 @@ pub const VER_FLG_BASE = 1;
|
||||
/// Weak version identifier
|
||||
pub const VER_FLG_WEAK = 2;
|
||||
|
||||
/// Program header table entry unused
|
||||
pub const PT_NULL = 0;
|
||||
/// Loadable program segment
|
||||
pub const PT_LOAD = 1;
|
||||
/// Dynamic linking information
|
||||
pub const PT_DYNAMIC = 2;
|
||||
/// Program interpreter
|
||||
pub const PT_INTERP = 3;
|
||||
/// Auxiliary information
|
||||
pub const PT_NOTE = 4;
|
||||
/// Reserved
|
||||
pub const PT_SHLIB = 5;
|
||||
/// Entry for header table itself
|
||||
pub const PT_PHDR = 6;
|
||||
/// Thread-local storage segment
|
||||
pub const PT_TLS = 7;
|
||||
/// Number of defined types
|
||||
pub const PT_NUM = 8;
|
||||
/// Start of OS-specific
|
||||
pub const PT_LOOS = 0x60000000;
|
||||
/// GCC .eh_frame_hdr segment
|
||||
pub const PT_GNU_EH_FRAME = 0x6474e550;
|
||||
/// Indicates stack executability
|
||||
pub const PT_GNU_STACK = 0x6474e551;
|
||||
/// Read-only after relocation
|
||||
pub const PT_GNU_RELRO = 0x6474e552;
|
||||
pub const PT_LOSUNW = 0x6ffffffa;
|
||||
/// Sun specific segment
|
||||
pub const PT_SUNWBSS = 0x6ffffffa;
|
||||
/// Stack segment
|
||||
pub const PT_SUNWSTACK = 0x6ffffffb;
|
||||
pub const PT_HISUNW = 0x6fffffff;
|
||||
/// End of OS-specific
|
||||
pub const PT_HIOS = 0x6fffffff;
|
||||
/// Start of processor-specific
|
||||
pub const PT_LOPROC = 0x70000000;
|
||||
/// End of processor-specific
|
||||
pub const PT_HIPROC = 0x7fffffff;
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.NULL)`
|
||||
pub const PT_NULL = @intFromEnum(std.elf.PT.NULL);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.LOAD)`
|
||||
pub const PT_LOAD = @intFromEnum(std.elf.PT.LOAD);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.DYNAMIC)`
|
||||
pub const PT_DYNAMIC = @intFromEnum(std.elf.PT.DYNAMIC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.INTERP)`
|
||||
pub const PT_INTERP = @intFromEnum(std.elf.PT.INTERP);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.NOTE)`
|
||||
pub const PT_NOTE = @intFromEnum(std.elf.PT.NOTE);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.SHLIB)`
|
||||
pub const PT_SHLIB = @intFromEnum(std.elf.PT.SHLIB);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.PHDR)`
|
||||
pub const PT_PHDR = @intFromEnum(std.elf.PT.PHDR);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.TLS)`
|
||||
pub const PT_TLS = @intFromEnum(std.elf.PT.TLS);
|
||||
/// Deprecated, use `std.elf.PT.NUM`.
|
||||
pub const PT_NUM = PT.NUM;
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.LOOS)`
|
||||
pub const PT_LOOS = @intFromEnum(std.elf.PT.LOOS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.GNU_EH_FRAME)`
|
||||
pub const PT_GNU_EH_FRAME = @intFromEnum(std.elf.PT.GNU_EH_FRAME);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.GNU_STACK)`
|
||||
pub const PT_GNU_STACK = @intFromEnum(std.elf.PT.GNU_STACK);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.GNU_RELRO)`
|
||||
pub const PT_GNU_RELRO = @intFromEnum(std.elf.PT.GNU_RELRO);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.LOSUNW)`
|
||||
pub const PT_LOSUNW = @intFromEnum(std.elf.PT.LOSUNW);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.SUNWBSS)`
|
||||
pub const PT_SUNWBSS = @intFromEnum(std.elf.PT.SUNWBSS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.SUNWSTACK)`
|
||||
pub const PT_SUNWSTACK = @intFromEnum(std.elf.PT.SUNWSTACK);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.HISUNW)`
|
||||
pub const PT_HISUNW = @intFromEnum(std.elf.PT.HISUNW);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.HIOS)`
|
||||
pub const PT_HIOS = @intFromEnum(std.elf.PT.HIOS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.LOPROC)`
|
||||
pub const PT_LOPROC = @intFromEnum(std.elf.PT.LOPROC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.PT.HIPROC)`
|
||||
pub const PT_HIPROC = @intFromEnum(std.elf.PT.HIPROC);
|
||||
|
||||
pub const PN_XNUM = 0xffff;
|
||||
|
||||
/// Section header table entry unused
|
||||
pub const SHT_NULL = 0;
|
||||
/// Program data
|
||||
pub const SHT_PROGBITS = 1;
|
||||
/// Symbol table
|
||||
pub const SHT_SYMTAB = 2;
|
||||
/// String table
|
||||
pub const SHT_STRTAB = 3;
|
||||
/// Relocation entries with addends
|
||||
pub const SHT_RELA = 4;
|
||||
/// Symbol hash table
|
||||
pub const SHT_HASH = 5;
|
||||
/// Dynamic linking information
|
||||
pub const SHT_DYNAMIC = 6;
|
||||
/// Notes
|
||||
pub const SHT_NOTE = 7;
|
||||
/// Program space with no data (bss)
|
||||
pub const SHT_NOBITS = 8;
|
||||
/// Relocation entries, no addends
|
||||
pub const SHT_REL = 9;
|
||||
/// Reserved
|
||||
pub const SHT_SHLIB = 10;
|
||||
/// Dynamic linker symbol table
|
||||
pub const SHT_DYNSYM = 11;
|
||||
/// Array of constructors
|
||||
pub const SHT_INIT_ARRAY = 14;
|
||||
/// Array of destructors
|
||||
pub const SHT_FINI_ARRAY = 15;
|
||||
/// Array of pre-constructors
|
||||
pub const SHT_PREINIT_ARRAY = 16;
|
||||
/// Section group
|
||||
pub const SHT_GROUP = 17;
|
||||
/// Extended section indices
|
||||
pub const SHT_SYMTAB_SHNDX = 18;
|
||||
/// Start of OS-specific
|
||||
pub const SHT_LOOS = 0x60000000;
|
||||
/// LLVM address-significance table
|
||||
pub const SHT_LLVM_ADDRSIG = 0x6fff4c03;
|
||||
/// GNU hash table
|
||||
pub const SHT_GNU_HASH = 0x6ffffff6;
|
||||
/// GNU version definition table
|
||||
pub const SHT_GNU_VERDEF = 0x6ffffffd;
|
||||
/// GNU needed versions table
|
||||
pub const SHT_GNU_VERNEED = 0x6ffffffe;
|
||||
/// GNU symbol version table
|
||||
pub const SHT_GNU_VERSYM = 0x6fffffff;
|
||||
/// End of OS-specific
|
||||
pub const SHT_HIOS = 0x6fffffff;
|
||||
/// Start of processor-specific
|
||||
pub const SHT_LOPROC = 0x70000000;
|
||||
/// Unwind information
|
||||
pub const SHT_X86_64_UNWIND = 0x70000001;
|
||||
/// End of processor-specific
|
||||
pub const SHT_HIPROC = 0x7fffffff;
|
||||
/// Start of application-specific
|
||||
pub const SHT_LOUSER = 0x80000000;
|
||||
/// End of application-specific
|
||||
pub const SHT_HIUSER = 0xffffffff;
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.NULL)`
|
||||
pub const SHT_NULL = @intFromEnum(std.elf.SHT.NULL);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.PROGBITS)`
|
||||
pub const SHT_PROGBITS = @intFromEnum(std.elf.SHT.PROGBITS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.SYMTAB)`
|
||||
pub const SHT_SYMTAB = @intFromEnum(std.elf.SHT.SYMTAB);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.STRTAB)`
|
||||
pub const SHT_STRTAB = @intFromEnum(std.elf.SHT.STRTAB);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.RELA)`
|
||||
pub const SHT_RELA = @intFromEnum(std.elf.SHT.RELA);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.HASH)`
|
||||
pub const SHT_HASH = @intFromEnum(std.elf.SHT.HASH);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.DYNAMIC)`
|
||||
pub const SHT_DYNAMIC = @intFromEnum(std.elf.SHT.DYNAMIC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.NOTE)`
|
||||
pub const SHT_NOTE = @intFromEnum(std.elf.SHT.NOTE);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.NOBITS)`
|
||||
pub const SHT_NOBITS = @intFromEnum(std.elf.SHT.NOBITS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.REL)`
|
||||
pub const SHT_REL = @intFromEnum(std.elf.SHT.REL);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.SHLIB)`
|
||||
pub const SHT_SHLIB = @intFromEnum(std.elf.SHT.SHLIB);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.DYNSYM)`
|
||||
pub const SHT_DYNSYM = @intFromEnum(std.elf.SHT.DYNSYM);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.INIT_ARRAY)`
|
||||
pub const SHT_INIT_ARRAY = @intFromEnum(std.elf.SHT.INIT_ARRAY);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.FINI_ARRAY)`
|
||||
pub const SHT_FINI_ARRAY = @intFromEnum(std.elf.SHT.FINI_ARRAY);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.PREINIT_ARRAY)`
|
||||
pub const SHT_PREINIT_ARRAY = @intFromEnum(std.elf.SHT.PREINIT_ARRAY);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.GROUP)`
|
||||
pub const SHT_GROUP = @intFromEnum(std.elf.SHT.GROUP);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.SYMTAB_SHNDX)`
|
||||
pub const SHT_SYMTAB_SHNDX = @intFromEnum(std.elf.SHT.SYMTAB_SHNDX);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.RELR)`
|
||||
pub const SHT_RELR = @intFromEnum(std.elf.SHT.RELR);
|
||||
/// Deprecated, use `std.elf.SHT.NUM`.
|
||||
pub const SHT_NUM = SHT.NUM;
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.LOOS)`
|
||||
pub const SHT_LOOS = @intFromEnum(std.elf.SHT.LOOS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.LLVM_ADDRSIG)`
|
||||
pub const SHT_LLVM_ADDRSIG = @intFromEnum(std.elf.SHT.LLVM_ADDRSIG);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.GNU_HASH)`
|
||||
pub const SHT_GNU_HASH = @intFromEnum(std.elf.SHT.GNU_HASH);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.GNU_VERDEF)`
|
||||
pub const SHT_GNU_VERDEF = @intFromEnum(std.elf.SHT.GNU_VERDEF);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.GNU_VERNEED)`
|
||||
pub const SHT_GNU_VERNEED = @intFromEnum(std.elf.SHT.GNU_VERNEED);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.GNU_VERSYM)`
|
||||
pub const SHT_GNU_VERSYM = @intFromEnum(std.elf.SHT.GNU_VERSYM);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.HIOS)`
|
||||
pub const SHT_HIOS = @intFromEnum(std.elf.SHT.HIOS);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.LOPROC)`
|
||||
pub const SHT_LOPROC = @intFromEnum(std.elf.SHT.LOPROC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.X86_64_UNWIND)`
|
||||
pub const SHT_X86_64_UNWIND = @intFromEnum(std.elf.SHT.X86_64_UNWIND);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.HIPROC)`
|
||||
pub const SHT_HIPROC = @intFromEnum(std.elf.SHT.HIPROC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.LOUSER)`
|
||||
pub const SHT_LOUSER = @intFromEnum(std.elf.SHT.LOUSER);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.SHT.HIUSER)`
|
||||
pub const SHT_HIUSER = @intFromEnum(std.elf.SHT.HIUSER);
|
||||
|
||||
// Note type for .note.gnu.build_id
|
||||
pub const NT_GNU_BUILD_ID = 3;
|
||||
@ -454,6 +461,127 @@ pub const STT_ARM_TFUNC = @intFromEnum(STT.ARM_TFUNC);
|
||||
/// Deprecated, use `@intFromEnum(std.elf.STT.ARM_16BIT)`
|
||||
pub const STT_ARM_16BIT = @intFromEnum(STT.ARM_16BIT);
|
||||
|
||||
pub const PT = enum(Word) {
|
||||
/// Program header table entry unused
|
||||
NULL = 0,
|
||||
/// Loadable program segment
|
||||
LOAD = 1,
|
||||
/// Dynamic linking information
|
||||
DYNAMIC = 2,
|
||||
/// Program interpreter
|
||||
INTERP = 3,
|
||||
/// Auxiliary information
|
||||
NOTE = 4,
|
||||
/// Reserved
|
||||
SHLIB = 5,
|
||||
/// Entry for header table itself
|
||||
PHDR = 6,
|
||||
/// Thread-local storage segment
|
||||
TLS = 7,
|
||||
_,
|
||||
|
||||
/// Number of defined types
|
||||
pub const NUM = @typeInfo(PT).@"enum".fields.len;
|
||||
|
||||
/// Start of OS-specific
|
||||
pub const LOOS: PT = @enumFromInt(0x60000000);
|
||||
/// End of OS-specific
|
||||
pub const HIOS: PT = @enumFromInt(0x6fffffff);
|
||||
|
||||
/// GCC .eh_frame_hdr segment
|
||||
pub const GNU_EH_FRAME: PT = @enumFromInt(0x6474e550);
|
||||
/// Indicates stack executability
|
||||
pub const GNU_STACK: PT = @enumFromInt(0x6474e551);
|
||||
/// Read-only after relocation
|
||||
pub const GNU_RELRO: PT = @enumFromInt(0x6474e552);
|
||||
|
||||
pub const LOSUNW: PT = @enumFromInt(0x6ffffffa);
|
||||
pub const HISUNW: PT = @enumFromInt(0x6fffffff);
|
||||
|
||||
/// Sun specific segment
|
||||
pub const SUNWBSS: PT = @enumFromInt(0x6ffffffa);
|
||||
/// Stack segment
|
||||
pub const SUNWSTACK: PT = @enumFromInt(0x6ffffffb);
|
||||
|
||||
/// Start of processor-specific
|
||||
pub const LOPROC: PT = @enumFromInt(0x70000000);
|
||||
/// End of processor-specific
|
||||
pub const HIPROC: PT = @enumFromInt(0x7fffffff);
|
||||
};
|
||||
|
||||
pub const SHT = enum(Word) {
|
||||
/// Section header table entry unused
|
||||
NULL = 0,
|
||||
/// Program data
|
||||
PROGBITS = 1,
|
||||
/// Symbol table
|
||||
SYMTAB = 2,
|
||||
/// String table
|
||||
STRTAB = 3,
|
||||
/// Relocation entries with addends
|
||||
RELA = 4,
|
||||
/// Symbol hash table
|
||||
HASH = 5,
|
||||
/// Dynamic linking information
|
||||
DYNAMIC = 6,
|
||||
/// Notes
|
||||
NOTE = 7,
|
||||
/// Program space with no data (bss)
|
||||
NOBITS = 8,
|
||||
/// Relocation entries, no addends
|
||||
REL = 9,
|
||||
/// Reserved
|
||||
SHLIB = 10,
|
||||
/// Dynamic linker symbol table
|
||||
DYNSYM = 11,
|
||||
/// Array of constructors
|
||||
INIT_ARRAY = 14,
|
||||
/// Array of destructors
|
||||
FINI_ARRAY = 15,
|
||||
/// Array of pre-constructors
|
||||
PREINIT_ARRAY = 16,
|
||||
/// Section group
|
||||
GROUP = 17,
|
||||
/// Extended section indices
|
||||
SYMTAB_SHNDX = 18,
|
||||
/// RELR relative relocations
|
||||
RELR = 19,
|
||||
_,
|
||||
|
||||
/// Number of defined types
|
||||
pub const NUM = @typeInfo(SHT).@"enum".fields.len;
|
||||
|
||||
/// Start of OS-specific
|
||||
pub const LOOS: SHT = @enumFromInt(0x60000000);
|
||||
/// End of OS-specific
|
||||
pub const HIOS: SHT = @enumFromInt(0x6fffffff);
|
||||
|
||||
/// LLVM address-significance table
|
||||
pub const LLVM_ADDRSIG: SHT = @enumFromInt(0x6fff4c03);
|
||||
|
||||
/// GNU hash table
|
||||
pub const GNU_HASH: SHT = @enumFromInt(0x6ffffff6);
|
||||
/// GNU version definition table
|
||||
pub const GNU_VERDEF: SHT = @enumFromInt(0x6ffffffd);
|
||||
/// GNU needed versions table
|
||||
pub const GNU_VERNEED: SHT = @enumFromInt(0x6ffffffe);
|
||||
/// GNU symbol version table
|
||||
pub const GNU_VERSYM: SHT = @enumFromInt(0x6fffffff);
|
||||
|
||||
/// Start of processor-specific
|
||||
pub const LOPROC: SHT = @enumFromInt(0x70000000);
|
||||
/// End of processor-specific
|
||||
pub const HIPROC: SHT = @enumFromInt(0x7fffffff);
|
||||
|
||||
/// Unwind information
|
||||
pub const X86_64_UNWIND: SHT = @enumFromInt(0x70000001);
|
||||
|
||||
/// Start of application-specific
|
||||
pub const LOUSER: SHT = @enumFromInt(0x80000000);
|
||||
/// End of application-specific
|
||||
pub const HIUSER: SHT = @enumFromInt(0xffffffff);
|
||||
};
|
||||
|
||||
pub const STB = enum(u4) {
|
||||
/// Local symbol
|
||||
LOCAL = 0,
|
||||
@ -899,7 +1027,7 @@ pub const Elf32 = struct {
|
||||
shstrndx: Half,
|
||||
};
|
||||
pub const Phdr = extern struct {
|
||||
type: Word,
|
||||
type: PT,
|
||||
offset: Elf32.Off,
|
||||
vaddr: Elf32.Addr,
|
||||
paddr: Elf32.Addr,
|
||||
@ -910,7 +1038,7 @@ pub const Elf32 = struct {
|
||||
};
|
||||
pub const Shdr = extern struct {
|
||||
name: Word,
|
||||
type: Word,
|
||||
type: SHT,
|
||||
flags: packed struct { shf: SHF },
|
||||
addr: Elf32.Addr,
|
||||
offset: Elf32.Off,
|
||||
@ -989,7 +1117,7 @@ pub const Elf64 = struct {
|
||||
shstrndx: Half,
|
||||
};
|
||||
pub const Phdr = extern struct {
|
||||
type: Word,
|
||||
type: PT,
|
||||
flags: PF,
|
||||
offset: Elf64.Off,
|
||||
vaddr: Elf64.Addr,
|
||||
@ -1000,7 +1128,7 @@ pub const Elf64 = struct {
|
||||
};
|
||||
pub const Shdr = extern struct {
|
||||
name: Word,
|
||||
type: Word,
|
||||
type: SHT,
|
||||
flags: packed struct { shf: SHF, unused: Word = 0 },
|
||||
addr: Elf64.Addr,
|
||||
offset: Elf64.Off,
|
||||
|
||||
@ -6101,7 +6101,7 @@ pub const dirent64 = extern struct {
|
||||
pub const dl_phdr_info = extern struct {
|
||||
addr: usize,
|
||||
name: ?[*:0]const u8,
|
||||
phdr: [*]std.elf.Phdr,
|
||||
phdr: [*]std.elf.ElfN.Phdr,
|
||||
phnum: u16,
|
||||
};
|
||||
|
||||
|
||||
@ -5048,6 +5048,13 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getSelfPhdrs() []std.elf.ElfN.Phdr {
|
||||
const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval;
|
||||
assert(getauxval(std.elf.AT_PHENT) == @sizeOf(std.elf.ElfN.Phdr));
|
||||
const phdrs: [*]std.elf.ElfN.Phdr = @ptrFromInt(getauxval(std.elf.AT_PHDR));
|
||||
return phdrs[0..getauxval(std.elf.AT_PHNUM)];
|
||||
}
|
||||
|
||||
pub fn dl_iterate_phdr(
|
||||
context: anytype,
|
||||
comptime Error: type,
|
||||
@ -5075,34 +5082,24 @@ pub fn dl_iterate_phdr(
|
||||
}
|
||||
}
|
||||
|
||||
const elf_base = std.process.getBaseAddress();
|
||||
const ehdr: *elf.Ehdr = @ptrFromInt(elf_base);
|
||||
// Make sure the base address points to an ELF image.
|
||||
assert(mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC));
|
||||
const n_phdr = ehdr.e_phnum;
|
||||
const phdrs = (@as([*]elf.Phdr, @ptrFromInt(elf_base + ehdr.e_phoff)))[0..n_phdr];
|
||||
|
||||
var it = dl.linkmap_iterator(phdrs) catch unreachable;
|
||||
var it = dl.linkmap_iterator() catch unreachable;
|
||||
|
||||
// The executable has no dynamic link segment, create a single entry for
|
||||
// the whole ELF image.
|
||||
if (it.end()) {
|
||||
// Find the base address for the ELF image, if this is a PIE the value
|
||||
// is non-zero.
|
||||
const base_address = for (phdrs) |*phdr| {
|
||||
if (phdr.p_type == elf.PT_PHDR) {
|
||||
break @intFromPtr(phdrs.ptr) - phdr.p_vaddr;
|
||||
// We could try computing the difference between _DYNAMIC and
|
||||
// the p_vaddr of the PT_DYNAMIC section, but using the phdr is
|
||||
// good enough (Is it?).
|
||||
}
|
||||
} else unreachable;
|
||||
|
||||
var info = dl_phdr_info{
|
||||
.addr = base_address,
|
||||
.name = "/proc/self/exe",
|
||||
const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval;
|
||||
const phdrs = getSelfPhdrs();
|
||||
var info: dl_phdr_info = .{
|
||||
.addr = for (phdrs) |phdr| switch (phdr.type) {
|
||||
.PHDR => break @intFromPtr(phdrs.ptr) - phdr.vaddr,
|
||||
else => {},
|
||||
} else unreachable,
|
||||
.name = switch (getauxval(std.elf.AT_EXECFN)) {
|
||||
0 => "/proc/self/exe",
|
||||
else => |name| @ptrFromInt(name),
|
||||
},
|
||||
.phdr = phdrs.ptr,
|
||||
.phnum = ehdr.e_phnum,
|
||||
.phnum = @intCast(phdrs.len),
|
||||
};
|
||||
|
||||
return callback(&info, @sizeOf(dl_phdr_info), context);
|
||||
@ -5110,24 +5107,18 @@ pub fn dl_iterate_phdr(
|
||||
|
||||
// Last return value from the callback function.
|
||||
while (it.next()) |entry| {
|
||||
var phdr: [*]elf.Phdr = undefined;
|
||||
var phnum: u16 = undefined;
|
||||
const phdrs: []elf.ElfN.Phdr = if (entry.l_addr != 0) phdrs: {
|
||||
const ehdr: *elf.ElfN.Ehdr = @ptrFromInt(entry.l_addr);
|
||||
assert(mem.eql(u8, ehdr.ident[0..4], elf.MAGIC));
|
||||
const phdrs: [*]elf.ElfN.Phdr = @ptrFromInt(entry.l_addr + ehdr.phoff);
|
||||
break :phdrs phdrs[0..ehdr.phnum];
|
||||
} else getSelfPhdrs();
|
||||
|
||||
if (entry.l_addr != 0) {
|
||||
const elf_header: *elf.Ehdr = @ptrFromInt(entry.l_addr);
|
||||
phdr = @ptrFromInt(entry.l_addr + elf_header.e_phoff);
|
||||
phnum = elf_header.e_phnum;
|
||||
} else {
|
||||
// This is the running ELF image
|
||||
phdr = @ptrFromInt(elf_base + ehdr.e_phoff);
|
||||
phnum = ehdr.e_phnum;
|
||||
}
|
||||
|
||||
var info = dl_phdr_info{
|
||||
var info: dl_phdr_info = .{
|
||||
.addr = entry.l_addr,
|
||||
.name = entry.l_name,
|
||||
.phdr = phdr,
|
||||
.phnum = phnum,
|
||||
.phdr = phdrs.ptr,
|
||||
.phnum = @intCast(phdrs.len),
|
||||
};
|
||||
|
||||
try callback(&info, @sizeOf(dl_phdr_info), context);
|
||||
|
||||
@ -257,11 +257,11 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
|
||||
while (i < info.phnum) : (i += 1) {
|
||||
const phdr = info.phdr[i];
|
||||
|
||||
if (phdr.p_type != elf.PT_LOAD) continue;
|
||||
if (phdr.type != .LOAD) continue;
|
||||
|
||||
const reloc_addr = info.addr + phdr.p_vaddr;
|
||||
const reloc_addr = info.addr + phdr.vaddr;
|
||||
// Find the ELF header
|
||||
const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.p_offset));
|
||||
const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.offset));
|
||||
// Validate the magic
|
||||
if (!mem.eql(u8, elf_header.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic;
|
||||
// Consistency check
|
||||
|
||||
@ -1658,13 +1658,13 @@ fn posixGetUserInfoPasswdStream(name: []const u8, reader: *std.Io.Reader) !UserI
|
||||
pub fn getBaseAddress() usize {
|
||||
switch (native_os) {
|
||||
.linux => {
|
||||
const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval;
|
||||
const base = getauxval(std.elf.AT_BASE);
|
||||
if (base != 0) {
|
||||
return base;
|
||||
}
|
||||
const phdr = getauxval(std.elf.AT_PHDR);
|
||||
return phdr - @sizeOf(std.elf.Ehdr);
|
||||
const phdrs = std.posix.getSelfPhdrs();
|
||||
var base: usize = 0;
|
||||
for (phdrs) |phdr| switch (phdr.type) {
|
||||
.LOAD => return base + phdr.vaddr,
|
||||
.PHDR => base = @intFromPtr(phdrs.ptr) - phdr.vaddr,
|
||||
else => {},
|
||||
} else unreachable;
|
||||
},
|
||||
.driverkit, .ios, .macos, .tvos, .visionos, .watchos => {
|
||||
return @intFromPtr(&std.c._mh_execute_header);
|
||||
|
||||
1072
src/link/Elf2.zig
1072
src/link/Elf2.zig
File diff suppressed because it is too large
Load Diff
@ -486,6 +486,14 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct {
|
||||
break :free .{ free_ni, free_node };
|
||||
},
|
||||
};
|
||||
switch (opts.prev) {
|
||||
.none => opts.parent.get(mf).first = free_ni,
|
||||
else => |prev_ni| prev_ni.get(mf).next = free_ni,
|
||||
}
|
||||
switch (opts.next) {
|
||||
.none => opts.parent.get(mf).last = free_ni,
|
||||
else => |next_ni| next_ni.get(mf).prev = free_ni,
|
||||
}
|
||||
free_node.* = .{
|
||||
.parent = opts.parent,
|
||||
.prev = opts.prev,
|
||||
@ -535,13 +543,10 @@ pub fn addOnlyChildNode(
|
||||
try mf.nodes.ensureUnusedCapacity(gpa, 1);
|
||||
const parent = parent_ni.get(mf);
|
||||
assert(parent.first == .none and parent.last == .none);
|
||||
const ni = try mf.addNode(gpa, .{
|
||||
return mf.addNode(gpa, .{
|
||||
.parent = parent_ni,
|
||||
.add_node = opts,
|
||||
});
|
||||
parent.first = ni;
|
||||
parent.last = ni;
|
||||
return ni;
|
||||
}
|
||||
|
||||
pub fn addFirstChildNode(
|
||||
@ -552,17 +557,11 @@ pub fn addFirstChildNode(
|
||||
) !Node.Index {
|
||||
try mf.nodes.ensureUnusedCapacity(gpa, 1);
|
||||
const parent = parent_ni.get(mf);
|
||||
const ni = try mf.addNode(gpa, .{
|
||||
return mf.addNode(gpa, .{
|
||||
.parent = parent_ni,
|
||||
.next = parent.first,
|
||||
.add_node = opts,
|
||||
});
|
||||
switch (parent.first) {
|
||||
.none => parent.last = ni,
|
||||
else => |first_ni| first_ni.get(mf).prev = ni,
|
||||
}
|
||||
parent.first = ni;
|
||||
return ni;
|
||||
}
|
||||
|
||||
pub fn addLastChildNode(
|
||||
@ -573,7 +572,7 @@ pub fn addLastChildNode(
|
||||
) !Node.Index {
|
||||
try mf.nodes.ensureUnusedCapacity(gpa, 1);
|
||||
const parent = parent_ni.get(mf);
|
||||
const ni = try mf.addNode(gpa, .{
|
||||
return mf.addNode(gpa, .{
|
||||
.parent = parent_ni,
|
||||
.prev = parent.last,
|
||||
.offset = offset: switch (parent.last) {
|
||||
@ -585,12 +584,6 @@ pub fn addLastChildNode(
|
||||
},
|
||||
.add_node = opts,
|
||||
});
|
||||
switch (parent.last) {
|
||||
.none => parent.first = ni,
|
||||
else => |last_ni| last_ni.get(mf).next = ni,
|
||||
}
|
||||
parent.last = ni;
|
||||
return ni;
|
||||
}
|
||||
|
||||
pub fn addNodeAfter(
|
||||
@ -603,19 +596,13 @@ pub fn addNodeAfter(
|
||||
try mf.nodes.ensureUnusedCapacity(gpa, 1);
|
||||
const prev = prev_ni.get(mf);
|
||||
const prev_offset, const prev_size = prev.location().resolve(mf);
|
||||
const ni = try mf.addNode(gpa, .{
|
||||
return mf.addNode(gpa, .{
|
||||
.parent = prev.parent,
|
||||
.prev = prev_ni,
|
||||
.next = prev.next,
|
||||
.offset = prev_offset + prev_size,
|
||||
.add_node = opts,
|
||||
});
|
||||
switch (prev.next) {
|
||||
.none => prev.parent.get(mf).last = ni,
|
||||
else => |next_ni| next_ni.get(mf).prev = ni,
|
||||
}
|
||||
prev.next = ni;
|
||||
return ni;
|
||||
}
|
||||
|
||||
fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user