| ... | @@ -3730,7 +3730,7 @@ fn create( | ... | @@ -3730,7 +3730,7 @@ fn create( |
| 3730 | .big => .@"2MSB", | 3730 | .big => .@"2MSB", |
| 3731 | }; | 3731 | }; |
| 3732 | const osabi: std.elf.OSABI = switch (target.os.tag) { | 3732 | const osabi: std.elf.OSABI = switch (target.os.tag) { |
| 3733 | else => if (target.abi.isGnu()) .GNU else .NONE, | 3733 | else => .NONE, // might be changed to `.GNU` by `checkInputIdent` |
| 3734 | .freestanding, .other => .STANDALONE, | 3734 | .freestanding, .other => .STANDALONE, |
| 3735 | .netbsd => .NETBSD, | 3735 | .netbsd => .NETBSD, |
| 3736 | .illumos => .SOLARIS, | 3736 | .illumos => .SOLARIS, |
| ... | @@ -7089,9 +7089,11 @@ fn loadDso( | ... | @@ -7089,9 +7089,11 @@ fn loadDso( |
| 7089 | /// `error.AlreadyReported`, but if the magic number is missing or incorrect, returns | 7089 | /// `error.AlreadyReported`, but if the magic number is missing or incorrect, returns |
| 7090 | /// `error.BadMagic` instead. | 7090 | /// `error.BadMagic` instead. |
| 7091 | /// | 7091 | /// |
| | 7092 | /// If necessary, modifies our own ident to use `ELF_OSABI_GNU` instead of `ELF_OSABI_NONE`. |
| | 7093 | /// |
| 7092 | /// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer. | 7094 | /// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer. |
| 7093 | fn checkInputIdent( | 7095 | fn checkInputIdent( |
| 7094 | elf: *const Elf, | 7096 | elf: *Elf, |
| 7095 | path: std.Build.Cache.Path, | 7097 | path: std.Build.Cache.Path, |
| 7096 | r: *Io.Reader, | 7098 | r: *Io.Reader, |
| 7097 | ) error{ BadMagic, EndOfStream, AlreadyReported, ReadFailed }!void { | 7099 | ) error{ BadMagic, EndOfStream, AlreadyReported, ReadFailed }!void { |
| ... | @@ -7106,8 +7108,9 @@ fn checkInputIdent( | ... | @@ -7106,8 +7108,9 @@ fn checkInputIdent( |
| 7106 | } | 7108 | } |
| 7107 | | 7109 | |
| 7108 | const ident = try r.peekStructPointer(std.elf.Ident); | 7110 | const ident = try r.peekStructPointer(std.elf.Ident); |
| 7109 | const target: *const std.elf.Ident = | 7111 | const target: *std.elf.Ident = @ptrCast( |
| 7110 | @ptrCast(elf.ni.elf.sliceConst(&elf.mf)[0..@sizeOf(std.elf.Ident)]); | 7112 | elf.ni.elf.slice(&elf.mf)[0..@sizeOf(std.elf.Ident)], |
| | 7113 | ); |
| 7111 | | 7114 | |
| 7112 | if (ident.class != target.class) return diags.failParse( | 7115 | if (ident.class != target.class) return diags.failParse( |
| 7113 | path, | 7116 | path, |
| ... | @@ -7124,17 +7127,24 @@ fn checkInputIdent( | ... | @@ -7124,17 +7127,24 @@ fn checkInputIdent( |
| 7124 | "bad ELF version ({d})", | 7127 | "bad ELF version ({d})", |
| 7125 | .{ident.version}, | 7128 | .{ident.version}, |
| 7126 | ); | 7129 | ); |
| 7127 | | 7130 | // OSABI is a bit more complex. |
| 7128 | // OSABI is a bit more complex. On Linux, `.NONE` and `.GNU` are both valid and both common. | 7131 | const expect_abiversion: u8 = switch (ident.osabi) { |
| 7129 | // It sounds reasonable to allow the value we chose *and* allow `.NONE`. | 7132 | .NONE => 0, |
| 7130 | const expect_abiversion: u8 = abiver: { | 7133 | .GNU => abiversion: { |
| 7131 | if (ident.osabi == .NONE) break :abiver 0; | 7134 | // If we're currently emitting `ELF_OSABI_NONE` then prefer `ELF_OSABI_GNU` to signify |
| 7132 | if (ident.osabi == target.osabi) break :abiver target.abiversion; | 7135 | // the GNU-specific features, but if we're already emitting a target-specific osabi then |
| 7133 | return diags.failParse( | 7136 | // just leave it alone. |
| | 7137 | if (target.osabi == .NONE) target.osabi = .GNU; |
| | 7138 | // Either way, allow the `ELF_OSABI_GNU` input through. |
| | 7139 | break :abiversion 0; |
| | 7140 | }, |
| | 7141 | else => if (ident.osabi == target.osabi) abiversion: { |
| | 7142 | break :abiversion target.abiversion; |
| | 7143 | } else return diags.failParse( |
| 7134 | path, | 7144 | path, |
| 7135 | "bad ELF OS/ABI ({?s})", | 7145 | "bad ELF OS/ABI ({?s})", |
| 7136 | .{std.enums.tagName(std.elf.OSABI, ident.osabi)}, | 7146 | .{std.enums.tagName(std.elf.OSABI, ident.osabi)}, |
| 7137 | ); | 7147 | ), |
| 7138 | }; | 7148 | }; |
| 7139 | if (ident.abiversion != expect_abiversion) return diags.failParse( | 7149 | if (ident.abiversion != expect_abiversion) return diags.failParse( |
| 7140 | path, | 7150 | path, |