Bug 21330 - dwarf_peel_type() loops infinitely for typedef const struct ...
Summary: dwarf_peel_type() loops infinitely for typedef const struct ...
Status: RESOLVED FIXED
Alias: None
Product: elfutils
Classification: Unclassified
Component: libdw (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-30 02:05 UTC by Kubo Takehiro
Modified: 2017-04-05 14:43 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kubo Takehiro 2017-03-30 02:05:54 UTC
When a type is defined as "typedef const struct foo foo_t", dwarf_peel_type() for foo_t loops infinitely.

  38 int
  39 dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
  40 {
  41   int tag;
  42 
  43   /* Ignore previous errors.  */
  44   if (die == NULL)
  45     return -1;
  46 
  47   *result = *die;
  48   tag = INTUSE (dwarf_tag) (result);
  49   while (tag == DW_TAG_typedef
  50          || tag == DW_TAG_const_type
  51          || tag == DW_TAG_volatile_type
  52          || tag == DW_TAG_restrict_type
  53          || tag == DW_TAG_atomic_type)
  54     {
  55       Dwarf_Attribute attr_mem;
  56       Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (die, DW_AT_type,
  57                                                              &attr_mem);
  58       if (attr == NULL)
  59         return 1;
  60 
  61       if (INTUSE (dwarf_formref_die) (attr, result) == NULL)
  62         return -1;
  63 
  64       tag = INTUSE (dwarf_tag) (result);
  65     }
  ...

dwarf_tag() at line 48 returns DW_TAG_typedef.
dwarf_attr_integrate() and dwarf_formref_die() sets DW_AT_type of die to result.
dwarf_tag() at line 64 returns DW_TAG_const.
dwarf_attr_integrate() and dwarf_formref_die() sets same value to result because the first argument of dwarf_attr_integrate() is unchanged.
dwarf_tag() at line 64 returns same value forever.
Comment 1 Mark Wielaard 2017-03-30 09:29:52 UTC
Oops. That die argument at line 56 to dwarf_attr_integrate () should obviously have been result instead.

This looks like it could never have worked. But there are various testcases that should have caught this. Unfortunately all usages in elfutils itself do dwarf_peel_type (die, die). And that invocation works just fine...
Comment 2 Mark Wielaard 2017-03-30 10:27:43 UTC
Posted a patch:
https://sourceware.org/ml/elfutils-devel/2017-q1/msg00149.html
Comment 3 Mark Wielaard 2017-04-05 14:43:08 UTC
commit f339da994fda25b51cddc3d88182f249b75f89ff
Author: Mark Wielaard <mark@klomp.org>
Date:   Thu Mar 30 12:19:53 2017 +0200

    libdw: Fix dwarf_peel_type infinite loop.
    
    We were calling dwarf_attr_integrate () in the die in the loop instead of
    on the result. Which would cause an infinite loop when die != result.
    Add a testcase that explicitly checks this case.
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=21330
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>