@@ -95,15 +95,30 @@ for my $path (@ARGV) {
9595 my $name_end = index($data, "\0", $name_start);
9696 next if $name_end < 0 || $name_end > $shstr_end;
9797 my $name = substr($data, $name_start, $name_end - $name_start);
98- next unless $name eq ".MIPS.abiflags";
99-
100- my $off = unpack("V", substr($data, $sh + 16, 4));
101- my $size = unpack("V", substr($data, $sh + 20, 4));
102- next if $size < 24 || $off + $size > length($data);
103- substr($data, $off + 7, 1) = "\x01"; # Val_GNU_MIPS_ABI_FP_DOUBLE
104- substr($data, $off + 8, 4) = pack("V", 0); # ISA extension: none
105- substr($data, $off + 12, 4) = pack("V", 0); # ASEs: none
106- substr($data, $off + 16, 4) = pack("V", 1); # FLAGS1: odd single-precision regs
98+
99+ if ($name eq ".MIPS.abiflags") {
100+ my $off = unpack("V", substr($data, $sh + 16, 4));
101+ my $size = unpack("V", substr($data, $sh + 20, 4));
102+ next if $size < 24 || $off + $size > length($data);
103+ substr($data, $off + 7, 1) = "\x01"; # Val_GNU_MIPS_ABI_FP_DOUBLE
104+ substr($data, $off + 8, 4) = pack("V", 0); # ISA extension: none
105+ substr($data, $off + 12, 4) = pack("V", 0); # ASEs: none
106+ substr($data, $off + 16, 4) = pack("V", 1); # FLAGS1: odd single-precision regs
107+ }
108+
109+ if ($name eq ".gnu.attributes") {
110+ my $off = unpack("V", substr($data, $sh + 16, 4));
111+ my $size = unpack("V", substr($data, $sh + 20, 4));
112+ next if $off + $size > length($data);
113+
114+ my $attrs = substr($data, $off, $size);
115+ # GNU MIPS Tag_GNU_MIPS_ABI_FP is encoded as tag 4 followed
116+ # by a small uleb128 value. Clang emits value 2 here while
117+ # the SDK/rustc-compatible .MIPS.abiflags metadata says
118+ # double-float. Keep both metadata sources in sync.
119+ $attrs =~ s/\x04\x02/\x04\x01/g;
120+ substr($data, $off, $size) = $attrs;
121+ }
107122 }
108123 }
109124 }
0 commit comments