This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

[patch] Fix for PIE with both -e and --core in use


Hi Roland,

jankratochvil/pie-core

it was already self-discussed at the bottom of "[API RFC] unwinder".

To load a PIE executable together with a core file one cannot relocate the
executable to the proper VMA.

Shared libraries are located by Dwfl_Callbacks->find_elf which will put them
proper displacement.  But the main executable is only specified via
--executable and one cannot easily associate it to the proper core segment.

(It may get associated via build-id but build-id does not have to be available
etc.)

With --core=X --executable=Y order one gets:
0x7ff2cfe9b000  0x7ff2d009c000  [pie]
0x200000        0x400ac0
where the second entry is not relocated.

Similarly it looks for the order --executable=Y --core=X:
0x200000        0x400ac0
0x7ff2cfe9b000  0x7ff2d009c000  [pie]

In both cases the main executable symbols are based at address 0x200000 while
we need them at address 0x7ff2cfe9b000.

The parse_opt diff below has many whitespace changes, one can use -w:
	git diff origin/master..origin/jankratochvil/pie-core -w libdwfl/argp-std.c


Thanks,
Jan


commit d01e339994eb1be65017eaf2f7fff8b77f3ff1f3
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Thu Oct 18 00:11:30 2012 +0200

    libdwfl/
    2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
    
    	* argp-std.c (offline_find_elf): New function.
    	(offline_callbacks): Use it for FIND_ELF.
    	(struct parse_opt): New.
    	(parse_opt): New KEY ARGP_KEY_INIT.  In other make HOOK struct
    	parse_opt pointer from former Dwfl pointer.  Delay 'e and OPT_COREFILE
    	processing till ARGP_KEY_SUCCESS.  Initialize state->INPUT already from
    	ARGP_KEY_SUCCESS.  Modify the cleanup in ARGP_KEY_ERROR.  Make the final state->INPUT initialization optional.
    	* libdwfl.h (dwfl_standard_argp): Extend the comment for USERDATA.
    
    tests/
    2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
    
    	* run-addrname-test.sh: New test for PIE relocation.
    	* testfile70.core.bz2: New file.
    	* testfile70.exec.bz2: New file.
    
    Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index bdd9440..3919973 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,16 @@
 2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
+	* argp-std.c (offline_find_elf): New function.
+	(offline_callbacks): Use it for FIND_ELF.
+	(struct parse_opt): New.
+	(parse_opt): New KEY ARGP_KEY_INIT.  In other make HOOK struct
+	parse_opt pointer from former Dwfl pointer.  Delay 'e and OPT_COREFILE
+	processing till ARGP_KEY_SUCCESS.  Initialize state->INPUT already from
+	ARGP_KEY_SUCCESS.  Modify the cleanup in ARGP_KEY_ERROR.  Make the final state->INPUT initialization optional.
+	* libdwfl.h (dwfl_standard_argp): Extend the comment for USERDATA.
+
+2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
 	* dwfl_module_getdwarf.c (mod_verify_build_id): New function with code
 	from ...
 	(__libdwfl_getelf): ... here.  Call it.
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
index 2ef4555..f0c530f 100644
--- a/libdwfl/argp-std.c
+++ b/libdwfl/argp-std.c
@@ -60,6 +60,27 @@ static const struct argp_option options[] =
   { NULL, 0, NULL, 0, NULL, 0 }
 };
 
+/* Wrapper to provide proper FILE_NAME for -e|--executable.  */
+static int
+offline_find_elf (Dwfl_Module *mod, void **userdata, const char *modname,
+		  Dwarf_Addr base, char **file_name, Elf **elfp)
+{
+  if (modname != NULL && (strcmp (modname, "[exe]") == 0
+			  || strcmp (modname, "[pie]") == 0)
+      && *userdata)
+    {
+      char *e_dup = strdup (*userdata);
+      if (e_dup)
+	{
+	  free (*file_name);
+	  *file_name = e_dup;
+	  return -1;
+	}
+    }
+  return INTUSE(dwfl_build_id_find_elf) (mod, userdata, modname, base,
+                                         file_name, elfp);
+}
+
 static char *debuginfo_path;
 
 static const Dwfl_Callbacks offline_callbacks =
@@ -70,7 +91,7 @@ static const Dwfl_Callbacks offline_callbacks =
     .section_address = INTUSE(dwfl_offline_section_address),
 
     /* We use this table for core files too.  */
-    .find_elf = INTUSE(dwfl_build_id_find_elf),
+    .find_elf = offline_find_elf,
   };
 
 static const Dwfl_Callbacks proc_callbacks =
@@ -90,6 +111,16 @@ static const Dwfl_Callbacks kernel_callbacks =
     .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
   };
 
+/* Structure held at state->HOOK.  */
+struct parse_opt
+{
+  Dwfl *dwfl;
+  /* The -e|--executable parameter.  */
+  const char *e;
+  /* The --core parameter.  */
+  const char *core;
+};
+
 static error_t
 parse_opt (int key, char *arg, struct argp_state *state)
 {
@@ -111,152 +142,142 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
   switch (key)
     {
+    case ARGP_KEY_INIT:
+      {
+	assert (state->hook == NULL);
+	struct parse_opt *opt = calloc (1, sizeof (*opt));
+	if (opt == NULL)
+	  failure (NULL, DWFL_E_ERRNO, "calloc");
+	state->hook = opt;
+      }
+      break;
+
     case OPT_DEBUGINFO:
       debuginfo_path = arg;
       break;
 
     case 'e':
       {
-	Dwfl *dwfl = state->hook;
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
 	if (dwfl == NULL)
 	  {
 	    dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
 	    if (dwfl == NULL)
 	      return fail (dwfl, -1, arg);
-	    state->hook = dwfl;
+	    opt->dwfl = dwfl;
 
 	    /* Start at zero so if there is just one -e foo.so,
 	       the DSO is shown without address bias.  */
 	    dwfl->offline_next_address = 0;
 	  }
-	if (dwfl->callbacks == &offline_callbacks)
-	  {
-	    if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
-	      return fail (dwfl, -1, arg);
-	    state->hook = dwfl;
-	  }
-	else
+	if (dwfl->callbacks != &offline_callbacks)
 	  {
 	  toomany:
 	    argp_error (state, "%s",
 			_("only one of -e, -p, -k, -K, or --core allowed"));
 	    return EINVAL;
 	  }
+	opt->e = arg;
       }
       break;
 
     case 'p':
-      if (state->hook == NULL)
-	{
-	  Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
-	  int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
-	  if (result != 0)
-	    return fail (dwfl, result, arg);
-	  state->hook = dwfl;
-	}
-      else
-	goto toomany;
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+	    int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
+	    if (result != 0)
+	      return fail (dwfl, result, arg);
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
       break;
 
     case 'M':
-      if (state->hook == NULL)
-	{
-	  FILE *f = fopen (arg, "r");
-	  if (f == NULL)
-	  nofile:
-	    {
-	      int code = errno;
-	      argp_failure (state, EXIT_FAILURE, code,
-			    "cannot open '%s'", arg);
-	      return code;
-	    }
-	  Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
-	  int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
-	  fclose (f);
-	  if (result != 0)
-	    return fail (dwfl, result, arg);
-	  state->hook = dwfl;
-	}
-      else
-	goto toomany;
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    FILE *f = fopen (arg, "r");
+	    if (f == NULL)
+	    nofile:
+	      {
+		int code = errno;
+		argp_failure (state, EXIT_FAILURE, code,
+			      "cannot open '%s'", arg);
+		return code;
+	      }
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+	    int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
+	    fclose (f);
+	    if (result != 0)
+	      return fail (dwfl, result, arg);
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
       break;
 
     case OPT_COREFILE:
       {
-	Dwfl *dwfl = state->hook;
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
 	if (dwfl == NULL)
-	  state->hook = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	  opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
 	/* Permit -e and --core together.  */
 	else if (dwfl->callbacks != &offline_callbacks)
 	  goto toomany;
-
-	int fd = open64 (arg, O_RDONLY);
-	if (fd < 0)
-	  goto nofile;
-
-	Elf *core;
-	Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
-	if (error != DWFL_E_NOERROR)
-	  {
-	    argp_failure (state, EXIT_FAILURE, 0,
-			  _("cannot read ELF core file: %s"),
-			  INTUSE(dwfl_errmsg) (error));
-	    return error == DWFL_E_ERRNO ? errno : EIO;
-	  }
-
-	int result = INTUSE(dwfl_core_file_report) (dwfl, core);
-	if (result < 0)
-	  {
-	    elf_end (core);
-	    close (fd);
-	    return fail (dwfl, result, arg);
-	  }
-
-	/* From now we leak FD and CORE.  */
-
-	if (result == 0)
-	  {
-	    argp_failure (state, EXIT_FAILURE, 0,
-			  _("No modules recognized in core file"));
-	    return ENOENT;
-	  }
+	opt->core = arg;
       }
       break;
 
     case 'k':
-      if (state->hook == NULL)
-	{
-	  Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
-	  int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
-	  if (result != 0)
-	    return fail (dwfl, result, _("cannot load kernel symbols"));
-	  result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
-	  if (result != 0)
-	    /* Non-fatal to have no modules since we do have the kernel.  */
-	    failure (dwfl, result, _("cannot find kernel modules"));
-	  state->hook = dwfl;
-	}
-      else
-	goto toomany;
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
+	    int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
+	    if (result != 0)
+	      return fail (dwfl, result, _("cannot load kernel symbols"));
+	    result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+	    if (result != 0)
+	      /* Non-fatal to have no modules since we do have the kernel.  */
+	      failure (dwfl, result, _("cannot find kernel modules"));
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
       break;
 
     case 'K':
-      if (state->hook == NULL)
-	{
-	  Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
-	  int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
-								 NULL);
-	  if (result != 0)
-	    return fail (dwfl, result, _("cannot find kernel or modules"));
-	  state->hook = dwfl;
-	}
-      else
-	goto toomany;
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	    int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
+								   NULL);
+	    if (result != 0)
+	      return fail (dwfl, result, _("cannot find kernel or modules"));
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
       break;
 
     case ARGP_KEY_SUCCESS:
       {
-	Dwfl *dwfl = state->hook;
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
 
 	if (dwfl == NULL)
 	  {
@@ -265,7 +286,56 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	    dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
 	    if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
 	      return fail (dwfl, -1, arg);
-	    state->hook = dwfl;
+	    opt->dwfl = dwfl;
+	  }
+
+	if (opt->core)
+	  {
+	    int fd = open64 (opt->core, O_RDONLY);
+	    if (fd < 0)
+	      goto nofile;
+
+	    Elf *core;
+	    Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
+	    if (error != DWFL_E_NOERROR)
+	      {
+		argp_failure (state, EXIT_FAILURE, 0,
+			      _("cannot read ELF core file: %s"),
+			      INTUSE(dwfl_errmsg) (error));
+		return error == DWFL_E_ERRNO ? errno : EIO;
+	      }
+
+	    int result = INTUSE(dwfl_core_file_report) (dwfl, core);
+	    if (result < 0)
+	      {
+		elf_end (core);
+		close (fd);
+		return fail (dwfl, result, opt->core);
+	      }
+
+	    /* From now we leak FD and CORE.  */
+
+	    if (result == 0)
+	      {
+		argp_failure (state, EXIT_FAILURE, 0,
+			      _("No modules recognized in core file"));
+		return ENOENT;
+	      }
+
+	    if (opt->e)
+	      for (Dwfl_Module *mod = dwfl->modulelist; mod; mod = mod->next)
+		{
+		  if (mod->name == NULL
+		      || (strcmp (mod->name, "[exe]") != 0
+			  && strcmp (mod->name, "[pie]") != 0))
+		    continue;
+		  mod->userdata = (void *) opt->e;
+		}
+	  }
+	else if (opt->e)
+	  {
+	    if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL)
+	      return fail (dwfl, -1, arg);
 	  }
 
 	/* One of the three flavors has done dwfl_begin and some reporting
@@ -274,12 +344,22 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
 	int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
 	assert (result == 0);
+
+	/* Update the input all along, so a parent parser can see it.
+	   As we free OPT the update below will be no longer active.  */
+	*(Dwfl **) state->input = dwfl;
+	free (opt);
+	state->hook = NULL;
       }
       break;
 
     case ARGP_KEY_ERROR:
-      dwfl_end (state->hook);
-      state->hook = NULL;
+      {
+	struct parse_opt *opt = state->hook;
+	dwfl_end (opt->dwfl);
+	free (opt);
+	state->hook = NULL;
+      }
       break;
 
     default:
@@ -287,7 +367,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
     }
 
   /* Update the input all along, so a parent parser can see it.  */
-  *(Dwfl **) state->input = state->hook;
+  struct parse_opt *opt = state->hook;
+  if (opt)
+    *(Dwfl **) state->input = opt->dwfl;
+
   return 0;
 }
 
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 000d582..8498c0c 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -364,7 +364,8 @@ extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
 				     const char *module_name, Dwarf_Addr base,
 				     char **file_name, Elf **);
 
-/* Standard argument parsing for using a standard callback set.  */
+/* Standard argument parsing for using a standard callback set.
+   Field Dwfl_Module->USERDATA is reserved for "[exe]" or "[pie]" modules.  */
 struct argp;
 extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const));
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9e8ad2c..b9674cc 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
 2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
+	* run-addrname-test.sh: New test for PIE relocation.
+	* testfile70.core.bz2: New file.
+	* testfile70.exec.bz2: New file.
+
+2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
 	* run-addrname-test.sh: New test for DSO with build-id bias.
 	* testfile69.core.bz2: New file.
 	* testfile69.so.bz2: New file.
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index cc8aa33..99abf9d 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -306,4 +306,14 @@ libglobal+0x9
 ??:0
 EOF
 
+testfiles testfile70.exec testfile70.core
+testrun_compare ../src/addr2line -S -e testfile70.exec --core=testfile70.core 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+testrun_compare ../src/addr2line -S --core=testfile70.core -e testfile70.exec 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+
 exit 0
diff --git a/tests/testfile70.core.bz2 b/tests/testfile70.core.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..6c47c6d45b2ba29d6956cedc43d60c48e77e16be
GIT binary patch
literal 2739
zcmV;k3QYAvT4*^jL0KkKSw1<bdjJxwfB*mg_x}I?|9}7W|4;w_|NhVa-_h0XU)}A(
z;@n>U|9jvHp8x;=00000000040ia|6G|*_s0077hG#NAufB*mtj79`88UO}?pwQ3(
zpaz)+fB*)7fHVw%2AT~S000>Qrh_JdkN^Myk%+*CBR~MqG#VNJGyu~e&;S6?5C(ye
z0MkLEAOHg(G|*(wG5`PoGBFqs#ApB-27^OD27nr58UO$q0szo502*jCWB>qU2AT|-
z20#D+21X+S7>xh}K+tGt0MG+WgFpZSKtLJ>Km$z%jDP?PfYU*fK*#_90La8(LlK|=
zXc`R-02%;kkZ1q^XaQ72ARqy#(?s+pYGN}~^b-(a)wPh~X3YI&k*kv6BbC#Fn?sK{h#
zrkI8yJrmMt=mdIcnomfX83vjjk)tLIiR3$#tEl^azh!0}+Va}At9&*GnzcmA>RPch
z?cM_^y^O^6NoOR7f|e_354(a)LCem4;j#bk^%$%8gcD{QeVwlP}2p1S?}MJ6w*q)erP
zi!M^twOMVJQpVLqv{LozU2W^tu~<s$$*Rkve7ViALfP%`I>$!Ay|KUJeO{+^m!p`!
znHQczp=rlwhK*Talq$<<x6E<QGBRMnxzBrU9?^xDfwbY$c4?mtzO$&)zFnukQyZVb
z&2z1m?(^_uR`c=WZSPMFdi9f(%%?u8n~sOYSiPv;Q(lu}6|L5WK8oGTq|MM-X9bs^
zl%mOK@%`5m65|GIL*x{gMU_)(xmG5UE~6d|_XC>2e}SW?p|P=-)!<uMrb&%m9M;{I
zYifGtn&s=YGB((1x#cE3OZO{!W5B^k%uFNrP5FXC2vSiH7wX~hzJELP{*GLIT#N`K
zcb7A%tD!b8+=z&Yd%vC1tVBdY^77?ee;-ke*DZ*P(8j)^RVYN(a)Ybr{y9cJo?MRzvd
zSrG1bYC;<FgPcxVMcqCU$iv#cBi+1Jr!9q)`0F8*u}H$(vz2y<zLPp-CgFPRES&<y
z7cWT|(-ysYj<IeAy2>Z$C54)?DxMP6s<0(82t--&IohUBwqM|wf-5jpIkU!0A|fo2
z1WbZu5SfUwVHA`^N?@5LK{F8(F$heNM8ch|9R$`<9>me4D~)-uuu958W(a)Z#jK}3(a)h
zP06GtV#KbPD=-j<<4uV>sf0?^Mm35h5fn^C^!3RiEKEc}4|0&xOhg$HLOq&9GZ8Rf
zB(a)nE_BN}1ENf;7zi98P*<MDiI(a)_tVy%hztJ^1MqMIDB23*S=NE%kvEQ-s?Y|W1UQG
z5{SH*Q837&D3mXxq(X^&mV>)!ve_A|PT_((B*Ph|q$6~aEKDIOEG8ktM8XI}W-3s&
zpMCV3Th>+A-|YD}+ea&Rlx0#kb^rd2MXiZ1q*WJ^?UN1T9T}Og+~ll6`eA}5A|pjC
zN<PcZfAgbU(n!3NFSPpn&85+(a)i#^@7U0Nw+t^NfkHe+R3q%bikYOW~~lfsyYn3#`(
z_sT>L!PLL4<-29E5%m)c)Wk>FOhiWkET5c~mY1Qux;8lfnzuW(BMVu^RQRccLH|iX
z+$9d><-dBUi0+dS2;liW6wMT)Ld?`|)N^(fRIw=HrJFuun^7M1zje<k$bCnc?_OK?
zyS69SNuMVIVcB%?J$&<u*Oyj9YkSa>>q^h1MYZr%H*Ol!@v86AcL`%k(a)cYLK6kn3N
zwHWN_kyjBUavds$?elk^>Z)m46k%bymr;c8N+KS5O!o=IU@%)V^Vk+vh`gn<8t;mu
zGBBlvD46|6c>i~LzM?ES3{HoV#>A6vmH4Zl`c&sPu93`r_g41q3vk{WRwi*eDa%et
zA=)Ido%HMGy(a)Rb)Y)U(a)M?zk%0(a)RZ1x*?U(hg=BbXI_J<)$$N(}-z*tzB+L^$Nf{zJ
z8|qxLlzXXarX!nPQ)RN1F-fkHFr?}Zl|@xrtyH3E5jQU~wA^1YN1*e1GYbr26r@!u
zu5KNPU72X2JM4`~N+O9&L*8M>w7UJ|TSE8DqSc8q+eHc`fntcNiCC(sQAoDl@%Fp#
zkKyS19aa1t5~?=SV;vFbJ?i>cm|P|Mmaa<Gt#eet4>`hXH`%H2JN(bW<`@`kXg4h!
zjTq)|8S9xl)@u4xdG8A^eK7Fl6_{3Gt746`u576nII-_Mi<)i2Qjx%>1kzcon{~Q4
z`~LBXl=JwCH$3(iG1C_PwBo$hD#VqYx{Plbr;aB|cQ0tCWS?@5s*gE&PLZ(f4`QQb
zl^q&hzna0iu|pEIe^Z|MXs+|9UcX~$`d(a)V}#beS>K$jzH)co9Sw>fy~-a|EV#`VI|
zdas6fk^TKvHZC-EtY)<B<s7Mww4NOt6<?wInlEOt&_7c#SNORm`FUd0m)PDrhWcw=
zaxc3#txCtON$D#4>~7Wa9|ijy+h1Mjw4W{Y-*N1j&ZYQcW&0L6Pu%g9eCIsG-?$4-
ze-t<_h{n*^yx4jS)vcAPE#^9>EX>H`ue6zNmld7Mr&I02Wk(IoFGu%aJeArGdB}L|
zrjx9D*I2-L&Cly?8qIaj#O_o+0#S3_5~1BYm&RE4m0GGVyx)YD1+lBG(a)D)+jSgy5{
zSxg7MPq|EICzi(SlT>Hkdv5X@#+-PqG>%T9X=B<7{R>J<@@Q!<=Ce&*hQmHFd(a)EGZ
zm}&GZ3U-;PTFDhzY-_dD@%$Cb@@TSUvlcBzlMJsl=2w>8c9eDv6f=2SY`239I8%9r
z=dndzU!&;KDKNgj>zVi;4cWfKT-P+?g57uKt1THCkDC9B6>84kIc+Bjkt$<R8Y-(>
zNoOItnAIuvoI6<Cwf5cW-_YG^(d?Pcn=Rry24}3x$)w&fLYWfUBIX9Ba(a)AEWy=qOE
zs|qz5TpP0r(snug%3h34^^q-SR_xiE#_@{*WF^gR^pSwMMs9X~*2vacQ1z^pc`WzL
zVRUYpyL#shp3Q6OvsvZ~?X!gQAAzjaenuw4OVotOnM{*08<|j<luAoK4*&A|2Yk1z
zTe)?+E>f#5d^c2q=%m8Bh~%@^nn{hWgA-Qy+odS(a)r4alIs+VHKwF;z4Qjdb|aIwCN
z{h3eY&tWi<idemgzj}|cYeBYOR{F&qq7FNdQ4))+_v$JAihEY$@=>(qcYIn_zEtlt
zn*Jl>GhEWl%<0p<rG8f{vRtxudm7%26)7HzioB}L=~z~@?WsyumD=TfY<Js!R;Mq%
z-#)+R(a)fh7ZVb?RXJ~W<PK6jF}Y_%A<6<G39NwzU6{!K-Z|A$+8IwPN9YCb|Lm#U(~
zKN|~4xTATu(a)cR$f>OaVSZl-_J?^AnQNc8;5Q{UFC&ndN0@@cnyWW8eFaTnjr<E44|
zUr^<`*O=y*vX|JHR<mA{_P0w`B=R27N56iKgTl;YW;f4KD+Pq}{-5n|IQY2yZlBVp
zr~7REHKruZ)@2_7wKq(a)8L_J37(<<9Gk5!Y6(q$^jQ68x3CJ9VIMV#ZSUt%q#xScyF
zvfjOUKtdzcVU=DZmi>&Utbc36dv<dk?Umcg9kDA3JA{YuOgTq(a)MGv@2T5b~h#yV0j
trV{g%N`(@a(a)MbEnpGcx3aQduF99O339LFb?*k^wccO+AV2?OJrm#}}-OG5wv

literal 0
HcmV?d00001

diff --git a/tests/testfile70.exec.bz2 b/tests/testfile70.exec.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..f1b969afa667b3166d8052481fad793990abd19f
GIT binary patch
literal 2567
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

literal 0
HcmV?d00001


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