[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Vincent Hamp
I honestly wouldn't know where to start. The wrong branch instructions
were created by an embedded forth compiler. I just tried mem-copying a
single definition containing one of those erroneous branches to some ram
array and then call into it with a pointer. The problem is that the
definition assumes certain preconditions like a register pointing to
forth's stack and all... Without those preconditions calling the
definition immediately hardfaults the core at the very first load
instruction.

After playing around with it for like ~2h I think that's not worth the
trouble. I'm glad the QEMU inconsistency is fixed, let's leave it at
that (I tested with 3.1.0 btw). :)

Thank you for all your trouble.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Fix Released

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Peter Maydell
That sounds odd (and also like it might be a gdb bug, since 'display /i'
is just implemented as memory reads from QEMU's point of view). I can
have a look if you provide repro instructions.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Fix Released

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Peter Maydell
That's great -- thanks for confirming that we've fixed the bug.


** Changed in: qemu
   Status: Incomplete => Fix Released

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Fix Released

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Vincent Hamp
There might still be some issues...

Single-stepping works as long as I don't let GDB display the assembly
with "display/i $pc". Once GDB decodes and displays every instruction
the debugging session gets canceled when I hit the unpredictable branch.
I'm not sure if this has anything to do with QEMU though?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Fix Released

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Vincent Hamp
Jesus... I'm sorry about the delay. Eclipse kept dying on me when
launching gdb so I had to first set up another IDE since I really really
didn't want to single-step through with the command line.

Anyhow. The behavior of QEMU during debugging is now identical to the
one when running it. Even with the unpredictable branch I could step
through the code.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Incomplete

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-28 Thread Peter Maydell
** Changed in: qemu
   Status: New => Incomplete

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  Incomplete

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2019-03-26 Thread Peter Maydell
I think this was probably fixed by commit c2d9644e6d517170b, which was
in QEMU 3.1.0 -- that commit certainly fixes some kinds of crash if
guest code tried to do an UNPREDICTABLE conditional instruction inside
an IT block.

Could you try again with that version of QEMU, or at least provide a
repro case with a command line which demonstrates the problem with
upstream QEMU?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  New

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2018-12-02 Thread Vincent Hamp
Oh damn it, you're right. Apparently encoding T3 of the branch
instruction inside an IT block is always unpredictable... Guess the
inline assembly version ignores the .w extension and creates some other
encoding that simply works.

I've attached the .elf which is causing GDB to halt.

Currently I'm invoking QEMU GNU MCU (some fork with small CortexM extensions) 
with
qemu-system-gnuarmeclipse -S -s -verbose -semihosting-config 
enable=on,target=native -mcu STM32F407VG --image arm_unpredictable_branch.elf

QEMU GNU MCU is currently at version 2.8.0.

But as I mentioned before I've also tried it with 3.0.0 from the ARCH
repository and both versions did the same thing. I think the only
difference is the "--image" option which translates to "--kernel" in the
original.

** Attachment added: "arm_unpredictable_branch.elf"
   
https://bugs.launchpad.net/qemu/+bug/1806243/+attachment/5218154/+files/arm_unpredictable_branch.elf

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  New

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions



[Qemu-devel] [Bug 1806243] Re: ARM conditional branch after if-then instruction not working

2018-12-02 Thread Peter Maydell
The disassembler is giving you a hint here:

2000408e: itt lt
20004090: pushlt {r0, r1}
20004092: blt.w 0x20004082 ; unpredictable  // <-- GDB hangs here

Your code has a "blt" instruction inside an IT block in a way that is
archictecturally UNPREDICTABLE, and the CPU is allowed to not behave in
the way you might expect it to.

Your attempt to reproduce the problem is likely generating different
instructions (specifically probably a different encoding of the branch
instruction).

On the other hand having QEMU behave differently in singlestep mode and
just hang (rather than, say, making the insn UNDEF or treating it as a
condition-failed or a condition-passed) is not ideal.

Do you have a sample binary and QEMU command line that reproduces this?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1806243

Title:
  ARM conditional branch after if-then instruction not working

Status in QEMU:
  New

Bug description:
  Hello

  There seems to be an issue with QEMU when debugging if-then condition
  blocks from the thumb2 instruction set. The following snippet runs
  fine during normal execution, but keeps hanging at the conditional
  branch when debugging. The jump at the branch should only be executed
  as long as $r0 is lower than $r1. Problem is that once both are equal,
  the execution is not continued past the branch and the program counter
  never gets popped.

  2000407a:   push{lr}
  2000407c:   movsr0, r6
  2000407e:   ldmia   r7!, {r1, r6}
  20004080:   push{r0, r1}
  20004082:   str.w   r6, [r7, #-4]!
  20004086:   ldr r6, [sp, #0]
  20004088:   pop {r0, r1}
  2000408a:   addsr0, #1
  2000408c:   cmp r0, r1
  2000408e:   itt lt
  20004090:   pushlt  {r0, r1}
  20004092:   blt.w   0x20004082  ; unpredictable   // <-- GDB hangs 
here
  20004096:   pop {pc}

  I have tried to reproduce the problem with inline assembly but for
  some reason the following example just worked:

  void f() {
static uint8_t stack[256]{};
stack[255] = 4;

asm volatile("\n\t"
 "push{lr}"
 "\n\t"

 // pre-conditions
 "movsr7, %[stack]"
 "\n\t"
 "movsr6, #1"
 "\n\t"

 "movsr0, r6"
 "\n\t"
 "ldmia   r7!, {r1, r6}"
 "\n\t"
 "push{r0, r1}"
 "\n\t"
 "1:"
 "\n\t"
 "str.w   r6, [r7, #-4]!"
 "\n\t"
 "ldr r6, [sp, #0]"
 "\n\t"
 "pop {r0, r1}"
 "\n\t"
 "addsr0, #1"
 "\n\t"
 "cmp r0, r1"
 "\n\t"
 "itt lt"
 "\n\t"
 "pushlt  {r0, r1}"
 "\n\t"

 // Original instruction
 //"blt.w   0x20004082"  //   ; unpredictable 

 // Trying to fake it
 "blt.w   1b"
 "\n\t"

 "pop {pc}"
 "\n\t"
 :
 : [stack] "r"([255]));
  }

  The only real major difference I see to the other code snipped is that
  the inline assembly is running from flash memory where as the original
  code runs in ram? Maybe that's a clue somehow?

  Quickly reading through already reported ARM bugs I think this might be 
related:
  https://bugs.launchpad.net/qemu/+bug/1364501
  At least the symptoms sound identical.

  
  The versions I'm running are:
  QEMU 3.0.0
  arm-none-eabi-gdb 8.2

  I've also captured some trace output for single stepping from the
  pushlt to the blt.w instruction with the trace arguments unimp,
  guest_errors, op, int, exec.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1806243/+subscriptions