Skip to content
  1. Nov 25, 2013
    • David Peixotto's avatar
      ARM integrated assembler generates incorrect nop opcode · 7266731f
      David Peixotto authored
      This patch fixes a bug in the assembler that was causing bad code to
      be emitted.  When switching modes in an assembly file (e.g. arm to
      thumb mode) we would always emit the opcode from the original mode.
      
      Consider this small example:
      
      $ cat align.s
      .code 16
      foo:
        add r0, r0
      .align 3
        add r0, r0
      
      $ llvm-mc -triple armv7-none-linux align.s -filetype=obj -o t.o
      $ llvm-objdump -triple thumbv7 -d t.o
      Disassembly of section .text:
      foo:
             0:       00 44         add     r0, r0
             2:       00 f0 20 e3   blx #4195904
             6:       00 00         movs    r0, r0
             8:       00 44         add     r0, r0
      
      This shows that we have actually emitted an arm nop (e320f000)
      instead of a thumb nop. Unfortunately, this encodes to a thumb
      branch which causes bad things to happen when compiling assembly
      code with align directives.
      
      The fix is to notify the ARMAsmBackend when we switch mode. The
      MCMachOStreamer was already doing this correctly. This patch makes
      the same change for the MCElfStreamer.
      
      There is still a bug in the way nops are emitted for alignment
      because the MCAlignment fragment does not store the correct mode.
      The ARMAsmBackend will emit nops for the last mode it knew about. In
      the example above, we still generate an arm nop if we add a `.code
      32` to the end of the file.
      
      PR18019
      
      llvm-svn: 195677
      7266731f
Loading