Bug 1201486 - run-backtrace-native-biarch fail when compiled with -m32 on x86-64
Summary: run-backtrace-native-biarch fail when compiled with -m32 on x86-64
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: elfutils
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Mark Wielaard
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-03-12 19:20 UTC by H.J. Lu
Modified: 2019-02-16 10:37 UTC (History)
7 users (show)

Fixed In Version:
Doc Type: Enhancement
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-02-16 10:37:42 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
A patch to skip 64-bit biarch tests on 32-bit host (1.01 KB, patch)
2015-03-12 22:01 UTC, H.J. Lu
no flags Details | Diff
ppc32 backend patch to query 64bit processes (3.02 KB, patch)
2015-03-17 20:19 UTC, Mark Wielaard
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Sourceware 24158 0 None None None 2019-02-16 10:37:41 UTC

Description H.J. Lu 2015-03-12 19:20:34 UTC
When elfutils is configured with

CC="gcc -m32" CXX="g++ -m32" ../elfutils/configure--enable-tests-rpath

I got

# make
...
# make check
...

FAIL: run-backtrace-native-biarch.sh
====================================

0x7f4a083aa000  0x7f4a08763000  /usr/lib64/libc-2.18.so
0x7f4a08768000  0x7f4a08981000  /usr/lib64/libpthread-2.18.so
0x7f4a08985000  0x7f4a08ba6000  /usr/lib64/ld-2.18.so
0x7f4a08ba7000  0x7f4a08da9000  /export/build/gnu/elfutils/build-i686-linux/tests/backtrace-child-biarch
0x7ffc2df0a000  0x7ffc2df0c000  [vdso: 14880]
TID 14880:
TID 14883:
/export/build/gnu/elfutils/build-i686-linux/tests/backtrace: dwfl_thread_getframes: no error
backtrace: /export/gnu/import/git/elfutils/libdwfl/linux-pid-attach.c:234: pid_set_initial_registers: Assertion `pid_arg->tid_attached == 0' failed.
/export/gnu/import/git/elfutils/tests/test-subr.sh: line 84: 14879 Aborted                 LD_LIBRARY_PATH="${built_library_path}${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" $VALGRIND_CMD "$@"
backtrace-child-biarch: no main

Comment 1 H.J. Lu 2015-03-12 22:01:17 UTC
Created attachment 1001207 [details]
A patch to skip 64-bit biarch tests on 32-bit host

Comment 2 Mark Wielaard 2015-03-13 09:54:25 UTC
In theory this should work. A 32bit elfutils can unwind a 64bit core file for example. But the problem here is that there seems to be no way to get the 64bit register values of the target process. We end up in backends/x86_64_initreg.c (x86_64_set_initial_registers_tid) which will just return false:

#if !defined(__x86_64__) || !defined(__linux__)
  return false;
#else /* __x86_64__ */

Is there anything we can do there?
Or is ptrace from a 32bit process against a 64bit process just not going to work?

Comment 3 H.J. Lu 2015-03-13 14:34:39 UTC
(In reply to Mark Wielaard from comment #2)
> Is there anything we can do there?
> Or is ptrace from a 32bit process against a 64bit process just not going to
> work?

You can't get 64-bit register values from ia32 process.  You can
get 64-bit register values from x32 process.  But the x32 address
space can't reach 64-bit address. Many things won't work.

Comment 4 Mark Wielaard 2015-03-13 15:03:48 UTC
(In reply to H.J. Lu from comment #3)
> You can't get 64-bit register values from ia32 process.
> You can get 64-bit register values from x32 process.

OK, then for ia32 your patch makes sense.
But it might be too broad if it also covers x32.

> But the x32 address space can't reach 64-bit address. Many things won't work.

For x32 I think we should at least get the 64-bit register values and see how far we get with that. Since libdw uses GElf_Addr and Dwarf_Addr, which are always 64bit, we are able to unwind 64-bit core files from a 32bit eu-stack for example. It might make sense to extend that to native processes for x32. Otherwise you'll have to build a x86_64 elfutils to get full x32 support.

Comment 5 Jan Kratochvil 2015-03-13 15:28:39 UTC
ppc has syscalls for 32->64 access like PPC_PTRACE_PEEKTEXT_3264.

Comment 6 H.J. Lu 2015-03-13 16:28:05 UTC
(In reply to Jan Kratochvil from comment #5)
> ppc has syscalls for 32->64 access like PPC_PTRACE_PEEKTEXT_3264.

I don't think it ever works:

static bool
pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
{
  struct __libdwfl_pid_arg *pid_arg = arg;
  pid_t tid = pid_arg->tid_attached;
  assert (tid > 0);
  Dwfl_Process *process = dwfl->process;
  if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
    {
#if SIZEOF_LONG == 8
      errno = 0;
      *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
      return errno == 0;
#else /* SIZEOF_LONG != 8 */
      /* This should not happen.  */
      return false;

Memory read of 64-bit process from 32-bit process always fails.

#endif /* SIZEOF_LONG != 8 */
    }

Comment 7 Mark Wielaard 2015-03-13 19:28:18 UTC
(In reply to H.J. Lu from comment #6)
> (In reply to Jan Kratochvil from comment #5)
> > ppc has syscalls for 32->64 access like PPC_PTRACE_PEEKTEXT_3264.
> 
> I don't think it ever works:
> 
> static bool
> pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
> {
>   struct __libdwfl_pid_arg *pid_arg = arg;
>   pid_t tid = pid_arg->tid_attached;
>   assert (tid > 0);
>   Dwfl_Process *process = dwfl->process;
>   if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
>     {
> #if SIZEOF_LONG == 8
>       errno = 0;
>       *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr,
> NULL);
>       return errno == 0;
> #else /* SIZEOF_LONG != 8 */
>       /* This should not happen.  */
>       return false;
> 
> Memory read of 64-bit process from 32-bit process always fails.
> 
> #endif /* SIZEOF_LONG != 8 */
>     }

Could that be fixed by using process_vm_readv or pread on /proc/PID/mem?

Comment 8 H.J. Lu 2015-03-13 20:00:20 UTC
(In reply to Mark Wielaard from comment #7)
> 
> Could that be fixed by using process_vm_readv or pread on /proc/PID/mem?

Yes, if you can read 64-bit process memory from 32-bit process.

Comment 9 H.J. Lu 2015-03-13 20:16:37 UTC
There are

struct iovec
  {
    void *iov_base;	/* Pointer to data.  */
    size_t iov_len;	/* Length of data.  */
  };

You can't read 64-bit memory from 32-bit process.

Comment 10 Mark Wielaard 2015-03-17 20:19:47 UTC
Created attachment 1002948 [details]
ppc32 backend patch to query 64bit processes

I created a dirty hack to make a ppc32 elfutils eu-stack work against ppc64 processes. It works, but needs some cleanup. The callback needs a way to know the ELF class of the process and the pid_memory_read probably needs to become a new ebl function so other arches can override.

$ file src/stack
src/stack: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xc8af6f4ce1da3e8c8c6eb20893f28c92edba8eec, not stripped

$ file -L /proc/$$/exe 
/proc/57869/exe: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xa0b448d58e63764cf7e618775cfa3ef639c107db, stripped

$ LD_LIBRARY_PATH=backends:libelf:libdw src/stack -v -p $$
PID 57869 - process
TID 57869:
#0  0x00003fffa9a416cc     __waitpid - /usr/lib64/power8/libc-2.17.so
#1  0x000000001004efd4 - 1 - /usr/bin/bash
#2  0x00000000100508cc - 1 wait_for - /usr/bin/bash
#3  0x000000001003c010 - 1 execute_command_internal - /usr/bin/bash
#4  0x000000001003c204 - 1 execute_command - /usr/bin/bash
#5  0x000000001001fa58 - 1 reader_loop - /usr/bin/bash
#6  0x000000001001d520 - 1 main - /usr/bin/bash
#7  0x00003fffa9995dec - 1 generic_start_main.isra.0 - /usr/lib64/power8/libc-2.17.so

Comment 11 Fedora End Of Life 2015-11-04 12:10:19 UTC
This message is a reminder that Fedora 21 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 21. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '21'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 21 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 12 Mark Wielaard 2015-11-04 12:30:33 UTC
Marking futurefeature since it could in theory be supported if needed.

Comment 13 Mark Wielaard 2019-02-16 10:37:42 UTC
Lets move this upstream. The following bug describes the same issue:
https://sourceware.org/bugzilla/show_bug.cgi?id=24158


Note You need to log in before you can comment on or make changes to this bug.