mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Elf2: elide unused nodes when emitting objects
This commit is contained in:
parent
7bcefe5a22
commit
80c961159b
327
lib/std/elf.zig
327
lib/std/elf.zig
@ -286,105 +286,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 +460,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 +1026,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 +1037,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 +1116,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 +1127,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,
|
||||||
|
|||||||
@ -462,7 +462,7 @@ pub const Reloc = extern struct {
|
|||||||
.TPOFF32 => {
|
.TPOFF32 => {
|
||||||
const phdr = @field(elf.phdrSlice(), @tagName(class));
|
const phdr = @field(elf.phdrSlice(), @tagName(class));
|
||||||
const ph = &phdr[elf.getNode(elf.ni.tls).segment];
|
const ph = &phdr[elf.getNode(elf.ni.tls).segment];
|
||||||
assert(elf.targetLoad(&ph.type) == std.elf.PT_TLS);
|
assert(elf.targetLoad(&ph.type) == .TLS);
|
||||||
std.mem.writeInt(
|
std.mem.writeInt(
|
||||||
i32,
|
i32,
|
||||||
loc_slice[0..4],
|
loc_slice[0..4],
|
||||||
@ -715,12 +715,15 @@ fn initHeaders(
|
|||||||
break :phndx phnum;
|
break :phndx phnum;
|
||||||
} else undefined;
|
} else undefined;
|
||||||
|
|
||||||
const expected_nodes_len = expected_nodes_len: {
|
const expected_nodes_len = expected_nodes_len: switch (@"type") {
|
||||||
const expected_nodes_len = 5 + phnum * 2 + @as(usize, 2) * @intFromBool(have_dynamic_section);
|
.NONE => unreachable,
|
||||||
if (@"type" != .REL) break :expected_nodes_len expected_nodes_len;
|
.REL => {
|
||||||
phnum = 0;
|
defer phnum = 0;
|
||||||
break :expected_nodes_len expected_nodes_len -
|
break :expected_nodes_len 5 + phnum;
|
||||||
@intFromBool(comp.config.any_non_single_threaded);
|
},
|
||||||
|
.EXEC, .DYN => break :expected_nodes_len 5 + phnum * 2 +
|
||||||
|
@as(usize, 2) * @intFromBool(have_dynamic_section),
|
||||||
|
.CORE, _ => unreachable,
|
||||||
};
|
};
|
||||||
try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);
|
try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);
|
||||||
try elf.phdrs.resize(gpa, phnum);
|
try elf.phdrs.resize(gpa, phnum);
|
||||||
@ -771,41 +774,42 @@ fn initHeaders(
|
|||||||
}));
|
}));
|
||||||
elf.nodes.appendAssumeCapacity(.shdr);
|
elf.nodes.appendAssumeCapacity(.shdr);
|
||||||
|
|
||||||
|
var ph_vaddr: u32 = if (@"type" != .REL) ph_vaddr: {
|
||||||
assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
||||||
.alignment = elf.mf.flags.block_size,
|
.alignment = elf.mf.flags.block_size,
|
||||||
.moved = @"type" != .REL,
|
.moved = true,
|
||||||
.bubbles_moved = false,
|
.bubbles_moved = false,
|
||||||
}));
|
}));
|
||||||
elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx });
|
elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx });
|
||||||
if (@"type" != .REL) elf.phdrs.items[rodata_phndx] = elf.ni.rodata;
|
elf.phdrs.items[rodata_phndx] = elf.ni.rodata;
|
||||||
|
|
||||||
assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{
|
assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{
|
||||||
.size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum),
|
.size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum),
|
||||||
.alignment = addr_align,
|
.alignment = addr_align,
|
||||||
.moved = @"type" != .REL,
|
.moved = true,
|
||||||
.resized = @"type" != .REL,
|
.resized = true,
|
||||||
.bubbles_moved = false,
|
.bubbles_moved = false,
|
||||||
}));
|
}));
|
||||||
elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx });
|
elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx });
|
||||||
if (@"type" != .REL) elf.phdrs.items[phdr_phndx] = elf.ni.phdr;
|
elf.phdrs.items[phdr_phndx] = elf.ni.phdr;
|
||||||
|
|
||||||
assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
||||||
.alignment = elf.mf.flags.block_size,
|
.alignment = elf.mf.flags.block_size,
|
||||||
.moved = @"type" != .REL,
|
.moved = true,
|
||||||
.bubbles_moved = false,
|
.bubbles_moved = false,
|
||||||
}));
|
}));
|
||||||
elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx });
|
elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx });
|
||||||
if (@"type" != .REL) elf.phdrs.items[text_phndx] = elf.ni.text;
|
elf.phdrs.items[text_phndx] = elf.ni.text;
|
||||||
|
|
||||||
assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
|
||||||
.alignment = elf.mf.flags.block_size,
|
.alignment = elf.mf.flags.block_size,
|
||||||
.moved = @"type" != .REL,
|
.moved = true,
|
||||||
.bubbles_moved = false,
|
.bubbles_moved = false,
|
||||||
}));
|
}));
|
||||||
elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx });
|
elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx });
|
||||||
if (@"type" != .REL) elf.phdrs.items[data_phndx] = elf.ni.data;
|
elf.phdrs.items[data_phndx] = elf.ni.data;
|
||||||
|
|
||||||
var ph_vaddr: u32 = switch (elf.ehdrField(.type)) {
|
break :ph_vaddr switch (elf.ehdrField(.type)) {
|
||||||
else => 0,
|
else => 0,
|
||||||
.EXEC => switch (elf.ehdrField(.machine)) {
|
.EXEC => switch (elf.ehdrField(.machine)) {
|
||||||
.@"386" => 0x400000,
|
.@"386" => 0x400000,
|
||||||
@ -816,6 +820,7 @@ fn initHeaders(
|
|||||||
else => 0x10000,
|
else => 0x10000,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else undefined;
|
||||||
switch (class) {
|
switch (class) {
|
||||||
.NONE, _ => unreachable,
|
.NONE, _ => unreachable,
|
||||||
inline else => |ct_class| {
|
inline else => |ct_class| {
|
||||||
@ -826,7 +831,7 @@ fn initHeaders(
|
|||||||
const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf)));
|
const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf)));
|
||||||
const ph_phdr = &phdr[phdr_phndx];
|
const ph_phdr = &phdr[phdr_phndx];
|
||||||
ph_phdr.* = .{
|
ph_phdr.* = .{
|
||||||
.type = std.elf.PT_PHDR,
|
.type = .PHDR,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = 0,
|
.vaddr = 0,
|
||||||
.paddr = 0,
|
.paddr = 0,
|
||||||
@ -840,7 +845,7 @@ fn initHeaders(
|
|||||||
if (maybe_interp) |_| {
|
if (maybe_interp) |_| {
|
||||||
const ph_interp = &phdr[interp_phndx];
|
const ph_interp = &phdr[interp_phndx];
|
||||||
ph_interp.* = .{
|
ph_interp.* = .{
|
||||||
.type = std.elf.PT_INTERP,
|
.type = .INTERP,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = 0,
|
.vaddr = 0,
|
||||||
.paddr = 0,
|
.paddr = 0,
|
||||||
@ -855,7 +860,7 @@ fn initHeaders(
|
|||||||
_, const rodata_size = elf.ni.rodata.location(&elf.mf).resolve(&elf.mf);
|
_, const rodata_size = elf.ni.rodata.location(&elf.mf).resolve(&elf.mf);
|
||||||
const ph_rodata = &phdr[rodata_phndx];
|
const ph_rodata = &phdr[rodata_phndx];
|
||||||
ph_rodata.* = .{
|
ph_rodata.* = .{
|
||||||
.type = std.elf.PT_NULL,
|
.type = if (rodata_size == 0) .NULL else .LOAD,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = ph_vaddr,
|
.vaddr = ph_vaddr,
|
||||||
.paddr = ph_vaddr,
|
.paddr = ph_vaddr,
|
||||||
@ -870,7 +875,7 @@ fn initHeaders(
|
|||||||
_, const text_size = elf.ni.text.location(&elf.mf).resolve(&elf.mf);
|
_, const text_size = elf.ni.text.location(&elf.mf).resolve(&elf.mf);
|
||||||
const ph_text = &phdr[text_phndx];
|
const ph_text = &phdr[text_phndx];
|
||||||
ph_text.* = .{
|
ph_text.* = .{
|
||||||
.type = std.elf.PT_NULL,
|
.type = if (text_size == 0) .NULL else .LOAD,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = ph_vaddr,
|
.vaddr = ph_vaddr,
|
||||||
.paddr = ph_vaddr,
|
.paddr = ph_vaddr,
|
||||||
@ -885,7 +890,7 @@ fn initHeaders(
|
|||||||
_, const data_size = elf.ni.data.location(&elf.mf).resolve(&elf.mf);
|
_, const data_size = elf.ni.data.location(&elf.mf).resolve(&elf.mf);
|
||||||
const ph_data = &phdr[data_phndx];
|
const ph_data = &phdr[data_phndx];
|
||||||
ph_data.* = .{
|
ph_data.* = .{
|
||||||
.type = std.elf.PT_NULL,
|
.type = if (data_size == 0) .NULL else .LOAD,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = ph_vaddr,
|
.vaddr = ph_vaddr,
|
||||||
.paddr = ph_vaddr,
|
.paddr = ph_vaddr,
|
||||||
@ -900,7 +905,7 @@ fn initHeaders(
|
|||||||
if (have_dynamic_section) {
|
if (have_dynamic_section) {
|
||||||
const ph_dynamic = &phdr[dynamic_phndx];
|
const ph_dynamic = &phdr[dynamic_phndx];
|
||||||
ph_dynamic.* = .{
|
ph_dynamic.* = .{
|
||||||
.type = std.elf.PT_DYNAMIC,
|
.type = .DYNAMIC,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = 0,
|
.vaddr = 0,
|
||||||
.paddr = 0,
|
.paddr = 0,
|
||||||
@ -915,7 +920,7 @@ fn initHeaders(
|
|||||||
if (comp.config.any_non_single_threaded) {
|
if (comp.config.any_non_single_threaded) {
|
||||||
const ph_tls = &phdr[tls_phndx];
|
const ph_tls = &phdr[tls_phndx];
|
||||||
ph_tls.* = .{
|
ph_tls.* = .{
|
||||||
.type = std.elf.PT_TLS,
|
.type = .TLS,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.vaddr = 0,
|
.vaddr = 0,
|
||||||
.paddr = 0,
|
.paddr = 0,
|
||||||
@ -931,7 +936,7 @@ fn initHeaders(
|
|||||||
const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf)));
|
const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf)));
|
||||||
sh_null.* = .{
|
sh_null.* = .{
|
||||||
.name = try elf.string(.shstrtab, ""),
|
.name = try elf.string(.shstrtab, ""),
|
||||||
.type = std.elf.SHT_NULL,
|
.type = .NULL,
|
||||||
.flags = .{ .shf = .{} },
|
.flags = .{ .shf = .{} },
|
||||||
.addr = 0,
|
.addr = 0,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@ -951,7 +956,7 @@ fn initHeaders(
|
|||||||
.unused = 0,
|
.unused = 0,
|
||||||
};
|
};
|
||||||
assert(elf.si.symtab == try elf.addSection(elf.ni.file, .{
|
assert(elf.si.symtab == try elf.addSection(elf.ni.file, .{
|
||||||
.type = std.elf.SHT_SYMTAB,
|
.type = .SYMTAB,
|
||||||
.size = @sizeOf(ElfN.Sym) * 1,
|
.size = @sizeOf(ElfN.Sym) * 1,
|
||||||
.addralign = addr_align,
|
.addralign = addr_align,
|
||||||
.entsize = @sizeOf(ElfN.Sym),
|
.entsize = @sizeOf(ElfN.Sym),
|
||||||
@ -972,7 +977,7 @@ fn initHeaders(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert(elf.si.shstrtab == try elf.addSection(elf.ni.file, .{
|
assert(elf.si.shstrtab == try elf.addSection(elf.ni.file, .{
|
||||||
.type = std.elf.SHT_STRTAB,
|
.type = .STRTAB,
|
||||||
.addralign = elf.mf.flags.block_size,
|
.addralign = elf.mf.flags.block_size,
|
||||||
.entsize = 1,
|
.entsize = 1,
|
||||||
}));
|
}));
|
||||||
@ -982,7 +987,7 @@ fn initHeaders(
|
|||||||
|
|
||||||
assert(elf.si.strtab == try elf.addSection(elf.ni.file, .{
|
assert(elf.si.strtab == try elf.addSection(elf.ni.file, .{
|
||||||
.name = ".strtab",
|
.name = ".strtab",
|
||||||
.type = std.elf.SHT_STRTAB,
|
.type = .STRTAB,
|
||||||
.size = 1,
|
.size = 1,
|
||||||
.addralign = elf.mf.flags.block_size,
|
.addralign = elf.mf.flags.block_size,
|
||||||
.entsize = 1,
|
.entsize = 1,
|
||||||
@ -1016,6 +1021,7 @@ fn initHeaders(
|
|||||||
elf.phdrs.items[interp_phndx] = interp_ni;
|
elf.phdrs.items[interp_phndx] = interp_ni;
|
||||||
|
|
||||||
const sec_interp_si = try elf.addSection(interp_ni, .{
|
const sec_interp_si = try elf.addSection(interp_ni, .{
|
||||||
|
.type = .PROGBITS,
|
||||||
.name = ".interp",
|
.name = ".interp",
|
||||||
.flags = .{ .ALLOC = true },
|
.flags = .{ .ALLOC = true },
|
||||||
.size = @intCast(interp.len + 1),
|
.size = @intCast(interp.len + 1),
|
||||||
@ -1038,7 +1044,7 @@ fn initHeaders(
|
|||||||
const ElfN = ct_class.ElfN();
|
const ElfN = ct_class.ElfN();
|
||||||
elf.si.dynsym = try elf.addSection(elf.ni.rodata, .{
|
elf.si.dynsym = try elf.addSection(elf.ni.rodata, .{
|
||||||
.name = ".dynsym",
|
.name = ".dynsym",
|
||||||
.type = std.elf.SHT_DYNSYM,
|
.type = .DYNSYM,
|
||||||
.size = @sizeOf(ElfN.Sym) * 1,
|
.size = @sizeOf(ElfN.Sym) * 1,
|
||||||
.addralign = addr_align,
|
.addralign = addr_align,
|
||||||
.entsize = @sizeOf(ElfN.Sym),
|
.entsize = @sizeOf(ElfN.Sym),
|
||||||
@ -1057,14 +1063,14 @@ fn initHeaders(
|
|||||||
}
|
}
|
||||||
elf.si.dynstr = try elf.addSection(elf.ni.rodata, .{
|
elf.si.dynstr = try elf.addSection(elf.ni.rodata, .{
|
||||||
.name = ".dynstr",
|
.name = ".dynstr",
|
||||||
.type = std.elf.SHT_STRTAB,
|
.type = .STRTAB,
|
||||||
.size = 1,
|
.size = 1,
|
||||||
.addralign = elf.mf.flags.block_size,
|
.addralign = elf.mf.flags.block_size,
|
||||||
.entsize = 1,
|
.entsize = 1,
|
||||||
});
|
});
|
||||||
elf.si.dynamic = try elf.addSection(dynamic_ni, .{
|
elf.si.dynamic = try elf.addSection(dynamic_ni, .{
|
||||||
.name = ".dynamic",
|
.name = ".dynamic",
|
||||||
.type = std.elf.SHT_DYNAMIC,
|
.type = .DYNAMIC,
|
||||||
.flags = .{ .ALLOC = true, .WRITE = true },
|
.flags = .{ .ALLOC = true, .WRITE = true },
|
||||||
.addralign = addr_align,
|
.addralign = addr_align,
|
||||||
});
|
});
|
||||||
@ -1126,7 +1132,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
|
|||||||
.file => return 0,
|
.file => return 0,
|
||||||
.ehdr, .shdr => unreachable,
|
.ehdr, .shdr => unreachable,
|
||||||
.segment => |phndx| break :parent_vaddr switch (elf.phdrSlice()) {
|
.segment => |phndx| break :parent_vaddr switch (elf.phdrSlice()) {
|
||||||
inline else => |ph| elf.targetLoad(&ph[phndx].vaddr),
|
inline else => |phdr| elf.targetLoad(&phdr[phndx].vaddr),
|
||||||
},
|
},
|
||||||
.section => |si| si,
|
.section => |si| si,
|
||||||
.input_section => unreachable,
|
.input_section => unreachable,
|
||||||
@ -1581,7 +1587,7 @@ fn loadObject(
|
|||||||
};
|
};
|
||||||
try r.discardAll(ehdr.shentsize);
|
try r.discardAll(ehdr.shentsize);
|
||||||
switch (section.shdr.type) {
|
switch (section.shdr.type) {
|
||||||
std.elf.SHT_NULL, std.elf.SHT_NOBITS => {},
|
.NULL, .NOBITS => {},
|
||||||
else => if (section.shdr.offset + section.shdr.size > fl.size)
|
else => if (section.shdr.offset + section.shdr.size > fl.size)
|
||||||
return diags.failParse(path, "bad section location", .{}),
|
return diags.failParse(path, "bad section location", .{}),
|
||||||
}
|
}
|
||||||
@ -1590,8 +1596,7 @@ fn loadObject(
|
|||||||
if (ehdr.shstrndx == std.elf.SHN_UNDEF or ehdr.shstrndx >= ehdr.shnum)
|
if (ehdr.shstrndx == std.elf.SHN_UNDEF or ehdr.shstrndx >= ehdr.shnum)
|
||||||
return diags.failParse(path, "missing section names", .{});
|
return diags.failParse(path, "missing section names", .{});
|
||||||
const shdr = §ions[ehdr.shstrndx].shdr;
|
const shdr = §ions[ehdr.shstrndx].shdr;
|
||||||
if (shdr.type != std.elf.SHT_STRTAB)
|
if (shdr.type != .STRTAB) return diags.failParse(path, "invalid shstrtab type", .{});
|
||||||
return diags.failParse(path, "invalid shstrtab type", .{});
|
|
||||||
const shstrtab = try gpa.alloc(u8, @intCast(shdr.size));
|
const shstrtab = try gpa.alloc(u8, @intCast(shdr.size));
|
||||||
errdefer gpa.free(shstrtab);
|
errdefer gpa.free(shstrtab);
|
||||||
try fr.seekTo(fl.offset + shdr.offset);
|
try fr.seekTo(fl.offset + shdr.offset);
|
||||||
@ -1604,7 +1609,7 @@ fn loadObject(
|
|||||||
try elf.input_sections.ensureUnusedCapacity(gpa, ehdr.shnum - 1);
|
try elf.input_sections.ensureUnusedCapacity(gpa, ehdr.shnum - 1);
|
||||||
for (sections[1..]) |*section| switch (section.shdr.type) {
|
for (sections[1..]) |*section| switch (section.shdr.type) {
|
||||||
else => {},
|
else => {},
|
||||||
std.elf.SHT_PROGBITS, std.elf.SHT_NOBITS => {
|
.PROGBITS, .NOBITS => {
|
||||||
if (section.shdr.name >= shstrtab.len) continue;
|
if (section.shdr.name >= shstrtab.len) continue;
|
||||||
const name = std.mem.sliceTo(shstrtab[section.shdr.name..], 0);
|
const name = std.mem.sliceTo(shstrtab[section.shdr.name..], 0);
|
||||||
const parent_si = elf.namedSection(name) orelse continue;
|
const parent_si = elf.namedSection(name) orelse continue;
|
||||||
@ -1639,14 +1644,14 @@ fn loadObject(
|
|||||||
defer symmap.deinit(gpa);
|
defer symmap.deinit(gpa);
|
||||||
for (sections[1..], 1..) |*symtab, symtab_shndx| switch (symtab.shdr.type) {
|
for (sections[1..], 1..) |*symtab, symtab_shndx| switch (symtab.shdr.type) {
|
||||||
else => {},
|
else => {},
|
||||||
std.elf.SHT_SYMTAB => {
|
.SYMTAB => {
|
||||||
if (symtab.shdr.entsize < @sizeOf(ElfN.Sym))
|
if (symtab.shdr.entsize < @sizeOf(ElfN.Sym))
|
||||||
return diags.failParse(path, "unsupported symtab entsize", .{});
|
return diags.failParse(path, "unsupported symtab entsize", .{});
|
||||||
const strtab = strtab: {
|
const strtab = strtab: {
|
||||||
if (symtab.shdr.link == std.elf.SHN_UNDEF or symtab.shdr.link >= ehdr.shnum)
|
if (symtab.shdr.link == std.elf.SHN_UNDEF or symtab.shdr.link >= ehdr.shnum)
|
||||||
return diags.failParse(path, "missing symbol names", .{});
|
return diags.failParse(path, "missing symbol names", .{});
|
||||||
const shdr = §ions[symtab.shdr.link].shdr;
|
const shdr = §ions[symtab.shdr.link].shdr;
|
||||||
if (shdr.type != std.elf.SHT_STRTAB)
|
if (shdr.type != .STRTAB)
|
||||||
return diags.failParse(path, "invalid strtab type", .{});
|
return diags.failParse(path, "invalid strtab type", .{});
|
||||||
const strtab = try gpa.alloc(u8, @intCast(shdr.size));
|
const strtab = try gpa.alloc(u8, @intCast(shdr.size));
|
||||||
errdefer gpa.free(strtab);
|
errdefer gpa.free(strtab);
|
||||||
@ -1729,13 +1734,13 @@ fn loadObject(
|
|||||||
}
|
}
|
||||||
for (sections[1..]) |*rels| switch (rels.shdr.type) {
|
for (sections[1..]) |*rels| switch (rels.shdr.type) {
|
||||||
else => {},
|
else => {},
|
||||||
inline std.elf.SHT_REL, std.elf.SHT_RELA => |sht| {
|
inline .REL, .RELA => |sht| {
|
||||||
if (rels.shdr.link != symtab_shndx or rels.shdr.info == std.elf.SHN_UNDEF or
|
if (rels.shdr.link != symtab_shndx or rels.shdr.info == std.elf.SHN_UNDEF or
|
||||||
rels.shdr.info >= ehdr.shnum) continue;
|
rels.shdr.info >= ehdr.shnum) continue;
|
||||||
const Rel = switch (sht) {
|
const Rel = switch (sht) {
|
||||||
else => comptime unreachable,
|
else => comptime unreachable,
|
||||||
std.elf.SHT_REL => ElfN.Rel,
|
.REL => ElfN.Rel,
|
||||||
std.elf.SHT_RELA => ElfN.Rela,
|
.RELA => ElfN.Rela,
|
||||||
};
|
};
|
||||||
if (rels.shdr.entsize < @sizeOf(Rel))
|
if (rels.shdr.entsize < @sizeOf(Rel))
|
||||||
return diags.failParse(path, "unsupported rel entsize", .{});
|
return diags.failParse(path, "unsupported rel entsize", .{});
|
||||||
@ -1810,7 +1815,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void
|
|||||||
try r.discardAll(ehdr.phentsize);
|
try r.discardAll(ehdr.phentsize);
|
||||||
switch (ph.type) {
|
switch (ph.type) {
|
||||||
else => {},
|
else => {},
|
||||||
std.elf.PT_DYNAMIC => break ph,
|
.DYNAMIC => break ph,
|
||||||
}
|
}
|
||||||
} else return diags.failParse(path, "no dynamic segment", .{});
|
} else return diags.failParse(path, "no dynamic segment", .{});
|
||||||
const dynnum = std.math.divExact(
|
const dynnum = std.math.divExact(
|
||||||
@ -1846,7 +1851,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void
|
|||||||
try r.discardAll(ehdr.phentsize);
|
try r.discardAll(ehdr.phentsize);
|
||||||
switch (ph.type) {
|
switch (ph.type) {
|
||||||
else => {},
|
else => {},
|
||||||
std.elf.PT_LOAD => if (strtab.? >= ph.vaddr and
|
.LOAD => if (strtab.? >= ph.vaddr and
|
||||||
strtab.? + (strsz orelse 0) <= ph.vaddr + ph.filesz) break ph,
|
strtab.? + (strsz orelse 0) <= ph.vaddr + ph.filesz) break ph,
|
||||||
}
|
}
|
||||||
} else return diags.failParse(path, "strtab not part of a loaded segment", .{});
|
} else return diags.failParse(path, "strtab not part of a loaded segment", .{});
|
||||||
@ -1982,15 +1987,15 @@ pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.In
|
|||||||
|
|
||||||
fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
|
fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
|
||||||
name: []const u8 = "",
|
name: []const u8 = "",
|
||||||
type: std.elf.Word = std.elf.SHT_NULL,
|
type: std.elf.SHT = .NULL,
|
||||||
flags: std.elf.SHF = .{},
|
flags: std.elf.SHF = .{},
|
||||||
size: std.elf.Word = 0,
|
size: std.elf.Word = 0,
|
||||||
addralign: std.mem.Alignment = .@"1",
|
addralign: std.mem.Alignment = .@"1",
|
||||||
entsize: std.elf.Word = 0,
|
entsize: std.elf.Word = 0,
|
||||||
}) !Symbol.Index {
|
}) !Symbol.Index {
|
||||||
switch (opts.type) {
|
switch (opts.type) {
|
||||||
std.elf.SHT_NULL => assert(opts.size == 0),
|
.NULL => assert(opts.size == 0),
|
||||||
std.elf.SHT_PROGBITS => assert(opts.size > 0),
|
.PROGBITS => assert(opts.size > 0),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
const gpa = elf.base.comp.gpa;
|
const gpa = elf.base.comp.gpa;
|
||||||
@ -2626,10 +2631,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
|
|||||||
const ph = &phdr[phndx];
|
const ph = &phdr[phndx];
|
||||||
switch (elf.targetLoad(&ph.type)) {
|
switch (elf.targetLoad(&ph.type)) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
std.elf.PT_NULL, std.elf.PT_LOAD => return,
|
.NULL, .LOAD => return,
|
||||||
std.elf.PT_DYNAMIC, std.elf.PT_INTERP => {},
|
.DYNAMIC, .INTERP => {},
|
||||||
std.elf.PT_PHDR => @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset,
|
.PHDR => @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset,
|
||||||
std.elf.PT_TLS => {},
|
.TLS => {},
|
||||||
}
|
}
|
||||||
elf.targetStore(&ph.vaddr, @intCast(elf.computeNodeVAddr(ni)));
|
elf.targetStore(&ph.vaddr, @intCast(elf.computeNodeVAddr(ni)));
|
||||||
ph.paddr = ph.vaddr;
|
ph.paddr = ph.vaddr;
|
||||||
@ -2694,22 +2699,18 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
|
|||||||
elf.targetStore(&ph.memsz, @intCast(memsz));
|
elf.targetStore(&ph.memsz, @intCast(memsz));
|
||||||
switch (elf.targetLoad(&ph.type)) {
|
switch (elf.targetLoad(&ph.type)) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
std.elf.PT_NULL => if (size > 0) elf.targetStore(&ph.type, std.elf.PT_LOAD),
|
.NULL => if (size > 0) elf.targetStore(&ph.type, .LOAD),
|
||||||
std.elf.PT_LOAD => if (size == 0) elf.targetStore(&ph.type, std.elf.PT_NULL),
|
.LOAD => if (size == 0) elf.targetStore(&ph.type, .NULL),
|
||||||
std.elf.PT_DYNAMIC, std.elf.PT_INTERP, std.elf.PT_PHDR => return,
|
.DYNAMIC, .INTERP, .PHDR => return,
|
||||||
std.elf.PT_TLS => return ni.childrenMoved(elf.base.comp.gpa, &elf.mf),
|
.TLS => return ni.childrenMoved(elf.base.comp.gpa, &elf.mf),
|
||||||
}
|
}
|
||||||
var vaddr = elf.targetLoad(&ph.vaddr);
|
var vaddr = elf.targetLoad(&ph.vaddr);
|
||||||
var new_phndx = phndx;
|
var new_phndx = phndx;
|
||||||
for (phdr[phndx + 1 ..], phndx + 1..) |*next_ph, next_phndx| {
|
for (phdr[phndx + 1 ..], phndx + 1..) |*next_ph, next_phndx| {
|
||||||
switch (elf.targetLoad(&next_ph.type)) {
|
switch (elf.targetLoad(&next_ph.type)) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
std.elf.PT_NULL, std.elf.PT_LOAD => {},
|
.NULL, .LOAD => {},
|
||||||
std.elf.PT_DYNAMIC,
|
.DYNAMIC, .INTERP, .PHDR, .TLS => break,
|
||||||
std.elf.PT_INTERP,
|
|
||||||
std.elf.PT_PHDR,
|
|
||||||
std.elf.PT_TLS,
|
|
||||||
=> break,
|
|
||||||
}
|
}
|
||||||
const next_vaddr = elf.targetLoad(&next_ph.vaddr);
|
const next_vaddr = elf.targetLoad(&next_ph.vaddr);
|
||||||
if (vaddr + memsz <= next_vaddr) break;
|
if (vaddr + memsz <= next_vaddr) break;
|
||||||
@ -2737,13 +2738,13 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
|
|||||||
elf.targetStore(&sh.size, @intCast(size));
|
elf.targetStore(&sh.size, @intCast(size));
|
||||||
switch (elf.targetLoad(&sh.type)) {
|
switch (elf.targetLoad(&sh.type)) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
std.elf.SHT_NULL => if (size > 0) elf.targetStore(&sh.type, std.elf.SHT_PROGBITS),
|
.NULL => if (size > 0) elf.targetStore(&sh.type, .PROGBITS),
|
||||||
std.elf.SHT_PROGBITS => if (size == 0) elf.targetStore(&sh.type, std.elf.SHT_NULL),
|
.PROGBITS => if (size == 0) elf.targetStore(&sh.type, .NULL),
|
||||||
std.elf.SHT_SYMTAB, std.elf.SHT_DYNSYM => elf.targetStore(
|
.SYMTAB, .DYNSYM => elf.targetStore(
|
||||||
&sh.info,
|
&sh.info,
|
||||||
@intCast(@divExact(size, elf.targetLoad(&sh.entsize))),
|
@intCast(@divExact(size, elf.targetLoad(&sh.entsize))),
|
||||||
),
|
),
|
||||||
std.elf.SHT_STRTAB, std.elf.SHT_DYNAMIC => {},
|
.STRTAB, .DYNAMIC => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2870,6 +2871,26 @@ pub fn printNode(
|
|||||||
try w.writeAll(@tagName(node));
|
try w.writeAll(@tagName(node));
|
||||||
switch (node) {
|
switch (node) {
|
||||||
else => {},
|
else => {},
|
||||||
|
.segment => |phndx| switch (elf.phdrSlice()) {
|
||||||
|
inline else => |phdr| {
|
||||||
|
const ph = &phdr[phndx];
|
||||||
|
try w.writeByte('(');
|
||||||
|
const pt = elf.targetLoad(&ph.type);
|
||||||
|
if (std.enums.tagName(std.elf.PT, pt)) |pt_name|
|
||||||
|
try w.writeAll(pt_name)
|
||||||
|
else inline for (@typeInfo(std.elf.PT).@"enum".decls) |decl| {
|
||||||
|
const decl_val = @field(std.elf.PT, decl.name);
|
||||||
|
if (@TypeOf(decl_val) != std.elf.PT) continue;
|
||||||
|
if (pt == @field(std.elf.PT, decl.name)) break try w.writeAll(decl.name);
|
||||||
|
} else try w.print("0x{x}", .{pt});
|
||||||
|
try w.writeAll(", ");
|
||||||
|
const pf = elf.targetLoad(&ph.flags);
|
||||||
|
if (pf.R) try w.writeByte('R');
|
||||||
|
if (pf.W) try w.writeByte('W');
|
||||||
|
if (pf.X) try w.writeByte('X');
|
||||||
|
try w.writeByte(')');
|
||||||
|
},
|
||||||
|
},
|
||||||
.section => |si| try w.print("({s})", .{elf.sectionName(si)}),
|
.section => |si| try w.print("({s})", .{elf.sectionName(si)}),
|
||||||
.input_section => |isi| {
|
.input_section => |isi| {
|
||||||
const ii = isi.input(elf);
|
const ii = isi.input(elf);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user