[v3,2/3] malloc: Remove LD_TRACE_PRELINKING usage from mtrace

Message ID 20220210121754.862331-3-adhemerval.zanella@linaro.org
State Committed
Commit d7703d3176d225d5743b21811d888619eba39e82
Headers
Series Remove prelink support |

Checks

Context Check Description
dj/TryBot-apply_patch fail Patch failed to apply to master at the time it was sent

Commit Message

Adhemerval Zanella Feb. 10, 2022, 12:17 p.m. UTC
  The fix for BZ#22716 replacde LD_TRACE_LOADED_OBJECTS with
LD_TRACE_PRELINKING so mtrace could record executable address
position.

To provide the same information, LD_TRACE_LOADED_OBJECTS is
extended where a value or '2' also prints the executable address
as well.  It avoid adding another loader environment variable
to be used solely for mtrace.  The vDSO will be printed as
a default library (with '=>' pointing the same name), which is
ok since both mtrace and ldd already handles it.

The mtrace script is changed to also parse the new format.  To
correctly support PIE and non-PIE executables, both the default
mtrace address and the one calculated as used (it fixes mtrace
for non-PIE exectuable as for BZ#22716 for PIE).

Checked on x86_64-linux-gnu.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
---
 NEWS             |  4 ++++
 elf/dl-main.h    |  3 +++
 elf/rtld.c       | 22 +++++++++++--------
 malloc/mtrace.pl | 55 +++++++++++++++++++++++++++---------------------
 4 files changed, 51 insertions(+), 33 deletions(-)
  

Comments

Andreas Schwab Aug. 22, 2022, 9:48 a.m. UTC | #1
This breaks cmake.

-- fixup_bundle: preparing...
  
Adhemerval Zanella Aug. 22, 2022, 6:56 p.m. UTC | #2
On 22/08/22 06:48, Andreas Schwab wrote:
> This breaks cmake.
> 
> -- fixup_bundle: preparing...
> -- warning: cannot resolve item 'linux-vdso.so.1' possible problems: need more directories? need to use InstallRequiredSystemLibraries? run in install tree instead of build tree? -- warning: gp_resolved_file_type non-absolute file 'linux-vdso.so.1' returning type 'other' -- possibly incorrect
> -- warning: cannot resolve item 'linux-vdso.so.1' possible problems: need more directories? need to use InstallRequiredSystemLibraries? run in install tree instead of build tree?
> -- warning: cannot resolve item 'linux-vdso.so.1' possible problems: need more directories? need to use InstallRequiredSystemLibraries? run in install tree instead of build tree? -- warning: gp_resolved_file_type non-absolute file 'linux-vdso.so.1' returning type 'other' -- possibly incorrect
> -- warning: cannot resolve item 'linux-vdso.so.1' possible problems: need more directories? need to use InstallRequiredSystemLibraries? run in install tree instead of build tree? CMake Error at /home/abuild/rpmbuild/BUILD/cmake-3.24.1/Modules/BundleUtilities.cmake:471 (file): file READ_ELF given FILE "linux-vdso.so.1" that does not exist. Call Stack (most recent call first): /home/abuild/rpmbuild/BUILD/cmake-3.24.1/Modules/BundleUtilities.cmake:527 (get_item_rpaths) /home/abuild/rpmbuild/BUILD/cmake-3.24.1/Modules/BundleUtilities.cmake:614 (set_bundle_key_values) /home/abuild/rpmbuild/BUILD/cmake-3.24.1/Modules/BundleUtilities.cmake:934 (get_bundle_keys) bundleutils.cmake:37 (fixup_bundle)

It seems that cmake does rely on vdso to not have the '=>' as the default
shared objects.  Does the following help cmake?

It is also unfortunate because we have been asked to also remove this [1]


diff --git a/elf/rtld.c b/elf/rtld.c
index cbbaf4a331..7e3e410719 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2122,6 +2122,10 @@ dl_main (const ElfW(Phdr) *phdr,
            if (l->l_faked)
              /* The library was not found.  */
              _dl_printf ("\t%s => not found\n",  l->l_libname->name);
+           else if (strcmp (l->l_libname->name, l->l_name) == 0)
+             _dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name,
+                         (int) sizeof l->l_map_start * 2,
+                         (size_t) l->l_map_start);
            else
              _dl_printf ("\t%s => %s (0x%0*Zx)\n",
                          DSO_FILENAME (l->l_libname->name),


[1] https://sourceware.org/pipermail/libc-help/2022-July/006225.html
  

Patch

diff --git a/NEWS b/NEWS
index 9bef1058b5..88815bcad1 100644
--- a/NEWS
+++ b/NEWS
@@ -193,6 +193,10 @@  Deprecated and removed features, and other changes affecting compatibility:
   removal of the LD_TRACE_PRELINKING, and LD_USE_LOAD_BIAS, environment
   variables and their functionality in the dynamic loader.
 
+* The LD_TRACE_PRELINKING environment variable has been removed.  Similar
+  functionality to obtain the program mapping address can be achieved by
+  using LD_TRACE_LOADED_OBJECTS to value of 2.
+
 Changes to build and runtime requirements:
 
 * The audit module interface version LAV_CURRENT is increased to enable
diff --git a/elf/dl-main.h b/elf/dl-main.h
index 3e32f254c5..e4fa19ee4e 100644
--- a/elf/dl-main.h
+++ b/elf/dl-main.h
@@ -94,6 +94,9 @@  struct dl_main_state
 
   enum rtld_mode mode;
 
+  /* True if program should be also printed for rtld_mode_trace.  */
+  bool mode_trace_program;
+
   /* True if any of the debugging options is enabled.  */
   bool any_debug;
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 5f089038e1..aa18256d86 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2104,18 +2104,18 @@  dl_main (const ElfW(Phdr) *phdr,
 	_dl_printf ("\tstatically linked\n");
       else
 	{
-	  for (l = main_map->l_next; l; l = l->l_next)
+	  for (l = state.mode_trace_program ? main_map : main_map->l_next;
+	       l; l = l->l_next) {
 	    if (l->l_faked)
 	      /* The library was not found.  */
-	      _dl_printf ("\t%s => not found\n", l->l_libname->name);
-	    else if (strcmp (l->l_libname->name, l->l_name) == 0)
-	      _dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name,
-			  (int) sizeof l->l_map_start * 2,
-			  (size_t) l->l_map_start);
+	      _dl_printf ("\t%s => not found\n",  l->l_libname->name);
 	    else
-	      _dl_printf ("\t%s => %s (0x%0*Zx)\n", l->l_libname->name,
-			  l->l_name, (int) sizeof l->l_map_start * 2,
+	      _dl_printf ("\t%s => %s (0x%0*Zx)\n",
+			  DSO_FILENAME (l->l_libname->name),
+			  DSO_FILENAME (l->l_name),
+			  (int) sizeof l->l_map_start * 2,
 			  (size_t) l->l_map_start);
+	  }
 	}
 
       if (__glibc_unlikely (state.mode != rtld_mode_trace))
@@ -2676,7 +2676,11 @@  process_envvars (struct dl_main_state *state)
 	case 20:
 	  /* The mode of the dynamic linker can be set.  */
 	  if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
-	    state->mode = rtld_mode_trace;
+	    {
+	      state->mode = rtld_mode_trace;
+	      state->mode_trace_program
+		= _dl_strtoul (&envline[21], NULL) > 1;
+	    }
 	  break;
 
 	  /* We might have some extra environment variable to handle.  This
diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl
index 042df725eb..3e7bd6852d 100644
--- a/malloc/mtrace.pl
+++ b/malloc/mtrace.pl
@@ -74,15 +74,14 @@  if ($#ARGV == 0) {
     } else {
 	$prog = "./$binary";
     }
-    # Set the environment variable LD_TRACE_PRELINKING to an empty string so
-    # that we trigger tracing but do not match with the executable or any of
-    # its dependencies.
-    if (open (LOCS, "env LD_TRACE_PRELINKING= $prog |")) {
-	while (<LOCS>) {
+    # Set the environment variable LD_TRACE_LOADED_OBJECTS to 2 so the
+    # executable is also printed.
+    if (open (locs, "env LD_TRACE_LOADED_OBJECTS=2 $prog |")) {
+	while (<locs>) {
 	    chop;
-	    if (/^.*=> (.*) \((0x[0123456789abcdef]*), (0x[0123456789abcdef]*).*/) {
+	    if (/^.*=> (.*) .(0x[0123456789abcdef]*).$/) {
 		$locs{$1} = $2;
-		$rel{$1} = hex($2) - hex($3);
+		$rel{$1} = hex($2);
 	    }
 	}
 	close (LOCS);
@@ -91,6 +90,18 @@  if ($#ARGV == 0) {
     die "Wrong number of arguments, run $progname --help for help.";
 }
 
+sub addr2line {
+    my $addr = pop(@_);
+    my $prog = pop(@_);
+    if (open (ADDR, "addr2line -e $prog $addr|")) {
+	my $line = <ADDR>;
+	chomp $line;
+	close (ADDR);
+	if ($line ne '??:0') {
+	    return $line
+	}
+    }
+}
 sub location {
     my $str = pop(@_);
     return $str if ($str eq "");
@@ -98,11 +109,9 @@  sub location {
 	my $addr = $1;
 	my $fct = $2;
 	return $cache{$addr} if (exists $cache{$addr});
-	if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
-	    my $line = <ADDR>;
-	    chomp $line;
-	    close (ADDR);
-	    if ($line ne '??:0') {
+	if ($binary ne "") {
+	    my $line = &addr2line($binary, $addr);
+	    if ($line) {
 		$cache{$addr} = $line;
 		return $cache{$addr};
 	    }
@@ -114,24 +123,22 @@  sub location {
 	my $searchaddr;
 	return $cache{$addr} if (exists $cache{$addr});
 	$searchaddr = sprintf "%#x", hex($addr) + $rel{$prog};
-	if ($binary ne "" && open (ADDR, "addr2line -e $prog $searchaddr|")) {
-	    my $line = <ADDR>;
-	    chomp $line;
-	    close (ADDR);
-	    if ($line ne '??:0') {
-		$cache{$addr} = $line;
-		return $cache{$addr};
+	if ($binary ne "") {
+	    for my $address ($searchaddr, $addr) {
+		my $line = &addr2line($prog, $address);
+		if ($line) {
+		    $cache{$addr} = $line;
+		    return $cache{$addr};
+		}
 	    }
 	}
 	$cache{$addr} = $str = $addr;
     } elsif ($str =~ /^.*[[](0x[^]]*)]$/) {
 	my $addr = $1;
 	return $cache{$addr} if (exists $cache{$addr});
-	if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
-	    my $line = <ADDR>;
-	    chomp $line;
-	    close (ADDR);
-	    if ($line ne '??:0') {
+	if ($binary ne "") {
+	    my $line = &addr2line($binary, $addr);
+	    if ($line) {
 		$cache{$addr} = $line;
 		return $cache{$addr};
 	    }