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