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

            Bug ID: 32705
           Summary: RISC-V: objdump prints .insn due to incorrect $x
                    mapping symbol handling
           Product: binutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: andrewoates at gmail dot com
  Target Milestone: ---

Symptom: objdump will fail to decode instructions when disassembling a file
generated by LLVM that mixes architecture strings between sections.  This can
result in many ".insn" lines.

Root cause: LLVM emits "$x" mapping symbols to signal transitions from a custom
architecture string (such as one that does not include the "c" extension) back
to the default.  When objdump sees a bare "$x" (as opposed to a "$xrv..." that
includes the architecture string), it does not actually reset to the ELF file
default.  This causes subsequent instructions to be decoded based on whatever
the last-seen architecture string was.

AFAICT, gas will never emit object files like this, because it always emits a
full mapping string ("$xrv...") at the start of each section (see
gas/config/tc-riscv.c:624 [1]).  LLVM's assembler will, however. 
Alternatively, it's possible this is a strange interaction between LLVM's
output and ld when linking gas-generated and LLVM-generated object files
together --- but I think this is really an objdump bug.

I have a patch prepared to fix this, but filing the bug for reference.  I'm
still working on a test case (which has to have a binary object file,
unfortunately, as gas won't generate a symbol sequence that triggers this bug).

Simple test case:

$ cat asm.s
.attribute arch, "rv64i"
.section .text, "ax"
addi    a0, zero, 1             # $xrv64i

$ cat test.c
int func(int x) { return x + 1; }

$ ../gas/as-new -o /tmp/test.o asm.s
$ clang -c -O1 -target riscv64 -o /tmp/test2.o test.c

$ ../ld/ld-new /tmp/test.o /tmp/test2.o -o /tmp/linked.o
../ld/ld-new: warning: cannot find entry symbol _start; defaulting to
00000000000100e8

$ ../binutils/objdump -d /tmp/linked.o| less                                   
                        fix-riscv-objdump () U

/tmp/linked.o:     file format elf64-littleriscv


Disassembly of section .text:

00000000000100e8 <func-0x4>:
   100e8:       00100513                li      a0,1

00000000000100ec <func>:
   100ec:       2505                    .insn   2, 0x2505
   100ee:       8082                    .insn   2, 0x8082

If you alter asm.s to say "rv64ic", then you get the expected disassembly at
the end:
00000000000100ec <func>:
   100ec:       2505                    addiw   a0,a0,1
   100ee:       8082                    ret


[1]
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/config/tc-riscv.c;h=493c393f5b2730fe8f841da074fa106d655ec9a7;hb=HEAD#l624

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

Reply via email to