llvm-objdump disassembling jmp

In creating a test case for a bug fix in llvm-objdump, I noticed that it differs in its output of pc-relative immediates from objdump:

[secdev:/tmp] s$ cat a.s
main:
        jmp .LBL0
.LBL0:
        ret
[secdev:/tmp] s$ llvm-mc -filetype=obj a.s > a.o
[secdev:/tmp] s$ objdump -d a.o |tail -n 2
   0: eb 00 jmp 2 <main+0x2>
   2: c3 retq
[secdev:/tmp] s$ llvm-objdump -d a.o |tail -n 2
       0: eb 00 jmp 0
       2: c3 ret

Is this intended behavior?

As an aside, obj2yaml can't handle this object file:
[secdev:/tmp] s$ ~/build-master/bin/obj2yaml a.o
LLVM ERROR: The end of the file was unexpectedly encountered

In creating a test case for a bug fix in llvm-objdump, I noticed that it
differs in its output of pc-relative immediates from objdump:

[secdev:/tmp] s$ cat a.s
main:
        jmp .LBL0
.LBL0:
        ret
[secdev:/tmp] s$ llvm-mc -filetype=obj a.s > a.o
[secdev:/tmp] s$ objdump -d a.o |tail -n 2
   0: eb 00 jmp 2 <main+0x2>
   2: c3 retq
[secdev:/tmp] s$ llvm-objdump -d a.o |tail -n 2
       0: eb 00 jmp 0
       2: c3 ret

Is this intended behavior?

I haven't looked at the source code but I'm guessing that llvm-objdump is
just being "dumb" in the sense that the disassembly API's probably just
return the imm8 as the raw field value and llvm-objdump is just printing
that, rather than actually interpreting it as an address (relative to the
instruction). In other words, binutils objdump is printing the operand of
the JMP as the address it jumps to, while llvm-objdump is printing the raw
imm8 field value. The binutils behavior is the desirable behavior, because
the semantics of the written operand to a JMP instruction in assembler is
the actual address (usually represented as a symbolic label), not the raw
displacement.

As an aside, obj2yaml can't handle this object file:
[secdev:/tmp] s$ ~/build-master/bin/obj2yaml a.o
LLVM ERROR: The end of the file was unexpectedly encountered

FYI, obj2yaml only handles COFF currently. It should probably diagnose
being fed and ELF file better than dying randomly though.

-- Sean Silva

I haven't looked at the source code but I'm guessing that llvm-objdump is
just being "dumb" in the sense that the disassembly API's probably just
return the imm8 as the raw field value and llvm-objdump is just printing
that, rather than actually interpreting it as an address (relative to the
instruction). In other words, binutils objdump is printing the operand of
the JMP as the address it jumps to, while llvm-objdump is printing the raw
imm8 field value. The binutils behavior is the desirable behavior, because
the semantics of the written operand to a JMP instruction in assembler is
the actual address (usually represented as a symbolic label), not the raw
displacement.

I agree that binutils has more desirable behavior. If I get a chance, I'll take a look at it. I just wanted to make sure that it wasn't intended behavior before I spent time on it.

As an aside, obj2yaml can't handle this object file:
[secdev:/tmp] s$ ~/build-master/bin/obj2yaml a.o
LLVM ERROR: The end of the file was unexpectedly encountered

FYI, obj2yaml only handles COFF currently. It should probably diagnose
being fed and ELF file better than dying randomly though.

Ah, good to know. I think I was trying to use it to produce a test case that I ended up doing by hand.