rpms/valgrind/F-12 valgrind-3.5.0-dwarf3.patch, NONE, 1.1 valgrind-3.5.0-pr40659.patch, NONE, 1.1 valgrind-3.5.0-ifunc.patch, 1.1, 1.2 valgrind.spec, 1.68, 1.69

Jakub Jelinek jakub at fedoraproject.org
Wed Oct 14 15:03:39 UTC 2009


Author: jakub

Update of /cvs/pkgs/rpms/valgrind/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv30638

Modified Files:
	valgrind-3.5.0-ifunc.patch valgrind.spec 
Added Files:
	valgrind-3.5.0-dwarf3.patch valgrind-3.5.0-pr40659.patch 
Log Message:
3.5.0-3

valgrind-3.5.0-dwarf3.patch:
 d3basics.c      |  320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 debuginfo.c     |   66 ++++++++++-
 priv_d3basics.h |   10 +
 tytypes.c       |    2 
 4 files changed, 385 insertions(+), 13 deletions(-)

--- NEW FILE valgrind-3.5.0-dwarf3.patch ---
--- valgrind/coregrind/m_debuginfo/priv_d3basics.h.jj	2009-10-09 12:52:05.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/priv_d3basics.h	2009-10-13 14:55:12.000000000 +0200
@@ -522,6 +522,9 @@ typedef enum
     DW_OP_form_tls_address = 0x9b,
     DW_OP_call_frame_cfa = 0x9c,
     DW_OP_bit_piece = 0x9d,
+    /* DWARF 4 extensions.  */
+    DW_OP_implicit_value = 0x9e,
+    DW_OP_stack_value = 0x9f,
     /* GNU extensions.  */
     DW_OP_GNU_push_tls_address = 0xe0,
     /* HP extensions.  */
@@ -596,12 +599,13 @@ typedef
 
 /* This describes the result of evaluating a DWARF3 expression.
    GXR_Failure: failed; .word is an asciiz string summarising why
+   GXR_Addr:    evaluated to an address of the object, in .word
    GXR_Value:   evaluated to a value, in .word
    GXR_RegNo:   evaluated to a DWARF3 register number, in .word
 */
 typedef
    struct { 
-      enum { GXR_Failure, GXR_Value, GXR_RegNo } kind;
+      enum { GXR_Failure, GXR_Addr, GXR_Value, GXR_RegNo } kind;
       UWord word;
    }
    GXResult;
@@ -644,6 +648,10 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
    covered by the guard is also ignored. */
 GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di );
 
+/* Compute CFA for IP/SP/FP.  */
+Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp,
+                   Addr min_accessible, Addr max_accessible);
+
 #endif /* ndef __PRIV_D3BASICS_H */
 
 /*--------------------------------------------------------------------*/
--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2009-10-09 12:52:05.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/d3basics.c	2009-10-13 14:54:40.000000000 +0200
@@ -443,7 +443,7 @@ static Bool bias_address( Addr* a, const
 
 
 /* Evaluate a standard DWARF3 expression.  See detailed description in
-   priv_d3basics.h. */
+   priv_d3basics.h.  Doesn't handle DW_OP_piece/DW_OP_bit_piece yet.  */
 GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, 
                                      GExpr* fbGX, RegSummary* regs,
                                      const DebugInfo* di,
@@ -482,8 +482,8 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
    Addr     stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
    GXResult fbval, res;
    Addr     a1;
-   Word     sw1;
-   UWord    uw1;
+   Word     sw1, sw2;
+   UWord    uw1, uw2;
    Bool     ok;
 
    sp = -1;
@@ -568,12 +568,15 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
             switch (fbval.kind) {
                case GXR_Failure:
                   return fbval; /* propagate failure */
-               case GXR_Value:
+               case GXR_Addr:
                   a1 = fbval.word; break; /* use as-is */
                case GXR_RegNo:
                   ok = get_Dwarf_Reg( &a1, fbval.word, regs );
                   if (!ok) return fbval; /* propagate failure */
                   break;
+               case GXR_Value:
+                  FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
+                       "in DW_AT_frame_base");
                default:
                   vg_assert(0);
             }
@@ -599,11 +602,23 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
             a1 += sw1;
             PUSH( a1 );
             break;
+         case DW_OP_bregx:
+            if (!regs)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
+            a1 = 0;
+            uw1 = (UWord)read_leb128U( &expr );
+            if (!get_Dwarf_Reg( &a1, uw1, regs ))
+               FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
+            sw1 = (Word)read_leb128S( &expr );
+            a1 += sw1;
+            PUSH( a1 );
+            break;
          /* As per comment on DW_OP_breg*, the following denote that
             the value in question is in a register, not in memory.  So
             we simply return failure. (iow, the expression is
             malformed). */
          case DW_OP_reg0 ... DW_OP_reg31:
+         case DW_OP_regx:
             FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
                  "whilst evaluating for a value");
             break;
@@ -637,6 +652,297 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
                     "address not valid for client");
             }
             break;
+         case DW_OP_deref_size:
+            POP(uw1);
+            uw2 = *expr++;
+            if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
+                                             VKI_PROT_READ )) {
+               switch (uw2) {
+                 case 1: uw1 = *(UChar*)uw1; break;
+                 case 2: uw1 = *(UShort*)uw1; break;
+                 case 4: uw1 = *(UInt*)uw1; break;
+                 case 8: uw1 = *(ULong*)uw1; break;
+                 default:
+                    FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
+                         "DW_OP_deref_size size");
+               }
+               PUSH(uw1);
+            } else {
+               FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
+                    "address not valid for client");
+            }
+            break;
+         case DW_OP_lit0 ... DW_OP_lit31:
+            PUSH(opcode - DW_OP_lit0);
+            break;
+         case DW_OP_const1u:
+	    uw1 = *expr++;
+	    PUSH(uw1);
+            break;
+         case DW_OP_const2u:
+	    uw1 = *(UShort *)expr;
+	    expr += 2;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_const4u:
+	    uw1 = *(UInt *)expr;
+	    expr += 4;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_const8u:
+	    uw1 = *(ULong *)expr;
+	    expr += 8;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_constu:
+            uw1 = read_leb128U( &expr );
+            PUSH(uw1);
+            break;
+         case DW_OP_const1s:
+	    uw1 = *(Char *) expr;
+	    expr++;
+	    PUSH(uw1);
+            break;
+         case DW_OP_const2s:
+	    uw1 = *(Short *)expr;
+	    expr += 2;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_const4s:
+	    uw1 = *(Int *)expr;
+	    expr += 4;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_const8s:
+	    uw1 = *(Long *)expr;
+	    expr += 8;
+	    PUSH(uw1);
+	    break;
+         case DW_OP_consts:
+            uw1 = read_leb128S( &expr );
+            PUSH(uw1);
+            break;
+         case DW_OP_dup:
+	    POP(uw1);
+	    PUSH(uw1);
+	    PUSH(uw1);
+	    break;
+	 case DW_OP_drop:
+	    POP(uw1);
+	    break;
+         case DW_OP_over:
+            uw1 = 1;
+            goto do_pick;
+	 case DW_OP_pick:
+	    uw1 = *expr++;
+         do_pick:
+            if (sp < (Int) uw1)
+               FAIL("evaluate_Dwarf3_Expr: stack underflow");
+            uw1 = stack[sp - uw1];
+            PUSH(uw1);
+            break;
+         case DW_OP_swap:
+            if (sp < 1)
+               FAIL("evaluate_Dwarf3_Expr: stack underflow");
+            uw1 = stack[sp];
+            stack[sp] = stack[sp - 1];
+            stack[sp - 1] = uw1;
+            break;
+         case DW_OP_rot:
+            if (sp < 2)
+               FAIL("evaluate_Dwarf3_Expr: stack underflow");
+            uw1 = stack[sp];
+            stack[sp] = stack[sp - 1];
+            stack[sp - 1] = stack[sp - 2];
+            stack[sp - 2] = uw1;
+            break;
+         case DW_OP_abs:
+            POP(sw1);
+            if (sw1 < 0)
+               sw1 = -sw1;
+            PUSH(sw1);
+            break;
+         case DW_OP_and:
+            POP(uw2);
+            POP(uw1);
+            uw1 &= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_div:
+            POP(sw2);
+            if (sw2 == 0)
+               FAIL("evaluate_Dwarf3_Expr: division by zero");
+            POP(sw1);
+            sw1 /= sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_minus:
+            POP(uw2);
+            POP(uw1);
+            uw1 -= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_mod:
+            POP(sw2);
+            if (sw2 == 0)
+               FAIL("evaluate_Dwarf3_Expr: division by zero");
+            POP(sw1);
+            sw1 %= sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_mul:
+            POP(uw2);
+            POP(uw1);
+            uw1 *= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_neg:
+            POP(uw1);
+            uw1 = -uw1;
+            PUSH(uw1);
+            break;
+         case DW_OP_not:
+            POP(uw1);
+            uw1 = ~uw1;
+            PUSH(uw1);
+            break;
+         case DW_OP_or:
+            POP(uw2);
+            POP(uw1);
+            uw1 |= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_plus:
+            POP(uw2);
+            POP(uw1);
+            uw1 += uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_shl:
+            POP(uw2);
+            POP(uw1);
+            uw1 <<= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_shr:
+            POP(uw2);
+            POP(uw1);
+            uw1 >>= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_shra:
+            POP(uw2);
+            POP(sw1);
+            sw1 >>= uw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_xor:
+            POP(uw2);
+            POP(uw1);
+            uw1 ^= uw2;
+            PUSH(uw1);
+            break;
+         case DW_OP_le:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 <= sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_lt:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 < sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_ge:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 >= sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_gt:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 > sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_ne:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 != sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_eq:
+            POP(sw2);
+            POP(sw1);
+            sw1 = sw1 == sw2;
+            PUSH(sw1);
+            break;
+         case DW_OP_skip:
+            sw1 = *(Short *)expr;
+            expr += 2;
+            if (sw1 < 0 && expr < limit - exprszB - sw1)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
+            expr += sw1;
+            break;
+         case DW_OP_bra:
+            sw1 = *(Short *)expr;
+            expr += 2;
+            if (sw1 < 0 && expr < limit - exprszB - sw1)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
+            POP(uw1);
+            if (uw1)
+               expr += sw1;
+            break;
+         case DW_OP_nop:
+            break;
+         case DW_OP_call_frame_cfa:
+            if (!regs)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_call_frame_cfa but no reg info");
+            uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
+            if (!uw1)
+               FAIL("evaluate_Dwarf3_Expr: Could not resolve "
+                    "DW_OP_call_frame_cfa");
+            PUSH(uw1);
+            break;
+         case DW_OP_implicit_value:
+            sw1 = (Word)read_leb128S( &expr );
+            uw1 = 0;
+            switch (sw1) {
+               case 1:
+                  uw1 = *(UChar *) expr;
+                  expr += 1;
+                  break;
+               case 2:
+                  uw1 = *(UShort *) expr;
+                  expr += 2;
+                  break;
+               case 4:
+                  uw1 = *(UInt *) expr;
+                  expr += 4;
+                  break;
+               case 8:
+                  uw1 = *(ULong *) expr;
+                  expr += 8;
+                  break;
+               default:
+                  FAIL("evaluate_Dwarf3_Expr: Unhandled "
+                       "DW_OP_implicit_value size");
+            }
+            if (expr != limit)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
+                    "does not terminate expression");
+            res.word = uw1;
+            res.kind = GXR_Value;
+            return res;
+         case DW_OP_stack_value:
+            POP (uw1);
+            res.word = uw1;
+            res.kind = GXR_Value;
+            if (expr != limit)
+               FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
+                    "does not terminate expression");
+            break;
          default:
             if (!VG_(clo_xml))
                VG_(message)(Vg_DebugMsg, 
@@ -650,7 +956,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
 
    vg_assert(sp >= 0 && sp < N_EXPR_STACK);
    res.word = stack[sp];
-   res.kind = GXR_Value;
+   res.kind = GXR_Addr;
    return res;
  
 #  undef POP
@@ -884,7 +1190,7 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
 
    /* Well, we have success.  All subexpressions evaluated, and 
       they all agree.  Hurrah. */
-   res.kind = GXR_Value;
+   res.kind = GXR_Addr;
    res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
    VG_(deleteXA)( results );
    return res;
@@ -896,6 +1202,8 @@ void ML_(pp_GXResult) ( GXResult res )
    switch (res.kind) {
       case GXR_Failure:
          VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
+      case GXR_Addr:
+         VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
       case GXR_Value:
          VG_(printf)("GXR_Value(0x%lx)", res.word); break;
       case GXR_RegNo:
--- valgrind/coregrind/m_debuginfo/debuginfo.c.jj	2009-10-09 12:52:05.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/debuginfo.c	2009-10-13 14:55:45.000000000 +0200
@@ -2003,6 +2003,62 @@ static void cfsi_cache__invalidate ( voi
 }
 
 
+Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp,
+                   Addr min_accessible, Addr max_accessible )
+{
+   Bool       ok;
+   DebugInfo* di;
+   DiCfSI*    cfsi = NULL;
+   Addr       cfa;
+   CfiExprEvalContext eec;
+   UWord hash = ip % N_CFSI_CACHE;
+   CFSICacheEnt* ce = &cfsi_cache[hash];
+
+   if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
+      /* found an entry in the cache .. */
+   } else {
+      /* not found in cache.  Search and update. */
+      ce->ip = ip;
+      find_DiCfSI( &ce->di, &ce->ix, ip );
+   }
+
+   if (UNLIKELY(ce->di == (DebugInfo*)1)) {
+      /* no DiCfSI for this address */
+      return 0;
+   } else {
+      /* found a DiCfSI for this address */
+      di = ce->di;
+      cfsi = &di->cfsi[ ce->ix ];
+   }
+
+   if (UNLIKELY(cfsi == NULL))
+      return 0; /* no info.  Nothing we can do. */
+
+   /* Compute the CFA. */
+   cfa = 0;
+   switch (cfsi->cfa_how) {
+      case CFIC_SPREL: 
+         cfa = cfsi->cfa_off + sp;
+         break;
+      case CFIC_FPREL: 
+         cfa = cfsi->cfa_off + fp;
+         break;
+      case CFIC_EXPR: 
+         eec.ipHere = ip;
+         eec.spHere = sp;
+         eec.fpHere = fp;
+         eec.min_accessible = min_accessible;
+         eec.max_accessible = max_accessible;
+         ok = True;
+         cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
+         if (!ok) return 0;
+         break;
+      default: 
+         vg_assert(0);
+   }
+   return cfa;
+}
+
 /* The main function for DWARF2/3 CFI-based stack unwinding.
    Given an IP/SP/FP triple, produce the IP/SP/FP values for the
    previous frame, if possible. */
@@ -2346,7 +2402,7 @@ static Bool data_address_is_in_var ( /*O
       VG_(printf)("\n");
    }
 
-   if (res.kind == GXR_Value 
+   if (res.kind == GXR_Addr 
        && res.word <= data_addr
        && data_addr < res.word + var_szB) {
       *offset = data_addr - res.word;
@@ -3057,7 +3113,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
    vg_assert(res_sp_6k.kind == res_fp_6k.kind);
    vg_assert(res_sp_6k.kind == res_fp_7k.kind);
 
-   if (res_sp_6k.kind == GXR_Value) {
+   if (res_sp_6k.kind == GXR_Addr) {
       StackBlock block;
       GXResult res;
       UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
@@ -3074,7 +3130,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
          regs.sp = regs.fp = 0;
          regs.ip = ip;
          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
-         tl_assert(res.kind == GXR_Value);
+         tl_assert(res.kind == GXR_Addr);
          if (debug)
          VG_(printf)("   %5ld .. %5ld (sp) %s\n",
                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
@@ -3093,7 +3149,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
          regs.sp = regs.fp = 0;
          regs.ip = ip;
          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
-         tl_assert(res.kind == GXR_Value);
+         tl_assert(res.kind == GXR_Addr);
          if (debug)
          VG_(printf)("   %5ld .. %5ld (FP) %s\n",
                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
@@ -3308,7 +3364,7 @@ void* /* really, XArray* of GlobalBlock 
             res = ML_(evaluate_trivial_GX)( var->gexpr, di );
 
             /* Not a constant address => not interesting */
-            if (res.kind != GXR_Value) {
+            if (res.kind != GXR_Addr) {
                if (0) VG_(printf)("FAIL\n");
                continue;
             }
--- valgrind/coregrind/m_debuginfo/tytypes.c.jj	2009-10-09 12:52:05.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/tytypes.c	2009-10-13 13:52:57.000000000 +0200
@@ -766,7 +766,7 @@ XArray* /*UChar*/ ML_(describe_type)( /*
                   ML_(pp_GXResult)(res);
                   VG_(printf)("\n");
                }
-               if (res.kind != GXR_Value)
+               if (res.kind != GXR_Addr)
                   continue;
                mul = ML_(sizeOfType)( tyents, field->Te.Field.typeR );
                if (mul.b != True)

valgrind-3.5.0-pr40659.patch:
 priv_tytypes.h |    9 ++++++--
 readdwarf3.c   |   24 ++++++++++++++--------
 tytypes.c      |   62 ++++++++++++++++++++++++++++++++++-----------------------
 3 files changed, 61 insertions(+), 34 deletions(-)

--- NEW FILE valgrind-3.5.0-pr40659.patch ---
--- valgrind/coregrind/m_debuginfo/tytypes.c.jj	2009-10-14 15:00:07.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/tytypes.c	2009-10-14 16:28:39.000000000 +0200
@@ -98,10 +98,15 @@ void ML_(pp_TyEnt)( TyEnt* te )
                      te->Te.Atom.value, te->Te.Atom.name);
          break;
       case Te_Field:
-         VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,loc=%p,\"%s\")",
-                     te->Te.Field.typeR, te->Te.Field.nLoc,
-                     te->Te.Field.loc,
-                     te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
+         if (te->Te.Field.nLoc == -1)
+            VG_(printf)("Te_Field(ty=0x%05lx,pos.offset=%ld,\"%s\")",
+                        te->Te.Field.typeR, te->Te.Field.pos.offset,
+                        te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
+         else
+            VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,pos.loc=%p,\"%s\")",
+                        te->Te.Field.typeR, te->Te.Field.nLoc,
+                        te->Te.Field.pos.loc,
+                        te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
          break;
       case Te_Bound:
          VG_(printf)("Te_Bound[");
@@ -476,7 +481,9 @@ Word ML_(TyEnt__cmp_by_all_except_cuOff)
       if (r != 0) return r;
       r = UWord__cmp(te1->Te.Field.nLoc, te2->Te.Field.nLoc);
       if (r != 0) return r;
-      r = Bytevector__cmp(te1->Te.Field.loc, te2->Te.Field.loc,
+      if (te1->Te.Field.nLoc == -1)
+         return Long__cmp(te1->Te.Field.pos.offset, te2->Te.Field.pos.offset);
+      r = Bytevector__cmp(te1->Te.Field.pos.loc, te2->Te.Field.pos.loc,
                           te1->Te.Field.nLoc);
       return r;
    case Te_Bound:
@@ -568,7 +575,8 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te 
          break;
       case Te_Field:
          if (te->Te.Field.name) ML_(dinfo_free)(te->Te.Field.name);
-         if (te->Te.Field.loc) ML_(dinfo_free)(te->Te.Field.loc);
+         if (te->Te.Field.nLoc > 0 && te->Te.Field.pos.loc)
+            ML_(dinfo_free)(te->Te.Field.pos.loc);
          break;
       case Te_Bound:
          break;
@@ -747,24 +755,30 @@ XArray* /*UChar*/ ML_(describe_type)( /*
                field = ML_(TyEnts__index_by_cuOff)(tyents, NULL, fieldR);
                vg_assert(field);
                vg_assert(field->tag == Te_Field);
-               vg_assert(field->Te.Field.loc);
-               vg_assert(field->Te.Field.nLoc > 0);
-               /* Re data_bias in this call, we should really send in
-                  a legitimate value.  But the expression is expected
-                  to be a constant expression, evaluation of which
-                  will not need to use DW_OP_addr and hence we can
-                  avoid the trouble of plumbing the data bias through
-                  to this point (if, indeed, it has any meaning; from
-                  which DebugInfo would we take the data bias? */
-               res = ML_(evaluate_Dwarf3_Expr)(
-                       field->Te.Field.loc, field->Te.Field.nLoc,
-                       NULL/*fbGX*/, NULL/*RegSummary*/,
-                       0/*data_bias*/,
-                       True/*push_initial_zero*/);
-               if (0) {
-                  VG_(printf)("QQQ ");
-                  ML_(pp_GXResult)(res);
-                  VG_(printf)("\n");
+               vg_assert(field->Te.Field.nLoc < 0
+                         || (field->Te.Field.nLoc > 0
+                             && field->Te.Field.pos.loc));
+               if (field->Te.Field.nLoc == -1) {
+                  res.kind = GXR_Addr;
+                  res.word = field->Te.Field.pos.offset;
+               } else {
+                  /* Re data_bias in this call, we should really send in
+                     a legitimate value.  But the expression is expected
+                     to be a constant expression, evaluation of which
+                     will not need to use DW_OP_addr and hence we can
+                     avoid the trouble of plumbing the data bias through
+                     to this point (if, indeed, it has any meaning; from
+                     which DebugInfo would we take the data bias? */
+                   res =  ML_(evaluate_Dwarf3_Expr)(
+                          field->Te.Field.pos.loc, field->Te.Field.nLoc,
+                          NULL/*fbGX*/, NULL/*RegSummary*/,
+                          0/*data_bias*/,
+                          True/*push_initial_zero*/);
+                  if (0) {
+                     VG_(printf)("QQQ ");
+                     ML_(pp_GXResult)(res);
+                     VG_(printf)("\n");
+                  }
                }
                if (res.kind != GXR_Addr)
                   continue;
--- valgrind/coregrind/m_debuginfo/priv_tytypes.h.jj	2009-08-19 15:37:44.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/priv_tytypes.h	2009-10-14 15:49:52.000000000 +0200
@@ -78,8 +78,13 @@ typedef
          struct {
             UChar* name;  /* in mallocville */
             UWord  typeR; /* should be Te_TyXXXX */
-            UChar* loc;   /* location expr, in mallocville */
-            UWord  nLoc;  /* number of bytes in .loc */
+            union {
+               UChar* loc;   /* location expr, in mallocville */
+               Word offset;  /* or offset from the beginning of containing
+                                entity */
+            } pos;
+            Word  nLoc;  /* number of bytes in .pos.loc if >= 0, or -1
+                            if .pos.offset should be used instead */
             Bool   isStruct;
          } Field;
          struct {
--- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj	2009-08-19 15:37:44.000000000 +0200
+++ valgrind/coregrind/m_debuginfo/readdwarf3.c	2009-10-14 16:25:51.000000000 +0200
@@ -2356,9 +2356,16 @@ static void parse_type_DIE ( /*MOD*/XArr
          if (attr == DW_AT_type && ctsSzB > 0) {
             fieldE.Te.Field.typeR = (UWord)cts;
          }
-         if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
+         /* There are 2 different cases for DW_AT_data_member_location.
+            If it is a constant class attribute, it contains byte offset
+            from the beginning of the containing entity.
+            Otherwise it is a location expression.  */
+         if (attr == DW_AT_data_member_location && ctsSzB > 0) {
+            fieldE.Te.Field.nLoc = -1;
+            fieldE.Te.Field.pos.offset = cts;
+         } else if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
             fieldE.Te.Field.nLoc = (UWord)ctsMemSzB;
-            fieldE.Te.Field.loc
+            fieldE.Te.Field.pos.loc
                = ML_(dinfo_memdup)( "di.readdwarf3.ptD.member.2",
                                     (UChar*)(UWord)cts, 
                                     (SizeT)fieldE.Te.Field.nLoc );
@@ -2385,13 +2392,14 @@ static void parse_type_DIE ( /*MOD*/XArr
       vg_assert(fieldE.Te.Field.name);
       if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
          goto bad_DIE;
-      if (fieldE.Te.Field.loc) {
+      if (fieldE.Te.Field.nLoc) {
          if (!parent_is_struct) {
             /* If this is a union type, pretend we haven't seen the data
                member location expression, as it is by definition
                redundant (it must be zero). */
-            ML_(dinfo_free)(fieldE.Te.Field.loc);
-            fieldE.Te.Field.loc  = NULL;
+            if (fieldE.Te.Field.nLoc > 0)
+               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
+            fieldE.Te.Field.pos.loc = NULL;
             fieldE.Te.Field.nLoc = 0;
          }
          /* Record this child in the parent */
@@ -2616,10 +2624,10 @@ static void parse_type_DIE ( /*MOD*/XArr
    /* For union members, Expr should be absent */
    if (0) VG_(printf)("YYYY Acquire Field\n");
    vg_assert(fieldE.tag == Te_Field);
-   vg_assert( (fieldE.Te.Field.nLoc > 0 && fieldE.Te.Field.loc != NULL)
-              || (fieldE.Te.Field.nLoc == 0 && fieldE.Te.Field.loc == NULL) );
+   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
+   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
    if (fieldE.Te.Field.isStruct) {
-      vg_assert(fieldE.Te.Field.nLoc > 0);
+      vg_assert(fieldE.Te.Field.nLoc != 0);
    } else {
       vg_assert(fieldE.Te.Field.nLoc == 0);
    }

valgrind-3.5.0-ifunc.patch:
 coregrind/m_debuginfo/debuginfo.c    |   14 ++-
 coregrind/m_debuginfo/priv_storage.h |    1 
 coregrind/m_debuginfo/readelf.c      |   22 ++++--
 coregrind/m_demangle/demangle.c      |   52 ++++++++++----
 coregrind/m_redir.c                  |  128 +++++++++++++++++++++++++++++++----
 coregrind/m_scheduler/scheduler.c    |    6 +
 coregrind/pub_core_clreq.h           |    5 +
 coregrind/pub_core_demangle.h        |    3 
 coregrind/pub_core_redir.h           |    3 
 coregrind/vg_preloaded.c             |   27 +++++++
 include/pub_tool_debuginfo.h         |    3 
 include/pub_tool_redir.h             |   29 +++++++
 memcheck/mc_replace_strmem.c         |   28 ++++++-
 13 files changed, 276 insertions(+), 45 deletions(-)

Index: valgrind-3.5.0-ifunc.patch
===================================================================
RCS file: /cvs/pkgs/rpms/valgrind/F-12/valgrind-3.5.0-ifunc.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- valgrind-3.5.0-ifunc.patch	12 Oct 2009 15:18:45 -0000	1.1
+++ valgrind-3.5.0-ifunc.patch	14 Oct 2009 15:03:39 -0000	1.2
@@ -1,4 +1,4 @@
-commit 27dc1029d4bca6409d0ed990264592dc75761cd0
+commit 3bd6e2ed7544778a5bbb0acaf69b103d7907185e
 Author: Dodji Seketeli <dodji at redhat.com>
 Date:   Wed Oct 7 16:09:30 2009 +0200
 
@@ -58,7 +58,10 @@ Date:   Wed Oct 7 16:09:30 2009 +0200
     	means once we have intercepted the strlen call by the runtime linker
     	to get the pointer to strlen_target. So we now store the strlen ->
     	vg_strlen redirection request in the iFuncToDirectFuncSet set so that
-    	we can get it later.
+    	we can get it later. For a given ifunc symbol that is loaded, activate
+    	the ifunc --> standard func redirection only if there is a
+    	standard func --> standard func redirection matching the ifunc
+    	symbol.
     	* coregrind/m_scheduler/scheduler.c (do_client_request): Add a new
     	VG_USERREQ__CHANGE_IFUNC_REDIR_TARGET.
     	* coregrind/pub_core_clreq.h (enum Vg_InternalClientRequest): Add
@@ -294,7 +297,7 @@ index 262fcfc..3ae050a 100644
  
        if (sym[i] == '_')
 diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
-index 98a502f..0140fc0 100644
+index 98a502f..cf968bd 100644
 --- a/coregrind/m_redir.c
 +++ b/coregrind/m_redir.c
 @@ -223,6 +223,7 @@ typedef
@@ -305,7 +308,15 @@ index 98a502f..0140fc0 100644
        const HChar** mandatory; /* non-NULL ==> abort V and print the
                                    strings if from_sopatt is loaded but
                                    from_fnpatt cannot be found */
-@@ -268,12 +269,20 @@ typedef
+@@ -252,7 +253,6 @@ typedef
+    to record abovementioned preloaded specifications.) */
+ static TopSpec* topSpecs = NULL;
+ 
+-
+ /*------------------------------------------------------------*/
+ /*--- CURRENTLY ACTIVE REDIRECTIONS                        ---*/
+ /*------------------------------------------------------------*/
+@@ -268,12 +268,20 @@ typedef
        TopSpec* parent_spec; /* the TopSpec which supplied the Spec */
        TopSpec* parent_sym;  /* the TopSpec which supplied the symbol */
        Bool     isWrap;      /* wrap or replacement? */
@@ -327,7 +338,7 @@ index 98a502f..0140fc0 100644
  
  /*------------------------------------------------------------*/
  /*--- FWDses                                               ---*/
-@@ -317,7 +326,7 @@ void generate_and_add_actives (
+@@ -317,7 +325,7 @@ void generate_and_add_actives (
  
  void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
  {
@@ -336,7 +347,7 @@ index 98a502f..0140fc0 100644
     Int          i, nsyms;
     Spec*        specList;
     Spec*        spec;
-@@ -350,10 +359,16 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
+@@ -350,10 +358,16 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
  
     nsyms = VG_(DebugInfo_syms_howmany)( newsi );
     for (i = 0; i < nsyms; i++) {
@@ -357,7 +368,7 @@ index 98a502f..0140fc0 100644
        /* ignore data symbols */
        if (!isText)
           continue;
-@@ -378,6 +393,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
+@@ -378,6 +392,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
        vg_assert(spec->from_fnpatt);
        spec->to_addr = sym_addr;
        spec->isWrap = isWrap;
@@ -365,7 +376,7 @@ index 98a502f..0140fc0 100644
        /* check we're not adding manifestly stupid destinations */
        vg_assert(is_plausible_guest_addr(sym_addr));
        spec->next = specList;
-@@ -388,12 +404,15 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
+@@ -388,12 +403,15 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
  
     if (check_ppcTOCs) {
        for (i = 0; i < nsyms; i++) {
@@ -384,7 +395,7 @@ index 98a502f..0140fc0 100644
           if (!ok)
              /* not a redirect.  Ignore. */
              continue;
-@@ -470,6 +489,38 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
+@@ -470,6 +488,42 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi )
  
  #undef N_DEMANGLED
  
@@ -404,26 +415,30 @@ index 98a502f..0140fc0 100644
 +    old = VG_(OSetGen_Lookup)(activeSet, &old_from);
 +    vg_assert(old);
 +    vg_assert(old->isIFunc);
++    /* We must have got here only if there was an ifunc symbol
++       that matches an active direct function --> direct function
++       redirection. Otherwise, it is not necessary to call this function.  */
++    vg_assert(iFuncToDirectFuncSet);
 +
 +    e = VG_(OSetGen_Lookup)(iFuncToDirectFuncSet, &old_from);
++    /* Same comment as for vg_assert(iFuncToDirectFuncSet) above.  */
++    vg_assert(e);
 +
 +    new = *old;
-+    if (e) {
-+        new.from_addr = new_from;
-+        new.to_addr = e->direct_func;
-+        if (VG_(clo_trace_redir))
-+            VG_(message) (Vg_DebugMsg, "changed redir (%lx)[indired]->(%lx) "
-+                           "to (%lx) -> (%lx))\n",
-+                           old_from, old->to_addr,
-+                           new_from, e->direct_func);
-+        new.isIFunc = False;
-+        maybe_add_active (new);
-+    }
++    new.from_addr = new_from;
++    new.to_addr = e->direct_func;
++    if (VG_(clo_trace_redir))
++        VG_(message) (Vg_DebugMsg, "changed redir (%lx)[indired]->(%lx) "
++                       "to (%lx) -> (%lx))\n",
++                       old_from, old->to_addr,
++                       new_from, e->direct_func);
++    new.isIFunc = False;
++    maybe_add_active (new);
 +}
  
  /* Do one element of the basic cross product: add to the active set,
     all matches resulting from comparing all the given specs against
-@@ -487,7 +538,7 @@ void generate_and_add_actives (
+@@ -487,7 +541,7 @@ void generate_and_add_actives (
       )
  {
     Spec*  sp;
@@ -432,7 +447,7 @@ index 98a502f..0140fc0 100644
     Active act;
     Int    nsyms, i;
     Addr   sym_addr;
-@@ -513,7 +564,7 @@ void generate_and_add_actives (
+@@ -513,7 +567,7 @@ void generate_and_add_actives (
     nsyms = VG_(DebugInfo_syms_howmany)( di );
     for (i = 0; i < nsyms; i++) {
        VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, NULL,
@@ -441,7 +456,7 @@ index 98a502f..0140fc0 100644
  
        /* ignore data symbols */
        if (!isText)
-@@ -533,13 +584,47 @@ void generate_and_add_actives (
+@@ -533,13 +587,61 @@ void generate_and_add_actives (
           if (!sp->mark)
              continue; /* soname doesn't match */
           if (VG_(string_match)( sp->from_fnpatt, sym_name )) {
@@ -450,8 +465,9 @@ index 98a502f..0140fc0 100644
 +            sp->done = True;
 +            if (isIFunc && !sp->isIFunc) {
 +                IFuncToDirectFuncEntry *e;
-+                 /* So we are facing a redirection spec
-+                    indirect function -> direct function.
++                 /* So we are facing an indirect function
++                    that matches a direct function -> direct function
++                    redirection spec.
 +                    We need to store that mapping in iFuncToDirectFuncSet so
 +                    that later once the indirect function's relocations are
 +                    processed by the dynamic linker on the client, we
@@ -478,6 +494,19 @@ index 98a502f..0140fc0 100644
 +                VG_(OSetGen_Insert)(iFuncToDirectFuncSet, e);
 +                continue;
 +            }
++
++            /* Consider special ifunc --> direct function redirections only when
++               there already is an direct function --> direct function
++               redirection that matches an ifunc symbol. Otherwise, we would
++               grow the active set unnecessarily.  */
++            if (isIFunc && sp->isIFunc) {
++                IFuncToDirectFuncEntry *e = NULL;
++                if (iFuncToDirectFuncSet)
++                    e = VG_(OSetGen_Lookup)(iFuncToDirectFuncSet, &sym_addr);
++                if (!e)
++                    continue;
++            }
++
              /* got a new binding.  Add to collection. */
              act.from_addr   = sym_addr;
              act.to_addr     = sp->to_addr;
@@ -559,7 +588,7 @@ index c993c27..025789d 100644
  // Queries
  //--------------------------------------------------------------------
 diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
-index 6f0f049..28e6c7d 100644
+index 6f0f049..41986d2 100644
 --- a/coregrind/vg_preloaded.c
 +++ b/coregrind/vg_preloaded.c
 @@ -68,6 +68,33 @@ void VG_NOTIFY_ON_LOAD(freeres)( void )
@@ -573,8 +602,8 @@ index 6f0f049..28e6c7d 100644
 +   (running on the real CPU) to update the redirection "ifunc -> this function".
 +
 +*/
-+void * VG_WRAP_I_FUNCTION_ZZ(VG_Z_LIBC_SONAME, Za) (void);
-+void * VG_WRAP_I_FUNCTION_ZZ(VG_Z_LIBC_SONAME, Za) (void)
++void * VG_WRAP_I_FUNCTION_ZZ(Za, Za) (void);
++void * VG_WRAP_I_FUNCTION_ZZ(Za, Za) (void)
 +{
 +    OrigFn fn;
 +    Addr result = 0;
@@ -611,7 +640,7 @@ index a02b790..85129ce 100644
  /* A simple enumeration to describe the 'kind' of various kinds of
     segments that arise from the mapping of object files. */
 diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
-index 3d3b516..ff6af2e 100644
+index 3d3b516..ec3e00a 100644
 --- a/include/pub_tool_redir.h
 +++ b/include/pub_tool_redir.h
 @@ -51,6 +51,16 @@
@@ -641,25 +670,29 @@ index 3d3b516..ff6af2e 100644
     characters are transformed.
  
       *         -->  Za    (asterisk)
-@@ -143,6 +154,17 @@
+@@ -143,6 +154,21 @@
       Z         -->  ZZ    (Z)
  
     Everything else is left unchanged.
 +
 +   Indirect function wrapping
-+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++   ~~~~~~~~~~~~~~~~~~~~~~~~~~
 +
 +   VG_WRAP_I_FUNCTION_ZZ is a macro (similar to VG_WRAP_FUNCTION_ZZ) that
-+   wraps functions only. It does not have any effect on regular (STT_FUNC) functions.
-+   Beware, the use of VG_WRAP_I_FUNCTION_ZZ in coregrin/vg_preloaded.c makes
-+   the wrapping function match all the indirect functions of the C library.
-+   So no other use of that macro should be necessary to match
-+   indirect functions of the C library.
++   wraps indirect functions (a.k.a. ifunc) only. It does not have any effect on
++   regular (STT_FUNC) functions. In other words this macros registers an
++   ifunc --> regular function redirection. It does it in a special way though.
++   The ifunc --> regular function redirection is registered iff there is a
++   regular function --> regular function redirection that matches the ifunc symbol
++   pattern of this macro.
++   Beware, the use of VG_WRAP_I_FUNCTION_ZZ in coregrind/vg_preloaded.c makes
++   the wrapping function match all the indirect functions of all libraries.
++   So no other use of that macro should be necessary.
 +
  */
  
  /* If you change these, the code in VG_(maybe_Z_demangle) needs to be
-@@ -158,6 +180,7 @@
+@@ -158,6 +184,7 @@
  
  #define VG_WRAP_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgwZU_,soname,_,fnname)
  #define VG_WRAP_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgwZZ_,soname,_,fnname)
@@ -668,7 +701,7 @@ index 3d3b516..ff6af2e 100644
  /* --------- Some handy Z-encoded names. --------- */
  
 diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c
-index c15717a..2bfe40b 100644
+index c15717a..abd838f 100644
 --- a/memcheck/mc_replace_strmem.c
 +++ b/memcheck/mc_replace_strmem.c
 @@ -116,6 +116,7 @@ Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
@@ -765,3 +798,14 @@ index c15717a..2bfe40b 100644
  STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
  STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
  #elif defined(VGO_darwin)
+@@ -709,7 +725,9 @@ GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
+    }
+ 
+ GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
+-
++#if defined (VGO_linux)
++GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
++#endif
+ 
+ /* glibc variant of strcpy that checks the dest is big enough.
+    Copied from glibc-2.5/debug/test-strcpy_chk.c. */


Index: valgrind.spec
===================================================================
RCS file: /cvs/pkgs/rpms/valgrind/F-12/valgrind.spec,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -p -r1.68 -r1.69
--- valgrind.spec	12 Oct 2009 15:18:45 -0000	1.68
+++ valgrind.spec	14 Oct 2009 15:03:39 -0000	1.69
@@ -1,7 +1,7 @@
 Summary: Tool for finding memory management bugs in programs
 Name: valgrind
 Version: 3.5.0
-Release: 2
+Release: 3
 Epoch: 1
 Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2
 Patch1: valgrind-3.5.0-cachegrind-improvements.patch
@@ -10,6 +10,8 @@ Patch3: valgrind-3.5.0-glibc-2.10.1.patc
 Patch4: valgrind-3.5.0-ifunc.patch
 Patch5: valgrind-3.5.0-inotify-init1.patch
 Patch6: valgrind-3.5.0-mmap-mprotect.patch
+Patch7: valgrind-3.5.0-dwarf3.patch
+Patch8: valgrind-3.5.0-pr40659.patch
 License: GPLv2
 URL: http://www.valgrind.org/
 Group: Development/Debuggers
@@ -69,6 +71,8 @@ or valgrind plugins.
 %patch4 -p1
 %patch5 -p1
 %patch6 -p1
+%patch7 -p1
+%patch8 -p1
 
 %build
 %ifarch x86_64 ppc64
@@ -101,13 +105,6 @@ int main (int argc, char *const argv[])
 EOF
 gcc $RPM_OPT_FLAGS -o close_fds close_fds.c
 
-for i in `find . -type f \( -name *-amd64-linux -o -name *-x86-linux -o -name *-ppc*-linux \)`; do
-  case "`file $i`" in
-    *ELF*executable*statically\ linked*)
-      objcopy -R .debug_loc -R .debug_frame -R .debug_ranges $i
-  esac
-done
-
 # XXX pth_cancel2 hangs on x86_64
 echo 'int main (void) { return 0; }' > none/tests/pth_cancel2.c
 
@@ -161,6 +158,11 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/pkgconfig/*
 
 %changelog
+* Wed Oct 14 2009 Jakub Jelinek <jakub at redhat.com> 3.5.0-3
+- handle many more DW_OP_* ops that GCC now uses
+- handle the more compact form of DW_AT_data_member_location
+- don't strip .debug_loc etc. from valgrind binaries
+
 * Mon Oct 12 2009 Jakub Jelinek <jakub at redhat.com> 3.5.0-2
 - add STT_GNU_IFUNC support (Dodji Seketeli, #518247)
 - wrap inotify_init1 syscall (Dodji Seketeli, #527198)




More information about the fedora-extras-commits mailing list