Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: Tristan Gingold <gingold@adacore.com>
Cc: Joel Brobecker <brobecker@adacore.com>, gdb-patches@sourceware.org
Subject: Re: [RFA/commit+doco 2/2] Windows x64 SEH unwinder.
Date: Wed, 09 Jan 2013 17:10:00 -0000	[thread overview]
Message-ID: <50EDA48E.2030406@redhat.com> (raw)
In-Reply-To: <9E84DF2D-7AF8-4AA1-A5DF-171EF189A6E7@adacore.com>

On 01/09/2013 04:28 PM, Tristan Gingold wrote:

>>> I don't really see a real way of supporting both old and new versions
>>> of GCC, unless we have a way of more finely ordering the unwinders.
>>
>> What specific finer order where you considering would be needed to
>> fix this?
> 
> Joel once proposed to activate this unwinder if the CU is compiled
> by gcc 4.6 or older.

I don't think you need to have a way of more finely ordering
the unwinders for that.  AFAICS, we can make the sniffer
return false in that case.  I had understood him
as meaning something about making the whole prepend/append
mechanisms more finer grained somehow.

Checking the CU/producer is kind of the obvious choice.
It requires debug info though.

>> Maybe detect if the whole module (exe/dll) the PC points at
>> contains any SEH (even if not for PC), and skip the SEH unwinder
>> if not?  Is that possible?
> 
> Yes, but useless.  There are SEH info in crt0.

You mean, the parts that are in mingw, right?  I'd assume
any bits in gcc to only contain SEH in >=4.7.  Yeah,
seems like that wouldn't work for static binaries.

>>> +     http://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
>>> +     Furthermore, according to RtlVirtualUnwind, the complete list of
>>> +     epilog marker is:
>>> +     - ret                      [c3]
>>> +     - ret n                    [c2 imm16]
>>> +     - rep ret                  [f3 c3]
>>> +     - jmp imm8 | imm32         [eb rel8] or [e9 rel32]
>>> +     - jmp qword ptr imm32                 - not handled
>>> +     - rex jmp reg              [4X ff eY]
>>> +     I would add:
>>> +     -  pop reg                 [41 58-5f] or [58-5f]
>>
>> If you add "pop", and you'd add "add" and "lea" as well,
>> right?  It's not super clear what "marker" means, but all
>> the instructions listed by RtlVirtualUnwind's docs are
>> control flow instructions.  And then, in the url you point
>> above, we see:
>>
>> "These are the only legal forms for an epilog. It must consist of either
>> an add RSP,constant or lea RSP,constant[FPReg], followed by a series
>> of zero or more 8-byte register pops and a return or a jmp. (Only
>> a subset of jmp statements are allowable in the epilog."
>>
>> So from both docs it seems to me that "marker" is always the
>> last instruction of the epilogue, and that "pop" is not called
>> a marker.
> 
> This is in fact an optimization. If we found a pop, followed by
> an epilog marker, there is not need to decode unwind info.

I don't understand.  pops will always be followed by a marker.
How can that be an optimization?

> 
>> Furthermore,
>>
>>> +
>>> +     We don't care about the instruction deallocating the frame:
>>> +     if it hasn't been executed, we can safely decode the insns;
>>> +     if it has been executed, the following epilog decoding will
>>> +     work.  */
>>> +  CORE_ADDR pc = cache->pc;
>>> +  CORE_ADDR cur_sp = cache->sp;
>>> +  struct gdbarch *gdbarch = get_frame_arch (this_frame);
>>> +  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>>> +
>>> +  while (1)
>>> +    {
>>> +      gdb_byte op;
>>> +      gdb_byte rex;
>>> +
>>> +      if (target_read_memory (pc, &op, 1) != 0)
>>> +	return -1;
>>> +
>>> +      if (op == 0xc3)
>>> +	{
>>> +	  /* Ret.  */
>>> +	  cache->prev_rip_addr = cur_sp;
>>> +	  cache->prev_sp = cur_sp + 8;
>>> +	  return 1;
>>> +	}
>>> +      else if (op == 0xeb)
>>> +	{
>>> +	  /* jmp rel8  */
>>> +	  gdb_byte rel8;
>>> +
>>> +	  if (target_read_memory (pc + 1, &rel8, 1) != 0)
>>> +	    return -1;
>>> +	  pc = pc + 2 + (signed char) rel8;
>>
>> this implementation follows jumps, and keeps looping
>> at the jump destination.
> 
> Right.
> 
>>  I see no hint that such thing
>> as an epilogue with a jump is a valid epilogue, only that
>> a jmp is only valid as replacement for ret.
>> Can you show an example where following the jmp until
>> you see a ret is necessary?
> 
> Interesting remark. First attempt to answer is the case of a
> jump to an epilogue.

The jump to an epilogue would not be part of the epilogue.

> But I may miss your point.

My point is that the docs say the epilogue has this rigid
format that always ends in a marker, and that a marker is
a ret or a jmp (therefore calling "pop" a marker as in the
"I would add" comment seems to me misleading).  The code
continues following the jmp, so it makes me believe the code
is erroneously decoding something after the jmp that is
not an epilogue (the caller or perhaps a tailcall).

-- 
Pedro Alves


  reply	other threads:[~2013-01-09 17:10 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-09 10:53 Add Windows x64 SEH unwinder (take 2) Joel Brobecker
2013-01-09 10:53 ` [RFA/commit+NEWS 1/2] Add command set/show debug unwind Joel Brobecker
2013-01-09 12:41   ` Jan Kratochvil
2013-01-09 18:40     ` Joel Brobecker
2013-01-09 15:14   ` Tom Tromey
2013-01-09 16:01   ` Eli Zaretskii
2013-01-09 10:53 ` [RFA/commit+doco 2/2] Windows x64 SEH unwinder Joel Brobecker
2013-01-09 15:52   ` Pedro Alves
2013-01-09 16:28     ` Tristan Gingold
2013-01-09 17:10       ` Pedro Alves [this message]
2013-01-09 17:53         ` Tom Tromey
2013-01-09 19:11           ` Pedro Alves
2013-01-09 20:07         ` Tristan Gingold
2013-01-10 16:24           ` Pedro Alves
2013-01-11  8:04             ` Tristan Gingold
2013-07-08 10:55             ` [RFA] Windows x64 SEH unwinder (v2) Tristan Gingold
2013-07-26 15:22               ` Pedro Alves
2013-08-19 13:59                 ` Tristan Gingold
2013-08-19 14:13                   ` Pedro Alves
2013-08-22  9:33                 ` [PATCH v3] Windows x64 SEH unwinder Tristan Gingold
2013-08-22 15:10                   ` Eli Zaretskii
2013-08-22 15:26                   ` Pedro Alves
2013-08-22 15:41                     ` Tristan Gingold
2013-08-22 16:15                       ` Pedro Alves
2013-08-23  6:54                         ` Tristan Gingold
2013-08-27 17:45                           ` Pedro Alves
2013-09-02  9:28                             ` Tristan Gingold
2013-01-09 16:06   ` [RFA/commit+doco 2/2] " Eli Zaretskii
2013-01-09 16:29     ` Tristan Gingold
2013-01-09 11:05 ` Add Windows x64 SEH unwinder (take 2) Pedro Alves
2013-01-09 11:11   ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50EDA48E.2030406@redhat.com \
    --to=palves@redhat.com \
    --cc=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=gingold@adacore.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox