| ... | @@ -2927,6 +2927,7 @@ fn initHeaders( | ... | @@ -2927,6 +2927,7 @@ fn initHeaders( |
| 2927 | tls: u32, | 2927 | tls: u32, |
| 2928 | dynamic: u32, | 2928 | dynamic: u32, |
| 2929 | relro: u32, | 2929 | relro: u32, |
| | 2930 | gnu_stack: u32, |
| 2930 | }, const phnum: u32 = ph: { | 2931 | }, const phnum: u32 = ph: { |
| 2931 | switch (@"type") { | 2932 | switch (@"type") { |
| 2932 | .NONE, .CORE, _ => unreachable, | 2933 | .NONE, .CORE, _ => unreachable, |
| ... | @@ -2967,12 +2968,16 @@ fn initHeaders( | ... | @@ -2967,12 +2968,16 @@ fn initHeaders( |
| 2967 | defer phnum += 1; | 2968 | defer phnum += 1; |
| 2968 | break :phndx phnum; | 2969 | break :phndx phnum; |
| 2969 | }, | 2970 | }, |
| | 2971 | .gnu_stack = phndx: { |
| | 2972 | defer phnum += 1; |
| | 2973 | break :phndx phnum; |
| | 2974 | }, |
| 2970 | }, phnum }; | 2975 | }, phnum }; |
| 2971 | }; | 2976 | }; |
| 2972 | | 2977 | |
| 2973 | const expected_nodes_len = 3 + // `.file`, `.ehdr`, and `.shdr` nodes | 2978 | const expected_nodes_len = 3 + // `.file`, `.ehdr`, and `.shdr` nodes |
| 2974 | (shnum - 1) + // -1 because the null shdr does not have a `.section` node | 2979 | (shnum - 1) + // -1 because the null shdr does not have a `.section` node |
| 2975 | phnum; | 2980 | (phnum -| 1); // -1 because the GNU_STACK phdr does not have a `.segment` node |
| 2976 | | 2981 | |
| 2977 | try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len); | 2982 | try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len); |
| 2978 | try elf.shdrs.ensureTotalCapacity(gpa, shnum); | 2983 | try elf.shdrs.ensureTotalCapacity(gpa, shnum); |
| ... | @@ -3085,6 +3090,8 @@ fn initHeaders( | ... | @@ -3085,6 +3090,8 @@ fn initHeaders( |
| 3085 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro }); | 3090 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro }); |
| 3086 | elf.phdrs.items[phndx.relro] = elf.ni.data_rel_ro; | 3091 | elf.phdrs.items[phndx.relro] = elf.ni.data_rel_ro; |
| 3087 | | 3092 | |
| | 3093 | elf.phdrs.items[phndx.gnu_stack] = .none; |
| | 3094 | |
| 3088 | break :ph_vaddr switch (elf.ehdrField(.type)) { | 3095 | break :ph_vaddr switch (elf.ehdrField(.type)) { |
| 3089 | .NONE, .CORE, _ => unreachable, | 3096 | .NONE, .CORE, _ => unreachable, |
| 3090 | .REL, .DYN => 0, | 3097 | .REL, .DYN => 0, |
| ... | @@ -3221,6 +3228,19 @@ fn initHeaders( | ... | @@ -3221,6 +3228,19 @@ fn initHeaders( |
| 3221 | .@"align" = @intCast(elf.mf.flags.block_size.toByteUnits()), | 3228 | .@"align" = @intCast(elf.mf.flags.block_size.toByteUnits()), |
| 3222 | }; | 3229 | }; |
| 3223 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_relro); | 3230 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_relro); |
| | 3231 | |
| | 3232 | const ph_gnu_stack = &phdr[phndx.gnu_stack]; |
| | 3233 | ph_gnu_stack.* = .{ |
| | 3234 | .type = .GNU_STACK, |
| | 3235 | .offset = 0, |
| | 3236 | .vaddr = 0, |
| | 3237 | .paddr = 0, |
| | 3238 | .filesz = 0, |
| | 3239 | .memsz = @intCast(elf.options.stack_size orelse 0), |
| | 3240 | .flags = .{ .R = true, .W = true }, |
| | 3241 | .@"align" = 1, |
| | 3242 | }; |
| | 3243 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_gnu_stack); |
| 3224 | } | 3244 | } |
| 3225 | | 3245 | |
| 3226 | const sh_undef: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf))); | 3246 | const sh_undef: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf))); |
| ... | @@ -6896,7 +6916,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo | ... | @@ -6896,7 +6916,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 6896 | switch (elf.targetLoad(&next_ph.type)) { | 6916 | switch (elf.targetLoad(&next_ph.type)) { |
| 6897 | else => unreachable, | 6917 | else => unreachable, |
| 6898 | .NULL, .LOAD => {}, | 6918 | .NULL, .LOAD => {}, |
| 6899 | .DYNAMIC, .INTERP, .PHDR, .TLS, std.elf.PT.GNU_RELRO => break, | 6919 | .DYNAMIC, .INTERP, .PHDR, .TLS, .GNU_RELRO, .GNU_STACK => break, |
| 6900 | } | 6920 | } |
| 6901 | const next_vaddr = elf.targetLoad(&next_ph.vaddr); | 6921 | const next_vaddr = elf.targetLoad(&next_ph.vaddr); |
| 6902 | if (vaddr + memsz <= next_vaddr) break; | 6922 | if (vaddr + memsz <= next_vaddr) break; |