This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: DWARF line number table problem when .byte is used for prefix (x86)


On Tue, Aug 31, 2010 at 6:04 PM, Cary Coutant <ccoutant@google.com> wrote:
> In the following test program, which I've reduced from gcc-generated
> code, ".byte 0x66" is used as a nop prefix for the leaq instruction in
> order to pad the TLS GD sequence to make room for a possible linker
> transformation (the exact code sequence, which I've chopped in half
> here, is given in Ulrich's "ELF Handling for Thread-Local Storage"
> document).
>
> ? ? ? ?.file ? "test.cc"
> ? ? ? ?.section ? ? ? ?.debug_abbrev,"",@progbits
> .Ldebug_abbrev0:
> ? ? ? ?.section ? ? ? ?.debug_info,"",@progbits
> .Ldebug_info0:
> ? ? ? ?.section ? ? ? ?.debug_line,"",@progbits
> .Ldebug_line0:
> ? ? ? ?.text
> .Ltext0:
> foo:
> .LFB5133:
> ? ? ? ?.file 1 "test.cc"
> ? ? ? ?.loc 1 41 0
> ? ? ? ?pushq ? %rbp
> .LCFI96:
> ? ? ? ?movq ? ?%rsp, %rbp
> .LCFI97:
> ? ? ? ?pushq ? %rbx
> ? ? ? ?subq ? ?$40, %rsp
> ? ? ? ?movq ? ?%rdi, -40(%rbp)
> .LBB13:
> ? ? ? ?.loc 1 41 0
> ? ? ? ?.byte ? 0x66
> ? ? ? ?leaq ? ?bar@TLSGD(%rip), %rdi
> ? ? ? ?ret
> .LFE5133:
> ? ? ? ?.size ? foo, .-foo
>
> The problem here is that gas assembles this with the line number table
> entry pointing to the byte after the 0x66 instead of the 0x66 itself:
>
> $ objdump -d test.o
> [...]
> 0000000000000000 <foo>:
> ? 0: ? 55 ? ? ? ? ? ? ? ? ? ? ?push ? %rbp
> ? 1: ? 48 89 e5 ? ? ? ? ? ? ? ?mov ? ?%rsp,%rbp
> ? 4: ? 53 ? ? ? ? ? ? ? ? ? ? ?push ? %rbx
> ? 5: ? 48 83 ec 28 ? ? ? ? ? ? sub ? ?$0x28,%rsp
> ? 9: ? 48 89 7d d8 ? ? ? ? ? ? mov ? ?%rdi,-0x28(%rbp)
> ? d: ? 66 48 8d 3d 00 00 00 ? ?lea ? ?0x0(%rip),%rdi ? ? ? ?# 15 <foo+0x15>
> ?14: ? 00
> ?15: ? c3 ? ? ? ? ? ? ? ? ? ? ?retq
>
> $ readelf -wl test.o
> [...]
> ?Line Number Statements:
> ?Extended opcode 2: set Address to 0x0
> ?Advance Line by 40 to 41
> ?Copy
> ?Special opcode 201: advance Address by 14 to 0xe and Line by 0 to 41
> ?Advance PC by 8 to 0x16
> ?Extended opcode 1: End of Sequence
>
> Notice the row at address 0xe, placed just after the 0x66 prefix.
>
> The result of this is that when gdb tries to set a breakpoint just
> after the prologue, it ends up setting the breakpoint in the middle of
> the instruction (because x86 executes the 0x66 as a prefix rather than
> a single-byte NOP).
>
> If I remove the ".byte 0x66" and replace the "leaq" with "word leaq",
> the same object code gets generated, but the line number info is now
> correct:
>
> $ readelf -wl test.o
> [...]
> ?Line Number Statements:
> ?Extended opcode 2: set Address to 0x0
> ?Advance Line by 40 to 41
> ?Copy
> ?Special opcode 187: advance Address by 13 to 0xd and Line by 0 to 41
> ?Advance PC by 9 to 0x16
> ?Extended opcode 1: End of Sequence
>
> Is this a gcc bug or a gas bug (or both)?

It is

http://sourceware.org/bugzilla/show_bug.cgi?id=11802

I think it is a gcc bug.

> We could change i386.md in gcc to use the mnemonic "word" prefix
> instead of ".byte 0x66" (or, alternatively, generate a real 1-byte NOP
> instead of using the prefix byte). Or we could change gas to call
> dwarf2_emit_insn() from cons_worker() to make sure that the location
> information gets processed at the right point.
>
> (Note that the same TLS sequence also uses a ".word 0x6666" prefix
> that probably ought to be changed as well, if we're changing what gcc
> emits. The difference there is that we'll never see a ".loc" opcode
> just before that, so I suspect it'll never actually trigger this
> problem.)
>


-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]