[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

Mark Wielaard  changed:

   What|Removed |Added

 CC||mark at klomp dot org

--- Comment #1 from Mark Wielaard  ---
There is no good way to tell. It could happen if the function calls itself
(although you would expect the pc to be different). How does perf call the
libdw getframe function? What does the CFI look like at that address?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread thommyj at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #2 from Thommy Jakobsson  ---
Created attachment 9833
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9833&action=edit
disassembly of function IBUFDIST_distribute

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Re: [PATCH] Check for existence of mempcpy

2017-02-17 Thread Mark Wielaard
On Thu, 2017-02-16 at 10:10 +0100, Ulf Hermann wrote:
> If it doesn't exist, provide a definition based on memcpy.

Applied, but slightly reluctantly. I have no way to test this. And it
will evaluate the last argument (n) twice. Which seems to not matter in
the current calls in our codebase. But it might subtly break something
if someone forgets.

Cheers,

Mark


[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread thommyj at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #3 from Thommy Jakobsson  ---
(In reply to Mark Wielaard from comment #1)
> There is no good way to tell. It could happen if the function calls itself
> (although you would expect the pc to be different).

I did check the assembler code for one case, and couldn't find anything
special, no calling of itself (although I didn't really know what to search for
either so I might have missed something =) ). Checking the code for the
specific example I pasted here it seems to be a return address for another
call. See attached file.

> How does perf call the libdw getframe function?
The actual call looks like this
err = dwfl_getthread_frames(ui.dwfl, thread->tid, frame_callback, &ui);
but I assume that you want some specific information? The entire wrapper around
libdw can be found here
http://lxr.free-electrons.com/source/tools/perf/util/unwind-libdw.c?v=4.4

> What does the CFI look like at that address?
How can I find this out? dwarfdump?

BR,
Thommy Jakobsson

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Re: [PATCH] Check for existence of mempcpy

2017-02-17 Thread Ulf Hermann
On 02/17/2017 10:46 AM, Mark Wielaard wrote:
> On Thu, 2017-02-16 at 10:10 +0100, Ulf Hermann wrote:
>> If it doesn't exist, provide a definition based on memcpy.
> 
> Applied, but slightly reluctantly. I have no way to test this. And it
> will evaluate the last argument (n) twice. Which seems to not matter in
> the current calls in our codebase. But it might subtly break something
> if someone forgets.

True. With other missing functions I tend to conditionally build the 
replacements into libeu.a as actual functions. That requires libeu.a to be 
linked into libdw.so, libelf.so, etc. I will create a followup patch that does 
the same with mempcpy.

Ulf


[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #4 from Mark Wielaard  ---
(In reply to Thommy Jakobsson from comment #2)
> Created attachment 9833 [details]
> disassembly of function IBUFDIST_distribute

That shows the (duplicated) address 6e3628 is the last one before the return of
the function:

  6e3628:   a8c27bfdldp x29, x30, [sp],#32
  6e362c:   d65f03c0ret

Maybe something gets confused by the stack adjustment?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread mark at klomp dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #5 from Mark Wielaard  ---
(In reply to Thommy Jakobsson from comment #3)
> (In reply to Mark Wielaard from comment #1)
> > How does perf call the libdw getframe function?
> The actual call looks like this
> err = dwfl_getthread_frames(ui.dwfl, thread->tid, frame_callback, &ui);
> but I assume that you want some specific information? The entire wrapper
> around libdw can be found here
> http://lxr.free-electrons.com/source/tools/perf/util/unwind-libdw.c?v=4.4

Maybe you can debug by triggering the pr_debug () to show what libdwfl returned
and compare it with how perf then prints out the struct ui that should hold the
same addresses to know which part of the code the duplicated address comes
from.

> > What does the CFI look like at that address?
> How can I find this out? dwarfdump?

eu-readelf --debug-dump=frame /usr/local/bin/Application
and look for the program covering initial_location and address range that
covers the address.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Re: [PATCH] Check for existence of mempcpy

2017-02-17 Thread Mark Wielaard
On Fri, 2017-02-17 at 10:50 +0100, Ulf Hermann wrote:
> True. With other missing functions I tend to conditionally build the
> replacements into libeu.a as actual functions. That requires libeu.a
> to be linked into libdw.so, libelf.so, etc. I will create a followup
> patch that does the same with mempcpy.

If at all possible I would like elfutils to not turn into some
abstraction layer for broken non-GNU/Linux systems. I don't mind small
(mostly) obvious correct defines/checks or tweaks to help out people
using such broken systems. But if we need a lot more of these things I
think we should look if we can just import the necessary gnulib modules
to get portability functions.

Cheers,

Mark


Re: [PATCH] Move print_version into printversion.{h|c}

2017-02-17 Thread Mark Wielaard
On Thu, 2017-02-16 at 12:32 +0100, Ulf Hermann wrote:
> Rename version.c so that the implementation is called after the header
> and the header doesn't clash with the toplevel version.h. print_version
> depends on argp and is only used in the tools.

Applied, because the split itself is fine.

But like said before argp is needed for the tools and the libdw
interface. If your glibc replacement doesn't provide argp the build
should pick up libargp and get the definitions and implementation from
there.

Cheers,

Mark


Re: [PATCH] Check for existence of mempcpy

2017-02-17 Thread Ulf Hermann

> If at all possible I would like elfutils to not turn into some
> abstraction layer for broken non-GNU/Linux systems. I don't mind small
> (mostly) obvious correct defines/checks or tweaks to help out people
> using such broken systems. But if we need a lot more of these things I
> think we should look if we can just import the necessary gnulib modules
> to get portability functions.

I've actually done that, but the amount of stuff that would need to be imported 
is staggering (see for example https://codereview.qt-project.org/#/c/182654/13) 
and comes with a serious mess of different licenses.

I've since switched to a different strategy where I rather disable features 
than import large gnulib modules. Disabling maintainer mode (for obstack) and 
any code that uses argp certainly helps. The remaining pain point is 
tsearch/tfind/tdelete/tdestroy for which we probably need third party code. 
Another problem is that we need fts for dwfl_linux_kernel_*. I'm on the edge on 
whether to include the gnulib implementation or disable it.

The retrying I/O functions can be implemented on top of either Linux/GNU or 
windows API and I would just move them to a separate file which I can replace 
based on availability of one or the other (I don't need to upstream the windows 
implementation). This technique will require universally using the retrying 
variants rather than the plain ones, which is a good thing anyway.

Replacements for mmap() and dlopen() on windows are a somewhat more involved 
matter but I don't really need to upstream them either, if you don't want them.

All other missing functions are just a few lines of C code each, which can 
either be pulled from gnulib or reimplemented. As I didn't want to taint myself 
with license problems I chose to reimplement them for now. But that can be 
decided on a case by case basis. Those are the patches I'm going to focus on 
next.

And then there are nonstandard C constructs, especially void* arithmetics and 
statement expressions, which I would like to replace with standards compliant 
C. That is a somewhat larger and not yet finished project, and I'm hoping 
you're generally open to it.

cheers,
Ulf


Re: [PATCH] Move print_version into printversion.{h|c}

2017-02-17 Thread Ulf Hermann

> But like said before argp is needed for the tools and the libdw
> interface. If your glibc replacement doesn't provide argp the build
> should pick up libargp and get the definitions and implementation from
> there.

libdw only needs it for argument parsing, which we can disable if argp isn't 
available. Not being able to build the tools in that case isn't the end of the 
world either. We're can still get a perfectly functional libdw and libelf. I 
would really like to cut down on dependencies rather than add extra third party 
code.

Ulf


[PATCH] Unify linking of libasm, libelf, libdw, backends

2017-02-17 Thread Ulf Hermann
Link them all with -z,defs,-z,relro,--no-undefined, provide complete
dependencies for the link steps, and add libeu.a to each one. libeu.a
contains useful library functionality that each of them might use. The
linker will strip unneeded symbols, so linking it in won't hurt even if
none of the functions are used.

Signed-off-by: Ulf Hermann 
---
 backends/Makefile.am |  7 ---
 libasm/Makefile.am   | 14 --
 libdw/Makefile.am| 15 +--
 libelf/Makefile.am   | 14 +-
 4 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/backends/Makefile.am b/backends/Makefile.am
index bfb6b84..79bd26c 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -45,6 +45,7 @@ noinst_DATA = $(libebl_pic:_pic.a=.so)
 
 libelf = ../libelf/libelf.so
 libdw = ../libdw/libdw.so
+libeu = ../lib/libeu.a
 
 i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c \
@@ -130,14 +131,14 @@ libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
 am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
 
 
-libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
+libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) $(libeu)
@rm -f $(@:.so=.map)
$(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: 
*; };' \
  > $(@:.so=.map)
$(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-   -Wl,--version-script,$(@:.so=.map) \
-   -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
+   -Wl,--version-script,$(@:.so=.map),--no-undefined \
+   -Wl,-z,defs,-z,relro -Wl,--as-needed $(libelf) $(libdw) $(libeu)
@$(textrel_check)
 
 libebl_i386.so: $(cpu_i386)
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 8094b05..9effa6c 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -55,17 +55,19 @@ libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c 
asm_error.c \
 libasm_pic_a_SOURCES =
 am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
 
-libasm_so_LDLIBS =
+libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl.a ../libelf/libelf.so 
../libdw/libdw.so
+libasm_so_LDLIBS = $(libasm_so_DEPS)
 if USE_LOCKS
 libasm_so_LDLIBS += -lpthread
 endif
 
+libasm_so_LIBS = libasm_pic.a
 libasm_so_SOURCES =
-libasm.so$(EXEEXT): libasm_pic.a libasm.map
-   $(AM_V_CCLD)$(LINK) -shared -o $@ 
-Wl,--whole-archive,$<,--no-whole-archive \
-   -Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
-   -Wl,--soname,$@.$(VERSION) \
-   ../libebl/libebl.a ../libelf/libelf.so ../libdw/libdw.so \
+libasm.so$(EXEEXT): $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
+   $(AM_V_CCLD)$(LINK) -shared -o $@ \
+   -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
+   -Wl,--version-script,$<,--no-undefined \
+   -Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
$(libasm_so_LDLIBS)
@$(textrel_check)
$(AM_V_at)ln -fs $@ $@.$(VERSION)
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 082d96c..634ac2e 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -102,17 +102,20 @@ endif
 libdw_pic_a_SOURCES =
 am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
 
+libdw_so_LIBS = libdw_pic.a ../libdwelf/libdwelf_pic.a \
+ ../libdwfl/libdwfl_pic.a ../libebl/libebl.a
+libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
+libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(zip_LIBS)
 libdw_so_SOURCES =
-libdw.so$(EXEEXT): $(srcdir)/libdw.map libdw_pic.a ../libdwelf/libdwelf_pic.a \
- ../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
- ../libelf/libelf.so
+libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
 # The rpath is necessary for libebl because its $ORIGIN use will
 # not fly in a setuid executable that links in libdw.
-   $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+   $(AM_V_CCLD)$(LINK) -shared -o $@ \
+   -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
-Wl,--version-script,$<,--no-undefined \
-   -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
-   -ldl -lz $(argp_LDADD) $(zip_LIBS)
+   -Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \
+   $(libdw_so_LDLIBS)
@$(textrel_check)
$(AM_V_at)ln -fs $@ $@.$(VERSION)
 
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 167a832..88c1edd 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -95,16 +95,20 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c 
elf_fill.c \
 libelf_pic_a_SOURCES =
 am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
 
-libelf_so_LDLIBS = -lz
+libelf_so_DEPS = ../lib/libeu.a
+libelf_so_LDLIBS = $(libelf_so_DEPS) -lz
 i

[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread thommyj at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #6 from Thommy Jakobsson  ---
Hi again and thanks for spending the time.

>>Maybe you can debug by triggering the pr_debug ()
Switched the pr_debug to a normal printf, and also added a printout of program
counter directly in the libdw frame callback (see attached patch). And from
what I can see the duplication of symbol comes from libdw

>>eu-readelf --debug-dump=frame /usr/local/bin/Application
Not fully understand how to read the callstack debug data, is this what you
want? I guess you are supposed to unroll the entire register file from last
function with this info, so I would have expected more data.

 [  1ad8] FDE length=36 cie=[  1aa0]
   CIE_pointer:  6816
   initial_location: 0x006e35d8 
   address_range:0x58

   Program:
 advance_loc 2 to 0x4
 def_cfa_offset 32
 offset r29 (x29) at cfa-32
 offset r30 (x30) at cfa-24
 advance_loc 2 to 0x8
 def_cfa_register r29 (x29)
 advance_loc 38 to 0x54
 restore r30 (x30)
 restore r29 (x29)
 def_cfa r31 (sp) at offset 0

 [  1b00] CIE length=12
   CIE_id:   18446744073709551615
   version:  1
   augmentation: ""
   code_alignment_factor:2
   data_alignment_factor:-4
   return_address_register:  30

   Program:
 def_cfa r31 (sp) at offset 0

BR,
Thommy Jakobsson

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[Bug libdw/21174] libdw with perf: duplication of entries in callstack

2017-02-17 Thread thommyj at gmail dot com
https://sourceware.org/bugzilla/show_bug.cgi?id=21174

--- Comment #7 from Thommy Jakobsson  ---
Created attachment 9834
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9834&action=edit
Add debug printouts in the perf stack unwind

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[PATCH v2] Unify linking of libasm, libelf, libdw, backends

2017-02-17 Thread Ulf Hermann
Link them all with -z,defs,-z,relro,--no-undefined, provide complete
dependencies for the link steps, and add libeu.a to each one. libeu.a
contains useful library functionality that each of them might use. The
linker will strip unneeded symbols, so linking it in won't hurt even if
none of the functions are used.

Signed-off-by: Ulf Hermann 
---
 backends/ChangeLog   |  6 ++
 backends/Makefile.am |  7 ---
 libasm/ChangeLog | 11 +++
 libasm/Makefile.am   | 14 --
 libdw/ChangeLog  |  9 +
 libdw/Makefile.am| 15 +--
 libelf/ChangeLog |  8 
 libelf/Makefile.am   | 14 +-
 8 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 02efb00..e66a5e0 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-17  Ulf Hermann  
+
+   * Makefile.am: Add libeu.
+   (libebl_%so): Link with --no-undefined,-z,defs,-z,relro
+   and libeu.a.
+
 2017-02-09  Ulf Hermann  
 
* aarch64_unwind.c: New file
diff --git a/backends/Makefile.am b/backends/Makefile.am
index bfb6b84..79bd26c 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -45,6 +45,7 @@ noinst_DATA = $(libebl_pic:_pic.a=.so)
 
 libelf = ../libelf/libelf.so
 libdw = ../libdw/libdw.so
+libeu = ../lib/libeu.a
 
 i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c \
@@ -130,14 +131,14 @@ libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
 am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
 
 
-libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
+libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) $(libeu)
@rm -f $(@:.so=.map)
$(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: 
*; };' \
  > $(@:.so=.map)
$(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-   -Wl,--version-script,$(@:.so=.map) \
-   -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
+   -Wl,--version-script,$(@:.so=.map),--no-undefined \
+   -Wl,-z,defs,-z,relro -Wl,--as-needed $(libelf) $(libdw) $(libeu)
@$(textrel_check)
 
 libebl_i386.so: $(cpu_i386)
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 26fc5a9..57b9ce1 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,14 @@
+2017-02-17  Ulf Hermann  
+
+   * Makefile.am: Add libasm_so_DEPS to specify external libraries
+   that have to be linked in, and libasm_so_LIBS to specify the
+   archives libasm consists of. The dependencies include libeu.a.
+   (libasm_so_LDLIBS): Add $(libasm_so_DEPS).
+   (libasm_so$(EXEEXT): Use $(libasm_so_LIBS),
+   add --no-undefined,-z,defs,-z,relro,
+   drop the manual enumeration of dependencies,
+   specify the correct path for libasm.map.
+
 2017-02-15  Ulf Hermann  
 
* disasm_str.c: Include system.h.
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 8094b05..9effa6c 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -55,17 +55,19 @@ libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c 
asm_error.c \
 libasm_pic_a_SOURCES =
 am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
 
-libasm_so_LDLIBS =
+libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl.a ../libelf/libelf.so 
../libdw/libdw.so
+libasm_so_LDLIBS = $(libasm_so_DEPS)
 if USE_LOCKS
 libasm_so_LDLIBS += -lpthread
 endif
 
+libasm_so_LIBS = libasm_pic.a
 libasm_so_SOURCES =
-libasm.so$(EXEEXT): libasm_pic.a libasm.map
-   $(AM_V_CCLD)$(LINK) -shared -o $@ 
-Wl,--whole-archive,$<,--no-whole-archive \
-   -Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
-   -Wl,--soname,$@.$(VERSION) \
-   ../libebl/libebl.a ../libelf/libelf.so ../libdw/libdw.so \
+libasm.so$(EXEEXT): $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
+   $(AM_V_CCLD)$(LINK) -shared -o $@ \
+   -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
+   -Wl,--version-script,$<,--no-undefined \
+   -Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
$(libasm_so_LDLIBS)
@$(textrel_check)
$(AM_V_at)ln -fs $@ $@.$(VERSION)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 978b991..0cc6049 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2017-02-17  Ulf Hermann  
+
+   * Makefile.am: Add libdw_so_LIBS to specify the archives libdw is is
+   made of, libdw_so_DEPS for libraries it depends on (including
+   libeu.a), libdw_so_LDLIBS to specify libraries libdw links against.
+   (libdw.so$(EXEEXT)): Add $(libdw_so_LDLIBS), remove enumeration of
+   library dependencies, use libdw_so_LIBS rather than relying on the
+   order of dependencies specified, add -z,relro.
+
 2016-10-22  Mark Wielaard  
 
* dwarf.h: Correct 

[PATCH] Make the replacement mempcpy a function

2017-02-17 Thread Ulf Hermann
This way we don't have to evaluate the 'n' argument twice. We now need
to link libeu.a into some tests, though. The system.h include was
accidentally dropped from elfcompress.c and findtextrel.c, but is
actually necessary when mempcpy is only available from libeu.

Signed-off-by: Ulf Hermann 
---
 ChangeLog |  4 
 configure.ac  |  1 +
 lib/ChangeLog |  7 +++
 lib/Makefile.am   |  4 
 lib/mempcpy.c | 41 +
 lib/system.h  |  3 +--
 src/ChangeLog |  5 +
 src/elfcompress.c |  1 +
 src/findtextrel.c |  2 +-
 tests/ChangeLog   |  4 
 tests/Makefile.am | 20 ++--
 11 files changed, 79 insertions(+), 13 deletions(-)
 create mode 100644 lib/mempcpy.c

diff --git a/ChangeLog b/ChangeLog
index 48185c3..15b36dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-17  Ulf Hermann  
+
+   * configure.ac: Define HAVE_MEMPCPY if mempcpy is available.
+
 2017-02-15  Ulf Hermann  
 
* configure.ac: Add check for mempcpy.
diff --git a/configure.ac b/configure.ac
index 3c35dac..303bf4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -288,6 +288,7 @@ AC_CHECK_DECLS([powerof2],[],[],[#include ])
 AC_CHECK_DECLS([mempcpy],[],[],
[#define _GNU_SOURCE
 #include ])
+AM_CONDITIONAL(HAVE_MEMPCPY, [test "x$ac_cv_have_decl_mempcpy" = "xyes"])
 
 AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
 AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 84290f7..dcd20e1 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,10 @@
+2017-02-17  Ulf Hermann  
+
+   * system.h: Make mempcpy a function.
+   * mempcpy.c: New file.
+   * Makefile.am (libeu_a_SOURCES): Add mempcpy.c if mempcpy is not
+   available from libc.
+
 2017-02-16  Ulf Hermann  
 
* Makefile.am (libeu_a_SOURCES): Remove version.c, add printversion.c
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7a65eb9..63738fd 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -41,6 +41,10 @@ noinst_HEADERS = fixedsizehash.h libeu.h system.h 
dynamicsizehash.h list.h \
 md5.h sha1.h eu-config.h color.h printversion.h
 EXTRA_DIST = dynamicsizehash.c
 
+if !HAVE_MEMPCPY
+libeu_a_SOURCES += mempcpy.c
+endif
+
 if !GPROF
 xmalloc_CFLAGS = -ffunction-sections
 endif
diff --git a/lib/mempcpy.c b/lib/mempcpy.c
new file mode 100644
index 000..aff8d54
--- /dev/null
+++ b/lib/mempcpy.c
@@ -0,0 +1,41 @@
+/* Implementation of mempcpy, using memcpy
+   Copyright (C) 2017 The Qt Company Ltd.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at
+   your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#include "system.h"
+#include 
+
+void *
+mempcpy(void *dest, const void *src, size_t n)
+{
+return (char *) memcpy (dest, src, n) + n;
+}
+
diff --git a/lib/system.h b/lib/system.h
index 2d05702..6ddbb2d 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -68,8 +68,7 @@
 #endif
 
 #if !HAVE_DECL_MEMPCPY
-#define mempcpy(dest, src, n) \
-((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
+void *mempcpy(void *dest, const void *src, size_t n);
 #endif
 
 /* A special gettext function we use if the strings are too short.  */
diff --git a/src/ChangeLog b/src/ChangeLog
index 0601198..d26169b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2017-02-17  Ulf Hermann  
+
+   * elfcompress.c: Include system.h.
+   * findtextrel.c: Likewise.
+
 2017-02-16  Ulf Hermann  
 
* addr2line.c: Include printversion.h
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 8e0d5c5..cf85820 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -36,6 +36,7 @@
 #include 
 #include "libeu.h"
 #include "printversion.h"
+#include "system.h"
 
 /* Name and version of program.  */
 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
diff --git a/src/findtextrel.c b/src/findtextrel.c
index 8f1e239..5382abd 100644
--- a/src/findtextrel.c
+++ b/src/findtextrel.c
@@ -37,7 +37,7 @@
 #include 
 
 #include 
-
+#include 
 
 struct