https://sourceware.org/bugzilla/show_bug.cgi?id=34756

            Bug ID: 34756
           Summary: x86: far jmp/call with a constant offset wider than 32
                    bits is silently truncated
           Product: binutils
           Version: 2.48 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gas
          Assignee: unassigned at sourceware dot org
          Reporter: martin.mirchev at u dot nus.edu
  Target Milestone: ---

In 32-bit code, a direct far jump or call whose constant offset does not fit
in 32 bits is assembled with the offset silently truncated, with no warning
or error. The 16-bit form is diagnosed ("16-bit jump out of range"), and an
oversized immediate in other instructions gets a "shortened" warning.

$ cat far.s
        .code32
        ljmp    $0x10, $0x123456789
        lcall   $0x10, $0x100000000
$ as --32 far.s -o far.o && objdump -d far.o
   0:   ea 89 67 45 23 10 00    ljmp   $0x10,$0x23456789
   7:   9a 00 00 00 00 10 00    lcall  $0x10,$0x0

For comparison:
        .code16
        ljmp    $0x10, $0x123456      -> Error: 16-bit jump out of range
        .code32
        mov     $0x123456789, %eax    -> Warning: 0x123456789 shortened to
0x23456789

Cause: output_interseg_jump() in gas/config/tc-i386.c only range-checks the
constant offset when size == 2; for size == 4 it is passed straight to
md_number_to_chars().

Suggested fix (mirrors the existing 16-bit check):

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -12115,6 +12115,13 @@
          as_bad (_("16-bit jump out of range"));
          return;
        }
+      if (size == 4
+         && !fits_in_unsigned_long (n)
+         && !fits_in_signed_long (n))
+       {
+         as_bad (_("32-bit jump out of range"));
+         return;
+       }
       md_number_to_chars (p, n, size);
     }
   else

With the patch both lines above are rejected, in-range offsets are
unchanged, and assembling every gas/testsuite/gas/i386/*.s with --32 and
--64 produces identical objects and diagnostics to the unpatched assembler.

Seen with binutils 2.47; the same code is present on current master.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified
manually.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to