[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gas/25235] New: Forward-referencing ADR instructions generate wrong

From: max at marrone dot nyc
Subject: [Bug gas/25235] New: Forward-referencing ADR instructions generate wrong offsets in Thumb code
Date: Sat, 30 Nov 2019 02:11:11 +0000


            Bug ID: 25235
           Summary: Forward-referencing ADR instructions generate wrong
                    offsets in Thumb code
           Product: binutils
           Version: 2.31
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gas
          Assignee: unassigned at sourceware dot org
          Reporter: max at marrone dot nyc
  Target Milestone: ---

bx'ing or blx'ing to a Thumb instruction requires the least significant bit of
the address to be set.  When the address of a label is taken with the ADR
instruction, the GNU documentation says that this setting of the least
significant bit happens automatically, provided -mthumb-interwork was passed. 
See https://sourceware.org/binutils/docs/as/ARM-Opcodes.html.

However, despite this guarantee, adr instructions sometimes generates incorrect
offsets that don't have the least significant bit set.

Backward references, assemble into subw instructions that subtract an odd
constant from the pc, as expected.  Forward references assemble into add
instructions that add an even constant to the pc, which is wrong.

I would expect adr to always generate correct addresses, regardless of the
direction.  If the instruction encoding makes that impossible, I would expect
gas to abort with a descriptive error.

There is some discussion of this at

Test case:

    .syntax unified

    .align 2
    .type f1, %function
        b f1

    .align 2
    .type f2, %function
        adr r1, f1
        blx r1
        adr r3, f3
        blx r3

    .align 2
    .type f3, %function
        b f3

Compiling with:

    arm-none-eabi-as -mthumb-interwork TestCase.s

Gives the disassembly (arm-none-eabi-objdump -d):

    00000000 <f1>:
       0:   e7fe        b.n 0 <f1>
       2:   46c0        nop         ; (mov r8, r8)

    00000004 <f2>:
       4:   f2af 0107   subw    r1, pc, #7  ; <-- Note odd offset, as expected.
       8:   4788        blx r1
       a:   a301        add r3, pc, #4  ; (adr r3, 10 <f3>) <-- Note even
(wrong) offset.
       c:   4798        blx r3
       e:   46c0        nop         ; (mov r8, r8)

    00000010 <f3>:
      10:   e7fe        b.n 10 <f3>
      12:   46c0        nop         ; (mov r8, r8)

Version I tested with:

    GNU assembler (GNU Tools for Arm Embedded Processors 8-2018-q4-major)

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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]