Re: Building Elfutils with Mingw32

2023-09-16 Thread Ulf Hermann via Elfutils-devel
I haven't considered shipping cygwin with perfparser. Is that actually 
possible? It looks like it needs some installation procedure I would 
have to burden the user with.


I guess shipping cygwin with perfparser would make me a 3PP [1]. Sounds 
like fun.


[1] https://www.cygwin.com/acronyms/#3PP


Re: Building Elfutils with Mingw32

2023-09-16 Thread Ulf Hermann via Elfutils-devel

Hi,

I'll answer some questions here:


Given that Windows doesn't even use ELF why would you even want elfutils on
such a platform?


There is a large number of developers who build software for ELF-based 
embedded systems on windows and test/debug/profile/deploy it over some 
network or USB connection. Those people want to have elfutils for their 
debugging and profiling. They want to use elfutils on the host (the 
windows box) because that is much faster.


Those people are not me and I'm not talking about sanity.

Qt Creator (the Qt IDE) has a profiling view that takes data produced by 
perf and paints pretty graphs from that. The actual perf data is 
recorded on the target (potentially an embedded device), then streamed 
or copied to the host, then run through perfparser to produce meaningful 
stack traces. perfparser uses elfutils for the actual work. That work is 
quite heavy. A sample frequency of 1000Hz is not uncommon. Few embedded 
device can do that "on the side" while still producing meaningful 
results for the actual task. Finally, Qt Creator takes the processed 
data and displays a UI to explore it. There is another UI for the same 
data, "Hotspot" by Milian, but I don't know if that can run on windows.



And why aren't people simply using cygwin for such a port?


If we built perfparser with cygwin, the people who use it would also 
need cygwin. People building embedded devices generally have a colorful 
mess of different tools, none of which you can rely on in advance. I 
haven't considered shipping cygwin with perfparser. Is that actually 
possible? It looks like it needs some installation procedure I would 
have to burden the user with.



Without it you don't even have a normal POSIX like system.


Indeed, but we have gnulib and the various adapters I wrote myself (some 
of which should probably be upstreamed to gnulib). That deals with the 
problem. We get binaries that only depend on a basic windows system.


This comes at the price of using the most basic C library that Microsoft 
offers, msvcrt.dll. In order to use the elfutils libraries built that 
way you have to jump through the open/close and malloc/free hoops we 
provide in eu_compat.lib. However, that is only a problem for perfparser 
or other software linked against elfutils, not for the user.



And when using mingw do people still use a normal gcc compiler (to cross
build)? Or is the goal to build with some alternative windows
compiler?


The gold standard would indeed be the ability to build it with Microsoft 
compilers and their associated C libraries. Then we could get  rid of 
the malloc/free and open/close hacks. However, given that Microsoft 
compilers have a rather different idea of C than elfutils, I didn't go 
there. Building it with gcc is more overhead for me when producing the 
binary. I cannot cleanly integrate it into the Qt Creator build system 
since that assumes it can use the same compiler for everything. However, 
for the users it doesn't make a difference.



But if there is consensus (among the Windows hackers) about using one
common target for the port then maybe we should have an official
branch on sourceware?


Such a thing would certainly be welcome from my point of view!


Also there is a mingw container setup on builder.sourceware.org which
we might use for doing CI on the port?
https://sourceware.org/cgit/builder/tree/builder/containers/Containerfile-fedora-mingw


I'll have to look at it in detail, but that also sounds great! So far 
there is no automated CI. I just run the tests manually when I change 
anything.


best regards,
Ulf


Re: Building Elfutils with Mingw32

2023-09-15 Thread Ulf Hermann via Elfutils-devel
Indeed I have noticed the other patches, but I don't think they are the 
same as mine. So, now we have a three way merge.


I guess some more of the changes could be merged if properly cleaned up 
and made to benefit other obscure platforms, too. However, there are a 
few I got a definite "no" for. In particular the windows dance around 
text/binary mode when opening files was not welcome. I couldn't come up 
with a better solution than adding an O_BINARY or O_TEXT to every single 
open() call. We actually need the distinction as some files need to be 
opened in text mode for the tests to pass. If you can come up with 
anything better here, please let me know.


best regards,
Ulf


Re: Building Elfutils with Mingw32

2023-09-14 Thread Ulf Hermann via Elfutils-devel

Hi,

keeping the windows/elfutils fork up to date definitely is a lot of 
work, which is why I haven't found the time to do it for a while. 
However, perfparser could in fact also use debuginfod (with some caveats).


I guess that some more of my patches could be upstreamed if properly 
cleaned up. A rebase rather than a merge may be more conductive to this.


All I can do right now is tell you that I'd be happy about any 
contribution. The repository I've been using still exists and accepts 
outside contributions. See 
https://codereview.qt-project.org/q/repo:qt-creator/elfutils . You have 
to go through the Qt CLA process to work with it, but the CLA is largely 
meaningless in this case. I'd be happy to move the repository to a more 
"official" place without CLA.


There have also been other people on this mailing list talking about 
porting elfutils to windows. Maybe if we combine our efforts we'll 
actually find a way to maintain a port.


best regards,
Ulf


Re: Windows build of libelf (or more)?

2021-05-06 Thread Ulf Hermann via Elfutils-devel

The Qt project had some windows libraries:
https://code.qt.io/cgit/qt-creator/elfutils.git/
https://download.qt.io/development_releases/prebuilt/elfutils/


Those are somewhat outdated, unfortunately. Contributions through our 
code review system at https://codereview.qt-project.org are always 
welcome. See 
https://codereview.qt-project.org/q/project:qt-creator%252Felfutils for 
older changes, and please add me as a reviewer if you push something.


cheers,
Ulf


Re: Symbol versioning (Was: [Bug general/24000] couple of testsuite fails with uclibc library)

2019-02-19 Thread Ulf Hermann
> The problem is that without it every elfutils release would (possibly)
> break the ABI between the shared libraries and programs using them.
> And we don't have/use a different mechanism to indicate symbols/ABI
> changed. How do you prevent things breaking when upgrading the
> elfutils libraries?

I ship the version of elfutils the application links against with the 
application. That is common practice on windows (and also on e.g. 
macOS). The concept of package management only exist on some platforms 
and only in this context symbol versioning makes sense. Even on linux, 
with things like flatpak, binary compatibility between different 
versions of a library becomes less important.

best,
Ulf


Re: [Bug general/24000] couple of testsuite fails with uclibc library

2019-02-19 Thread Ulf Hermann
Hi,

>>> Don't disable symbol versioning, without it binary compatibility is broken.
>>
>> As per the following commit disabled symbol versioning for uclibc
>> https://sourceware.org/git/?p=elfutils.git;a=commit;
>> h=bafacacaf7659a4933604662daba26a480b29a8d
>>
>> with uclibc,the test suite hangs in middle when compiled with Symbol
>> versioning
> 
> hmmm. I think that commit might have been a mistake in hindsight.

The option to disable symbol versioning is appreciated here. I don't 
think it's a mistake. There are platforms which don't support symbol 
versioning at all.

best,
Ulf


Re: [PATCH] configure: Add new --enable-install-elfh option.

2019-01-18 Thread Ulf Hermann
I think you should also adapt tests/Makefile.am to use our own elf.h in 
this case. See https://codereview.qt-project.org/#/c/187812/25 for my 
solution to this.


[PATCH] Use separate files for strip outputs

2019-01-18 Thread Ulf Hermann
Let's see if this works: Apparently I cannot get a properly formatted 
inline diff through. Therefore, please find the pull request, including 
diff, as attachment.

regards,
Ulf
The following changes since commit e65d91d21cb09d83b001fef9435e576ba447db32:

  libelf: Correct overflow check in note_xlate. (2019-01-16 12:25:57 +0100)

are available in the git repository at:

  https://codereview.qt-project.org/qt-creator/elfutils changes/37/250337/3

for you to fetch changes up to ce0ea06597bbba665ad6c26cef50d20895d246de:

  Use separate files for strip outputs (2019-01-18 13:53:52 +0100)


Ulf Hermann (1):
  Use separate files for strip outputs

 tests/ChangeLog  |  6 +
 tests/run-annobingroup.sh| 20 -
 tests/run-strip-test-many.sh | 53 +---
 3 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index 8c9e7807..19879269 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-18  Ulf Hermann 
+
+   * run-annobingroup.sh: Use different files for strip output.
+   * run-strip-test-many.sh: Use different files for strip output,
+   check results of strip, unstrip, elflint.
+
 2019-01-09  Ulf Hermann 
 
* run-readelf-compressed.sh: Skip if USE_BZIP2 not found.
diff --git a/tests/run-annobingroup.sh b/tests/run-annobingroup.sh
index fd36e4ac..16b031a1 100755
--- a/tests/run-annobingroup.sh
+++ b/tests/run-annobingroup.sh
@@ -25,7 +25,7 @@
 # gcc -g -O2 -fplugin=annobin -c testfile-annobingroup.c
 testfiles testfile-annobingroup.o
 
-tempfiles merged.elf stripped.elf debugfile.elf remerged.elf
+tempfiles merged.elf stripped.elf debugfile1.elf debugfile2.elf debugfile3.elf 
remerged.elf
 
 testrun_compare ${abs_top_builddir}/src/readelf -g testfile-annobingroup.o << 
EOF
 
@@ -35,7 +35,7 @@ Section group [ 1] '.group' with signature 
'.text.unlikely.group' contains 3 ent
   [ 9] .text.unlikely
 EOF
 
-testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile.elf 
testfile-annobingroup.o
+testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile1.elf 
testfile-annobingroup.o
 
 testrun_compare ${abs_top_builddir}/src/readelf -g stripped.elf << EOF
 
@@ -45,7 +45,7 @@ Section group [ 1] '.group' with signature 
'.text.unlikely.group' contains 3 ent
   [ 9] .text.unlikely
 EOF
 
-testrun_compare ${abs_top_builddir}/src/readelf -g debugfile.elf << EOF
+testrun_compare ${abs_top_builddir}/src/readelf -g debugfile1.elf << EOF
 
 Section group [ 1] '.group' with signature '.text.unlikely.group' contains 3 
entries:
   [ 7] .gnu.build.attributes..text.unlikely
@@ -53,7 +53,7 @@ Section group [ 1] '.group' with signature 
'.text.unlikely.group' contains 3 ent
   [ 9] .text.unlikely
 EOF
 
-testrun ${abs_top_builddir}/src/unstrip -o remerged.elf stripped.elf 
debugfile.elf
+testrun ${abs_top_builddir}/src/unstrip -o remerged.elf stripped.elf 
debugfile1.elf
 
 testrun_compare ${abs_top_builddir}/src/readelf -g remerged.elf << EOF
 
@@ -81,7 +81,7 @@ COMDAT section group [ 2] '.group' with signature 
'__x86.get_pc_thunk.ax' contai
   [13] .text.__x86.get_pc_thunk.ax
 EOF
 
-testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile.elf 
testfile-annobingroup-i386.o
+testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile2.elf 
testfile-annobingroup-i386.o
 
 testrun_compare ${abs_top_builddir}/src/readelf -g stripped.elf << EOF
 
@@ -94,7 +94,7 @@ COMDAT section group [ 2] '.group' with signature 
'__x86.get_pc_thunk.ax' contai
   [13] .text.__x86.get_pc_thunk.ax
 EOF
 
-testrun_compare ${abs_top_builddir}/src/readelf -g debugfile.elf << EOF
+testrun_compare ${abs_top_builddir}/src/readelf -g debugfile2.elf << EOF
 
 Section group [ 1] '.group' with signature '.text.unlikely.group' contains 3 
entries:
   [ 8] .gnu.build.attributes..text.unlikely
@@ -105,7 +105,7 @@ COMDAT section group [ 2] '.group' with signature 
'__x86.get_pc_thunk.ax' contai
   [13] .text.__x86.get_pc_thunk.ax
 EOF
 
-testrun ${abs_top_builddir}/src/unstrip -o remerged.elf stripped.elf 
debugfile.elf
+testrun ${abs_top_builddir}/src/unstrip -o remerged.elf stripped.elf 
debugfile2.elf
 
 testrun_compare ${abs_top_builddir}/src/readelf -g remerged.elf << EOF
 
@@ -143,13 +143,13 @@ Section group [ 4] '.group' with signature 
'.text.unlikely..group' contains 1 en
   [27] .text.unlikely
 EOF
 
-testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile.elf 
testfile-annobingroup-x86_64.o
+testrun ${abs_top_builddir}/src/strip -o stripped.elf -f debugfile3.elf 
testfile-annobingroup-x86_64.o
 
 # This would/should work, except for the unknown NOTEs.
 # testrun ${abs_top_builddir}/src/elflint --gnu stripped.elf
-# testrun ${abs_top_builddir}/src/elflint --gnu --debug debugfile.elf
+# testrun ${abs_top_builddir}/src/elflint --gnu --d

[PATCH] Skip run-readelf-compressed.sh test if built without bzip2

2019-01-09 Thread Ulf Hermann
Obviously, we cannot read the compressed ELF file if no bzip2 support is
present.

Signed-off-by: Ulf Hermann 
---
  tests/run-readelf-compressed.sh | 5 +
  1 file changed, 5 insertions(+)

diff --git a/tests/run-readelf-compressed.sh 
b/tests/run-readelf-compressed.sh
index a2a04a2a..861553fe 100755
--- a/tests/run-readelf-compressed.sh
+++ b/tests/run-readelf-compressed.sh
@@ -17,6 +17,11 @@

  . $srcdir/test-subr.sh

+if ! grep -q -F '#define USE_BZLIB' ${abs_top_builddir}/config.h; then
+  echo "elfutils built without bzip2 support"
+  exit 77
+fi
+
  # See run-strip-reloc.sh
  testfiles hello_i386.ko

-- 
2.11.0



Re: Handling pgoff in perf elf mmap/mmap2 elf info

2018-10-18 Thread Ulf Hermann
Consider:

> 0x7fac5ec0b000 to 0x7fac5ed9a000, len =   0x18f000, offset =0
> r--p/usr/lib/libstdc++.so.6.0.25
> 0x7fac5ec94000 to 0x7fac5ed8a000, len =0xf6000, offset =  0x89000
> ---p/usr/lib/libstdc++.so.6.0.25

0x7fac5ec94000 - 0x89000 = 0x7fac5ec0b000

This is just taking away the 'r' bit from part of the first mapping. We 
can ignore it in perf and perfparser.

> 0x7fac5ec94000 to 0x7fac5ed4c000, len =0xb8000, offset =  0x89000
> r-xp/usr/lib/libstdc++.so.6.0.25

Same thing, but adding the 'r' and 'x' bits.

> 0x7fac5ed4c000 to 0x7fac5ed89000, len =0x3d000, offset = 0x141000
> r--p/usr/lib/libstdc++.so.6.0.25

0x7fac5ed4c000 - 0x141000 = 0x7fac5ec0b000

This is re-adding the 'r' bit for a different range, again without 
changing the contents.

> 0x7fac5ed8a000 to 0x7fac5ed97000, len = 0xd000, offset = 0x17e000
> rw-p/usr/lib/libstdc++.so.6.0.25

0x7fac5ed8a000 - 0x17e000 = 0x7fac5ec0c000

Strange, what is this? Note that the 'rw', though. It probably doesn't 
contain any executable code. In effect, perfparser and perf should then 
truncate the original mapping and never report this one to libdw, just 
like we do in perfparser now (for different reasons).

So, what about the following algorithing, which can be done entirely 
outside of elfutils:

If we get an mmap with a pgoff, check if the same file is already mapped 
at the "virtual" start address of the file (start - pgoff), and if it 
is, ignore the mmap. That should deal with the first 3 overlaps here. 
The last one is really mapping a different part of the file, but as the 
mapping is not executable and read-write we should really never get a 
sample from it.

We might actually check the permission bits before reporting things to 
dwfl so that a few broken samples don't destroy the memory map. However, 
that partially contradicts the above. We'd need to OR up all the 
permissions from different mmaps covering the same file at the same base 
address to get an approximation for it, or we need a different data 
structure.

best,
Ulf


Re: How to associate Elf with Dwfl_Module returned by dwfl_report_module

2018-03-22 Thread Ulf Hermann
Hi Milian,

> I am regularly seeing broken backtraces for samples where I have 
> the gut feeling that missing reported ELFs are to blame. But we report 
> everything, except for scenarios where the mmap events seemingly overlap.

Actually, at least for perfparser that's not quite true. When perfparser 
encounters an overlap error, it will throw out the entire set of mappings and 
restart reporting, with the addresses from the current sample (see 
PerfSymbolTable::reportElf() and PerfSymbolTable::clearCache()). If that still 
gives you overlapping ranges, it means perf has not sent all the mmap events 
and therefore we're reporting the wrong ELF for some address in your sample. 
That wrong ELF may be larger than the one we actually want and therefore it can 
overlap some other ELF an address in your sample points to.

I've seen that happen. Make sure to keep your sample rate low enough to prevent 
perf from dropping anything.

I realize we could optimize the reporting a bit, with the dwfl_report_end 
callback Mark mentioned, but if you have addresses into two overlapping ELFs in 
one sample, that's fundamentally impossible to unwind.

Ulf


Re: How to associate Elf with Dwfl_Module returned by dwfl_report_module

2018-03-21 Thread Ulf Hermann
> MEH: heaptrack_print | mmap: 56166e9d4000 56166ea39000 | dwfl: 56166e9d4000 
> 56166ea38880
> MEH: ld-2.26.so | mmap: 7fd0afc6c000 7fd0afe93000 | dwfl: 7fd0afc6c000 
> 7fd0afe920f8
> MEH: libc-2.26.so | mmap: 7fd0ae16a000 7fd0ae521000 | dwfl: 7fd0ae16a000 
> 7fd0ae5208f0
> MEH: libstdc++.so.6.0.24 | mmap: 7fd0aea84000 7fd0aee0b000 | dwfl: 
> 7fd0aea84000 7fd0aee0a640
> MEH: libzstd.so.1.3.3 | mmap: 7fd0aee0b000 7fd0af087000 | dwfl: 7fd0aee0b000 
> 7fd0af086030
> 
> Interestingly, here the mmap events observed by perf are actually always 
> *larger* than what dwfl sees...

Do those differences map to some specific ELF sections? That is, does elfutils 
assume some sections are mmap'd even though they aren't or vice versa? As 
elfutils always assumes pgoff == 0 it should be fairly simple to see which 
sections those are (right?).

Ulf


Re: [PATCH v2] Add fallthrough attributes

2018-02-09 Thread Ulf Hermann
> [...]
> +#ifdef HAVE_FALLTHROUGH
> +  __attribute__ ((fallthrough));
> +#endif
> [...]

I would like to see this stanza wrapped in a macro, so that we only have one 
"#ifdef HAVE_FALLTHROUGH" in the code, not another one in every place we want 
to fall through. See the "internal_function" macro defined in lib/eu-config.h 
for a similar case.

Ulf


Re: [PATCH 1/2 v2] Don't overflow in __libdw_in_section

2017-12-21 Thread Ulf Hermann

It is surprising we didn't see more issues with this code. There is
also the fake loc cu that fetches data from a different section. I
updated both functions as attached.


Looks good to me.

Ulf


Re: [PATCH 1/2 v2] Don't overflow in __libdw_in_section

2017-12-14 Thread Ulf Hermann
On 12/14/2017 02:43 PM, Mark Wielaard wrote:
> (Meta, I have some trouble applying this with git am, it thinks the
> patch is malformed. But I can apply by hand of course.)

Oh, sorry for that. It's probably the leading spaces again. I keep messing up 
my mail setup on windows ...

> The transformation seems correct. But if we can overflow/underflow
> here, do we have the same problem in __libdw_offset_in_section where we
>   check data->d_size - offset < size, with offset a Dwarf_Off?

Probably we have the same problem there. I didn't catch any instances of it, 
though.

regards,
Ulf


Re: [PATCH 2/2 v2] Generalize cu_sec_idx

2017-12-14 Thread Ulf Hermann
On 12/14/2017 02:51 PM, Mark Wielaard wrote:
> This is clever and indeed cu_sec_idx () is not generic enough.
> But this is also somewhat inefficient. I am working on DWARF5 support
> and there a CU can come from even more different sections (or file). So
> I am changing Dwarf_CU to have an explicit section to which is it is
> associated. This can then also be used by the "fake" CUs like created
> in dwarf_getmacros.

Mind that the two most common cases are 0 and 1. In fact nothing else was 
supported before this change. So, most of the time this will not do a lot of 
iteration.

regards,
Ulf


[PATCH 2/2 v2] Generalize cu_sec_idx

2017-12-08 Thread Ulf Hermann

Apparently CUs can appear in other sections than IDX_debug_info and
IDX_types. Rather than relying on the indirect indication provided by
type_offset we compare the addresses directly to figure out which section
a given CU belongs to.

This fixes the dwarf-getmacros test.

(Signed-off instead of Change-Id ...)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdw/ChangeLog |  4 
 libdw/libdwP.h  | 12 +++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 996cd2e..508bf9c 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2017-12-08  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * libdwP.h: Generalize cu_sec_idx to check all sections.
+
 2017-05-09  Ulf Hermann  <ulf.herm...@qt.io>
  	* libdwP.h: Fix check for the upper border of the range in 
__libdw_in_section.

diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index e092d8e..8f3a95c 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -715,7 +715,17 @@ __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
 static inline size_t
 cu_sec_idx (struct Dwarf_CU *cu)
 {
-  return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
+  for (int sec_index = IDX_debug_info; sec_index < IDX_last; ++sec_index)
+{
+  Elf_Data *data = cu->dbg->sectiondata[sec_index];
+  if (data != NULL && data->d_buf != NULL
+  && cu->startp >= data->d_buf
+  && cu->startp < data->d_buf + data->d_size)
+{
+  return sec_index;
+}
+}
+  return IDX_last;
 }
  static inline bool
--
2.8.1.windows.1



[PATCH 1/2 v2] Don't overflow in __libdw_in_section

2017-12-08 Thread Ulf Hermann

This exposes a bug in dwarf_formstring as detected by the dwarf-getmacros
test. We cannot unconditionally assume that a string is in either the
IDX_debug_info or the IDX_debug_types section as determined by
cu_sec_idx.

(Signed-off instead of Change-Id ...)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdw/ChangeLog | 4 
 libdw/libdwP.h  | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 4375244..996cd2e 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-09  Ulf Hermann  <ulf.herm...@qt.io>
+
+	* libdwP.h: Fix check for the upper border of the range in 
__libdw_in_section.

+
 2017-11-03  Mark Wielaard  <m...@klomp.org>
* dwarf_getlocation.c (__libdw_intern_expression): Handle
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 78c0013..e092d8e 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -643,7 +643,8 @@ __libdw_in_section (Dwarf *dbg, int sec_index,
   if (data == NULL)
 return false;
   if (unlikely (addr < data->d_buf)
-  || unlikely (data->d_size - (addr - data->d_buf) < size))
+  || unlikely (data->d_size < size)
+  || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
 {
   __libdw_seterrno (DWARF_E_INVALID_OFFSET);
   return false;
--
2.8.1.windows.1



Re: [PATCH] Add replacement endian.h and byteswap.h to libgnu

2017-11-16 Thread Ulf Hermann
>> Some systems don't provide endian.h and byteswap.h. The required
>> functions are trivial to define using sys/param.h and gcc builtins,
>> though.
>>
>> Also, include endian.h in dwelf_scn_gnu_compressed_size.c as that uses
>> be64toh().
> 
> This is still an issue with non-glibc, non-BSD compilation.  The patch
> is not ideal, as it depends on a GCC extension, but it's an
> improvement for those who use GCC on a platform which does not provide
> these functions as part of the C library.

Well, there are a lot of other issues to be fixed if you want to build elfutils 
on anything non-gcc. We could add a further check for those builtins and 
sys/param.h and then add a somewhat less trivial version of endian.h and 
byteswap.h if they are missing. But that would likely involve other compiler 
extensions or OS-specific headers.

br,
Ulf


Re: Compile elfutils with Clang

2017-09-12 Thread Ulf Hermann
Hi Dmitry,

I would love to know how you implemented INLINE_NESTED_FUNC, but nested_func.h 
seems to be missing from your patch. Can you please double check this?

regards,
Ulf


Re: [PATCH 1/2] Initialize type_offset of fake_cu

2017-09-06 Thread Ulf Hermann
On 05/09/2017 06:28 PM, Ulf Hermann wrote:
> Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
> ---
>  libdw/ChangeLog | 4 
>  libdw/dwarf_getmacros.c | 1 +
>  2 files changed, 5 insertions(+)
> [...]
It seems we missed this one, but it fixes a bug. Can we apply it? PATCH 2/2 is 
not actually related.

Ulf


[PATCH v3] Check if rpath is supported and throw an error if not

2017-08-18 Thread Ulf Hermann
Some systems don't have rpath. In that case the backends need to be
made available by some external mechanism. Provide a configure switch
to explicitly turn off the setting of rpaths. Throw an error if that is
not set and rpath is not supported.

(Reposting rebased patch, as v2 was never reviewed.)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog |  5 +
 configure.ac  | 22 ++
 libdw/ChangeLog   |  4 
 libdw/Makefile.am |  8 +++-
 4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index b720f2cd..47b37565 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check if the linker supports -rpath and add a switch
+   to disable setting of rpath.
+
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Test if symbol versioning is supported.
 
 2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/configure.ac b/configure.ac
index 4ab8816a..6856ff7e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -208,6 +208,28 @@ fi
 
 AC_SUBST([dso_LDFLAGS])
 
+AC_ARG_ENABLE([rpath],
+AS_HELP_STRING([--disable-rpath], [Disable setting of rpath]))
+
+AC_CACHE_CHECK([for rpath support], ac_cv_rpath, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$save_LDFLAGS -Wl,--enable-new-dtags,-rpath,/foo/bar"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_rpath=yes, ac_cv_rpath=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_rpath" = "no"; then
+if test "x$enable_rpath" != "xno"; then
+AC_MSG_ERROR([rpath is not supported.
+  Use --disable-rpath to build without.])
+fi
+fi
+
+AM_CONDITIONAL(RPATH, [test "x$enable_rpath" != "xno"])
+AS_IF([test "x$enable_rpath" = "xno"],
+  [AC_MSG_WARN([Disabling rpath prevents libdw from automatically
+finding the ebl backends.])
+   enable_rpath=no],[enable_rpath=yes])
+
 AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl
 # Use the same flags that we use for our DSOs, so the test is representative.
 # Some old compiler/linker/libc combinations fail some ways and not others.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 79cce5ce..8020c569 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Don't set rpath if it's disabled.
+
 2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Drop libdw_so_SOURCES.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index af7d7793..3257c014 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -99,6 +99,12 @@ $(srcdir)/known-dwarf.h: 
$(top_srcdir)/config/known-dwarf.awk $(srcdir)/dwarf.h
mv -f $@.new $@
 endif
 
+if RPATH
+PKG_RPATH = -Wl,--enable-new-dtags,-rpath,$(pkglibdir)
+else
+PKG_RPATH =
+endif
+
 libdw_pic_a_SOURCES =
 am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
 
@@ -111,7 +117,7 @@ libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) 
$(libdw_so_DEPS)
 # not fly in a setuid executable that links in libdw.
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$@.$(VERSION) \
-   -Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
+   $(PKG_RPATH) \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \
$(libdw_so_LDLIBS)
-- 
2.11.0



[PATCH] Drop *_so_SOURCES from libasm, libdw, libelf Makefile.am

2017-08-18 Thread Ulf Hermann
They aren't used and cause warnings from autoconf.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libasm/ChangeLog   | 4 
 libasm/Makefile.am | 1 -
 libdw/ChangeLog| 4 
 libdw/Makefile.am  | 1 -
 libelf/ChangeLog   | 4 
 libelf/Makefile.am | 1 -
 6 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index fffcced0..fb282e3e 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Drop libasm_so_SOURCES.
+
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use dso_LDFLAGS.
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 19fef508..29d2efee 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -62,7 +62,6 @@ libasm_so_LDLIBS += -lpthread
 endif
 
 libasm_so_LIBS = libasm_pic.a
-libasm_so_SOURCES =
 libasm.so$(EXEEXT): $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$@.$(VERSION) \
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 94e9c9ab..79cce5ce 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,9 @@
 2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * Makefile.am: Drop libdw_so_SOURCES.
+
+2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
+
* memory-access.h: Use attribute_packed.
 
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 8ee46802..af7d7793 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -106,7 +106,6 @@ 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_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.
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 7bd9e1bc..23484499 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,9 @@
 2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * Makefile.am: Drop libelf_so_SOURCES.
+
+2017-08-18  Ulf Hermann  <ulf.herm...@qt.io>
+
* gelf_xlate.c: Use attribute_packed.
 
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index ddaeaa2b..a749a1bb 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -102,7 +102,6 @@ libelf_so_LDLIBS += -lpthread
 endif
 
 libelf_so_LIBS = libelf_pic.a
-libelf_so_SOURCES =
 libelf.so$(EXEEXT): $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$@.$(VERSION) \
-- 
2.11.0



[PATCH v2] Check if gcc complains about __attribute__ (visibility(..))

2017-08-18 Thread Ulf Hermann
If so, define attribute_hidden to be empty. Also, use attribute_hidden
in all places where we hide symbols. If this attribute is missing, it
simply means that we cannot hide private symbols in the binary using
attributes. This disables some optimizations and may increase the risk 
of symbol name clashes with other libraries, but is not fatal. 

However, we still employ linker version scripts to explicitly define 
the exported symbols. This serves much of the same purpose. Also, as
all our symbols are prefixed with the library name, and "__" for 
private ones, the chance of clashes is low anyway.

(I'm reposting this patch, rebased and with extended commit message. v1
was apparently not accepted because the patch's implications were
misunderstood.)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  5 +
 configure.ac| 16 
 lib/ChangeLog   |  5 +
 lib/eu-config.h |  4 
 libdw/ChangeLog |  5 +
 libdw/libdwP.h  |  2 +-
 libdw/libdw_alloc.c |  2 +-
 libelf/ChangeLog|  4 
 libelf/libelfP.h|  2 +-
 9 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 62146227..84fd2555 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check if the compiler supports
+   __attribute__((visibility(...))).
+
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs,
and -Wl,-z,relro are supported by the compiler.
 
diff --git a/configure.ac b/configure.ac
index e6e3b675..c4fc7e3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,6 +127,22 @@ CFLAGS="$old_CFLAGS"])
 AS_IF([test "x$ac_cv_c99" != xyes],
   AC_MSG_ERROR([gcc with GNU99 support required]))
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))],
+   ac_cv_visibility, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+int __attribute__((visibility("hidden")))
+foo (int a)
+{
+  return a;
+}])], ac_cv_visibility=yes, ac_cv_visibility=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_visibility" = "yes"; then
+   AC_DEFINE([HAVE_VISIBILITY], [1],
+ [Defined if __attribute__((visibility())) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
 save_CFLAGS="$CFLAGS"
 CFLAGS="$save_CFLAGS -fPIC -Werror"
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 67ef2792..23c0f41b 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * eu-config.h: Define attribute_hidden to be empty if the compiler
+   doesn't support it.
+
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use fpic_CFLAGS.
 
 2017-07-18  Mark Wielaard  <m...@klomp.org>
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 400cdc6e..07098282 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -68,8 +68,12 @@
 #define internal_strong_alias(name, aliasname) \
   extern __typeof (name) aliasname __attribute__ ((alias (#name))) 
internal_function;
 
+#ifdef HAVE_VISIBILITY
 #define attribute_hidden \
   __attribute__ ((visibility ("hidden")))
+#else
+#define attribute_hidden /* empty */
+#endif
 
 /* Define ALLOW_UNALIGNED if the architecture allows operations on
unaligned memory locations.  */
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 67d7799d..c13344af 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,10 @@
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * libdwP.h: Use attribute_hidden.
+   * libdw_alloc.c: Likewise.
+
+2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
 
 2017-07-26  Mark Wielaard  <m...@klomp.org>
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 6ad322c1..78c00132 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -434,7 +434,7 @@ extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, 
size_t align)
  __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
 
 /* Default OOM handler.  */
-extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
+extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden;
 
 /* Allocate the internal data for a unit not seen before.  */
 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c
index 28a8cf6e..d6af23a2 100644
--- a/libdw/libdw_alloc.c
+++ b/libdw/libdw_alloc.c
@@ -70,7 +70,7 @@ dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler)
 
 
 void
-__attribute ((noreturn, visibility ("hidden")))
+__attribute ((noreturn)) attribute_hidden
 __libdw_oom (void)
 {
   whi

[PATCH v3] Check for -z,defs, -z,relro, -fPIC, -fPIE before using them

2017-08-18 Thread Ulf Hermann
Those flags are not available on all platforms, and omitting them when
not available will not cause any harm. In particular:

-z,defs disallows undefined symbols in object files. This option is
unsupported if the target binary format enforces the same condition
already. Furthermore it is only a compile time sanity check. When it is
omitted, the same binary is produced.

-z,relro instructs the loader to mark sections read-only after loading
the library, where possible. This is a hardening mechanism. If it is
unavailable, the functionality of the code is not affected in any way.

-fPIC instructs the compiler to produce position independent code. While
this is preferable to relocatable code, relocatable code also works and
may even be faster. Relocatable code might just be loaded into memory
multiple times for different processes.

-fPIE is the same thing as -fPIC for executables rather than shared
libraries.

(I'm reposting this patch, rebased to not depend on any others, with 
extended commit message. v2 was apparently not accepted because the
patch's implications were misunderstood.)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog|  5 +
 backends/ChangeLog   |  4 
 backends/Makefile.am |  4 ++--
 config/ChangeLog |  4 
 config/eu.am |  4 ++--
 configure.ac | 56 ++--
 lib/ChangeLog|  4 
 lib/Makefile.am  |  2 +-
 libasm/ChangeLog |  4 
 libasm/Makefile.am   |  4 ++--
 libcpu/ChangeLog |  4 
 libcpu/Makefile.am   |  2 +-
 libdw/ChangeLog  |  4 
 libdw/Makefile.am|  6 +++---
 libebl/ChangeLog |  4 
 libebl/Makefile.am   |  2 +-
 libelf/ChangeLog |  4 
 libelf/Makefile.am   |  6 +++---
 tests/ChangeLog  |  4 
 tests/Makefile.am|  4 ++--
 20 files changed, 112 insertions(+), 19 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9253c0a3..62146227 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs,
+   and -Wl,-z,relro are supported by the compiler.
+
 2017-08-02  Mark Wielaard  <m...@klomp.org>
 
* configure.ac: Set version to 0.170.
diff --git a/backends/ChangeLog b/backends/ChangeLog
index a66e923e..79b50ebf 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann <ulf.herm...@qt.io>
+
+   * Makefile.am: Use dso_LDFLAGS.
+
 2017-07-27  Mark Wielaard  <m...@klomp.org>
 
* sparc_reloc.def: GOTDATA_OP_HIX22, GOTDATA_OP_LOX10 and
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 37dc2d20..0fde0cb0 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -129,10 +129,10 @@ 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) \
+   $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-Wl,--version-script,$(@:.so=.map),--no-undefined \
-   -Wl,-z,defs,-z,relro -Wl,--as-needed $(libelf) $(libdw) $(libeu)
+   -Wl,--as-needed $(libelf) $(libdw) $(libeu)
@$(textrel_check)
 
 libebl_i386.so: $(cpu_i386)
diff --git a/config/ChangeLog b/config/ChangeLog
index 02cf76f9..1ed3c4af 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eu.am: Use fpic_CFLAGS.
+
 2016-08-02  Mark Wielaard  <m...@klomp.org>
 
* elfutils.spec.in: Update for 0.170.
diff --git a/config/eu.am b/config/eu.am
index 8fe1e259..796f3883 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -86,14 +86,14 @@ endif
 
 %.os: %.c %.o
 if AMDEP
-   $(AM_V_CC)if $(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) -MT $@ -MD -MP \
+   $(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ 
-MD -MP \
  -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
 rm -f "$(DEPDIR)/$*.Tpo"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
 else
-   $(AM_V_CC)$(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) $<
+   $(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $<
 endif
 
 CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index 1f1856df..e6e3b675 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,13 +127,65 @@ CFLAGS="$old_CFLAGS"])
 AS_IF([test "x$ac_cv_c99" != xyes],
   AC_MSG_ERROR([gcc with GNU99 support required]))
 
+AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
+save_CFLAGS="$CFLAGS&qu

Problems in dwfl_segment_report_module

2017-05-10 Thread Ulf Hermann
Hi,

In dwfl_segment_report_module.c:657ff we have this heuristic to determine if an 
elf is invalid:

  if ((module_end > module->start && module_start < module->end)
|| dyn_vaddr == module->l_ld)
  {
if (module->elf != NULL
&& invalid_elf (module->elf, module->disk_file_has_build_id,
build_id, build_id_len))
  {
elf_end (module->elf);
close (module->fd);
module->elf = NULL;
[...]

As far as I understand, module_start, module_end, module->start and module->end 
are the runtime mmap'd positions of the loaded elf file. The problem with this 
is that multiple elfs can be mmap'd on top of one another. That frequently 
happens. For example ld.so is always overwritten at some point. If we retrieve 
the positions of the overwritten mmaps from e.g. a core file, then we can 
attribute them to the wrong elf file, find that the build ID is "wrong" and 
discard the elf. This makes the run-backtrace-native-core.sh test fail for me 
in sometimes. linux-vdso.so is apparently mapped underneath backtrace-child and 
consequently backtrace-child gets discarded. Then we cannot unwind anything.

regards,
Ulf


[PATCH 2/2] Don't overflow in __libdw_in_section

2017-05-09 Thread Ulf Hermann
This exposes a bug in dwarf_formstring as detected by the dwarf-getmacros
test. We cannot unconditionally assume that a string is in either the
IDX_debug_info or the IDX_debug_types section as determined by
cu_sec_idx.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdw/ChangeLog | 4 
 libdw/libdwP.h  | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 665c232..a5c1ff0 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-09  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * libdwP.h: Fix check for the upper border of the range in 
__libdw_in_section.
+
+2017-05-09  Ulf Hermann  <ulf.herm...@qt.io>
+
* dwarf_getmacros.c: Initialize type_offset of the fake CU.
 
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index cefcafd..b87a94b 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -642,7 +642,8 @@ __libdw_in_section (Dwarf *dbg, int sec_index,
   if (data == NULL)
 return false;
   if (unlikely (addr < data->d_buf)
-  || unlikely (data->d_size - (addr - data->d_buf) < size))
+  || unlikely (data->d_size < size)
+  || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
 {
   __libdw_seterrno (DWARF_E_INVALID_OFFSET);
   return false;
-- 
2.1.4



[PATCH 1/2] Initialize type_offset of fake_cu

2017-05-09 Thread Ulf Hermann
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdw/ChangeLog | 4 
 libdw/dwarf_getmacros.c | 1 +
 2 files changed, 5 insertions(+)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index eda35c5..665c232 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-09  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * dwarf_getmacros.c: Initialize type_offset of the fake CU.
+
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use the predefined common library names rather than
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index eb50508..9e2a4a1 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -361,6 +361,7 @@ read_macros (Dwarf *dbg, int sec_index,
.offset_size = table->is_64bit ? 8 : 4,
.startp = (void *) startp + offset,
.endp = (void *) endp,
+   .type_offset = 0,
   };
 
   Dwarf_Attribute *attributes;
-- 
2.1.4



Re: Problems with dwarf-getmacros test

2017-05-09 Thread Ulf Hermann

Do you have the whole call stack of that failed __libdw_read_offset
call? Which source line in tests/dwarf-getmacros.c prints the "(null)"?


Actually I just managed to catch a backtrace by inserting an infinite
loop at the point where it would normally return -1. It turns out the
address we are looking for is not in the IDX_debug_info section, but in
the IDX_debug_macro section (which by itself isn't all that surprising,
but if that is a rule, how can this code ever work??).


The likely solution of the mystery is this piece of code in 
__libdw_in_section:


if (unlikely (addr < data->d_buf)
  || unlikely (data->d_size - (addr - data->d_buf) < size))
{
  __libdw_seterrno (DWARF_E_INVALID_OFFSET);
  return false;
}

If addr < data->d_buf we fail immediately. That's what's happening to me 
sometimes. However, if addr > data->d_buf, then it's likely much bigger, 
as the allocations of the different sections are unrelated. data->d_size 
is always 159 in this test case. Therefore, data->d_size - (addr - 
data->d_buf) will produce something negative, which then gets compared 
to a size_t, forcing it to overflow. size is 4, so this case never gets 
detected.


Ulf


Re: Problems with dwarf-getmacros test

2017-05-09 Thread Ulf Hermann

Do you have the whole call stack of that failed __libdw_read_offset
call? Which source line in tests/dwarf-getmacros.c prints the "(null)"?


Actually I just managed to catch a backtrace by inserting an infinite 
loop at the point where it would normally return -1. It turns out the 
address we are looking for is not in the IDX_debug_info section, but in 
the IDX_debug_macro section (which by itself isn't all that surprising, 
but if that is a rule, how can this code ever work??).


Thread 1 (Thread 220048.0x35af0):
#0  0x70ec311e in __libdw_read_offset (sec_ret=8, size=1, 
ret=, width=4, addr=0xe90089 ".\027", sec_index=0, 
dbg_ret=, dbg=) at 
D:/qtcreator-super-master/elfutils/libdw/libdwP.h:712

orig_addr = 
#1  dwarf_formstring (attrp=attrp@entry=0x6af950) at 
D:/qtcreator-super-master/elfutils/libdw/dwarf_formstring.c:69

dbg = 
dbg_ret = 
off = 
#2  0x70ecc709 in dwarf_macro_param2 
(macro=macro@entry=0x6afaa0, paramp=paramp@entry=0x0, 
strp=strp@entry=0x6af9f0) at 
D:/qtcreator-super-master/elfutils/libdw/dwarf_macro_param2.c:50
param = {code = 8473, form = 14, valp = 0xe90089 ".\027", cu = 
0x6afac0}
#3  0x00401784 in mac (macro=0x6afaa0, dbg=0xf926f0) at 
D:/qtcreator-super-master/elfutils/tests/dwarf-getmacros.c:87

value = 0xf927b8 "p?ù"
level = 0
opcode = 5
#4  0x70ecbf1d in read_macros (dbg=dbg@entry=0xf926f0, 
sec_index=sec_index@entry=10, macoff=macoff@entry=0, callback=out>, callback@entry=0x4015e0 , arg=, 
offset=, offset@entry=0, accept_0xff=, 
accept_0xff@entry=false, cudie=, cudie@entry=0x6afe10) at 
D:/qtcreator-super-master/elfutils/libdw/dwarf_getmacros.c:409

opcode = 
idx = 
attributesp = 
nattributes = {{code = 8473, form = 15, valp = 0xe90088 
"\001.\027", cu = 0x6afac0}, {code = 8473, form = 14, valp = 0xe90089 
".\027", cu = 0x6afac0}, {code = 0, form = 0, valp = 0x0, cu = 0x0}, 
{code = 0, form = 0, valp = 0x0, cu = 0x0}, {code = 0, form = 0, valp = 
0x0, cu = 0x0}, {code = 0, form = 0, valp = 0x0, cu = 0x0}, {code = 0, 
form = 0, valp = 0x0, cu = 0x0}, {code = 0, form = 0, valp = 0x0, cu = 0x0}}
fake_cu = {dbg = 0xf926f0, start = 0, end = 0, address_size = 0 
'\000', offset_size = 4 '\004', version = 4, type_offset = 0, type_sig8 
= 0, abbrev_hash = {size = 0, filled = 0, table = 0x0}, 
orig_abbrev_offset = 0, last_abbrev_offset = 0, lines = 0x0, files = 
0x0, locs = 0x0, startp = 0xe90087, endp = 0xe90ac4}

attributes = 
macro = {table = 0xf928b0, attributes = 0x6afb40, opcode = 5 
'\005'}

res = 
d = 
startp = 
endp = 
readp = 0xe9008d "\005\001î!"
#5  0x70ecc302 in gnu_macros_getmacros_off (dbg=0xf926f0, 
macoff=0, callback=callback@entry=0x4015e0 , 
arg=arg@entry=0xf926f0, offset=offset@entry=0, 
accept_0xff=accept_0xff@entry=false, cudie=cudie@entry=0x6afe10) at 
D:/qtcreator-super-master/elfutils/libdw/dwarf_getmacros.c:478

No locals.
#6  0x70ecc502 in dwarf_getmacros (cudie=cudie@entry=0x6afe10, 
callback=callback@entry=0x4015e0 , arg=arg@entry=0xf926f0, token=0) 
at D:/qtcreator-super-master/elfutils/libdw/dwarf_getmacros.c:564

macoff = 0
accept_0xff = false
offset = 
#7  0x00409a36 in main (argc=3, argv=) at 
D:/qtcreator-super-master/elfutils/tests/dwarf-getmacros.c:133

off = 
name = 
cuoff = 
new_style = 
fd = 
dbg = 0xf926f0
cudie_mem = {addr = 0xf93a5b, cu = 0xf92810, abbrev = 0xf92890, 
padding__ = 0}

cudie = 0x6afe10


Re: Problems with dwarf-getmacros test

2017-05-09 Thread Ulf Hermann
> Is it only with testfile-macros?
> All other testfiles always run correctly?

Yes, it only happens with the testfile-macros check at 0xb.

> Do you have the whole call stack of that failed __libdw_read_offset
> call? Which source line in tests/dwarf-getmacros.c prints the "(null)"?

I'm having a hard time triggering the problem in a controlled environment. So 
far I didn't manage to create a stack trace. The (null) is the result of 
passing a value of null to dwarf-getmacros.c:88. I get an errno of 
DWARF_E_INVALID_OFFSET at the assert failure. So I put some debug messages into 
all places where that is generated and this is how I found the source of this. 
It seems I can't trigger the effect if I put the debug output directly into 
__libdw_in_section (but maybe I was just very unlucky). If I put it in 
READ_AND_RELOCATE I can see that the check always fails before it outputs 
(null) or hits the assertion.

>> Experiments show that the address is 
>> frequently not in the section we're checking there, but still valid. 
>> Just dropping the check makes the test succeed.
> 
> I think this might be related to our "fake" CU and attributes we invent
> in libdw/dwarf_getmacros.c (read_macros). See around this comment:
> 
>   /* We pretend this is a DW_AT_GNU_macros attribute so that
>  DW_FORM_sec_offset forms get correctly interpreted as
>  offset into .debug_macro.  */
> 
> If that is the issue then we might need to somehow make
> READ_AND_RELOCATE and/or __libdw_in_section aware that the CU is fake
> and the check isn't needed. In which case we probably need to add some
> flag "fake" to the CU and pass the CU to the various __libdw_read_*
> functions to disable that sanity check in READ_AND_RELOCATE.

We don't set type_offset on the fake_cu, but we read it via cu_sec_idx when 
calling __libdw_read_offset from dwarf_formstring. This seems wrong.

Ulf


Problems with dwarf-getmacros test

2017-05-08 Thread Ulf Hermann

Hi,

I frequently get failures from the run-dwarf-getmacros.sh test, on 
testfile-macros:0xb. The test repeatedly outputs "(null)" instead of the 
actual macros and then runs into the assert at dwarf-getmacros.c:50. The 
failure is very nondeterministic, though. I haven't found a reliable way 
to trigger it.


Further examination reveals that the __libdw_in_section check in 
READ_AND_RELOCATE (libdwP.h:656), when called from __libdw_read_offset 
seems to be bogus. The "return -1" in there is what produces the null 
results and ultimately the assert. Experiments show that the address is 
frequently not in the section we're checking there, but still valid. 
Just dropping the check makes the test succeed.


I'm currently at a loss about why this happens. One thing that strikes 
me was that the additional dbg_ret mechamism was added in 2012 with 
commit 775375e3, but the check in READ_AND_RELOCATE was not adapted then.


However, the address is also not necessarily in dbg_ret at that point. 
Checking dbg_ret in addition to dbg still fails sometimes, and also that 
wouldn't explain the nondeterminism.


Ulf


[PATCH] On non-linux systems, don't use native signal numbers

2017-05-08 Thread Ulf Hermann

We assume core files from linux systems, so we should use the linux
version of the signals when reading them. Other OS might have different
signal numbers.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/readelf.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/readelf.c b/src/readelf.c
index 6811ace..01d2a56 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -57,6 +57,21 @@
  #include "../libdw/known-dwarf.h"
 +#ifdef __linux__
+#define CORE_SIGILL  SIGILL
+#define CORE_SIGBUS  SIGBUS
+#define CORE_SIGFPE  SIGFPE
+#define CORE_SIGSEGV SIGSEGV
+#define CORE_SI_USER SI_USER
+#else
+/* We want the linux version of those as that is what shows up in the 
core files. */

+#define CORE_SIGILL  4  /* Illegal instruction (ANSI).  */
+#define CORE_SIGBUS  7  /* BUS error (4.2 BSD).  */
+#define CORE_SIGFPE  8  /* Floating-point exception (ANSI).  */
+#define CORE_SIGSEGV 11 /* Segmentation violation (ANSI).  */
+#define CORE_SI_USER 0  /* Sent by kill, sigsend.  */
+#endif
+
  /* Name and version of program.  */
 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
@@ -9244,10 +9259,10 @@ handle_siginfo_note (Elf *core, GElf_Word 
descsz, GElf_Off desc_pos)

   if (si_code > 0)
 switch (si_signo)
   {
-  case SIGILL:
-  case SIGFPE:
-  case SIGSEGV:
-  case SIGBUS:
+  case CORE_SIGILL:
+  case CORE_SIGFPE:
+  case CORE_SIGSEGV:
+  case CORE_SIGBUS:
{
  uint64_t addr;
  if (! buf_read_ulong (core, , end, ))
@@ -9258,7 +9273,7 @@ handle_siginfo_note (Elf *core, GElf_Word descsz, 
GElf_Off desc_pos)

   default:
;
   }
-  else if (si_code == SI_USER)
+  else if (si_code == CORE_SI_USER)
 {
   int pid, uid;
   if (! buf_read_int (core, , end, )
--
2.8.1.windows.1



[PATCH v2] Cast pid_t to long long when printing

2017-05-08 Thread Ulf Hermann

On windows x86_64 pid_t is 64bit wide. We need to adapt our printf
format respectively.

(We can actually print the extra bits in a portable way, so let's do it 
rather than casting to int and ignoring them.)


Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog |  4 
 src/stack.c   | 22 +++---
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index a474331..1c67b57 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 +  * stack.c: Cast pid_t to int when printing using %d.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* strip.c: Close and reopen file when renaming.
  2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/src/stack.c b/src/stack.c
index 1f5a1c6..da912e5 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -362,7 +362,7 @@ print_frames (struct frames *frames, pid_t tid, int 
dwflerr, const char *what)

   if (frames->frames > 0)
 frames_shown = true;
 -  printf ("TID %d:\n", tid);
+  printf ("TID %lld:\n", (long long)tid);
   int frame_nr = 0;
   for (int nr = 0; nr < frames->frames && (maxframes == 0
   || frame_nr < maxframes); nr++)
@@ -419,8 +419,8 @@ print_frames (struct frames *frames, pid_t tid, int 
dwflerr, const char *what)

 }
if (frames->frames > 0 && frame_nr == maxframes)
-error (0, 0, "tid %d: shown max number of frames "
-  "(%d, use -n 0 for unlimited)", tid, maxframes);
+error (0, 0, "tid %lld: shown max number of frames "
+  "(%d, use -n 0 for unlimited)", (long long)tid, maxframes);
   else if (dwflerr != 0)
 {
   if (frames->frames > 0)
@@ -440,11 +440,11 @@ print_frames (struct frames *frames, pid_t tid, 
int dwflerr, const char *what)

  else
modname = "";
}
- error (0, 0, "%s tid %d at 0x%" PRIx64 " in %s: %s", what, tid,
+	  error (0, 0, "%s tid %lld at 0x%" PRIx64 " in %s: %s", what, (long 
long)tid,

 pc_adjusted, modname, dwfl_errmsg (dwflerr));
}
   else
-   error (0, 0, "%s tid %d: %s", what, tid, dwfl_errmsg (dwflerr));
+	error (0, 0, "%s tid %lld: %s", what, (long long)tid, dwfl_errmsg 
(dwflerr));

 }
 }
 @@ -575,10 +575,10 @@ parse_opt (int key, char *arg __attribute__ 
((unused)),

  int err = dwfl_linux_proc_report (dwfl, pid);
  if (err < 0)
-   error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %d: %s", pid,
+	error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %lld: %s", (long 
long)pid,

   dwfl_errmsg (-1));
  else if (err > 0)
-   error (EXIT_BAD, err, "dwfl_linux_proc_report pid %d", pid);
+	error (EXIT_BAD, err, "dwfl_linux_proc_report pid %lld", (long 
long)pid);

}
if (core != NULL)
@@ -597,10 +597,10 @@ parse_opt (int key, char *arg __attribute__ 
((unused)),

{
  int err = dwfl_linux_proc_attach (dwfl, pid, false);
  if (err < 0)
-   error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %d: %s", pid,
+	error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %lld: %s", (long 
long)pid,

   dwfl_errmsg (-1));
  else if (err > 0)
-   error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %d", pid);
+	error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %lld", (long 
long)pid);

}
if (core != NULL)
@@ -688,7 +688,7 @@ invoked with bad or missing arguments it will exit 
with return code 64.")

if (show_modules)
 {
-  printf ("PID %d - %s module memory map\n", dwfl_pid (dwfl),
+  printf ("PID %lld - %s module memory map\n", (long long)dwfl_pid 
(dwfl),

  pid != 0 ? "process" : "core");
   if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0)
error (EXIT_BAD, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
@@ -721,7 +721,7 @@ invoked with bad or missing arguments it will exit 
with return code 64.")

 }
   else
 {
-  printf ("PID %d - %s\n", dwfl_pid (dwfl), pid != 0 ? "process" : 
"core");
+  printf ("PID %lld - %s\n", (long long)dwfl_pid (dwfl), pid != 0 ? 
"process" : "core");

   switch (dwfl_getthreads (dwfl, thread_callback, ))
{
case DWARF_CB_OK:
--
2.8.1.windows.1



Re: windows patches

2017-05-08 Thread Ulf Hermann
Hi Mark,

> Thanks a lot for all your work and posting the patches.
> I will go through them next week.

Thanks for reviewing them. The ones that got accepted will already make my life 
easier.

> I quickly scanned some just now. Some seem fine to go in. But others are
> a bit more iffy. I think some should really go towards gnulib if we are
> going to use that anyway so other projects get the same portability
> benefits. 

Let's do the easy ones first. I will handle the gnulib and glibc material when 
I get back in fall.

> And I do worry a bit about others, like the O_BINARY one for
> example that patches every open call. That seems impossible to properly
> maintain and is clearly intended for a platform that is really not even
> POSIX/Unix-like.

If we want elfutils to work on windows, we need to take care of the text vs. 
binary issue somehow. If you open a file in text mode, any "\n" not prefixed by 
"\r" will be replaced with "\r\n" when reading or writing. This is quite 
disastrous. I couldn't come up with anything better than just adding O_BINARY 
everywhere. If there is a better way, I'll be happy to change the code.

cheers,
Ulf


[PATCH v2] Avoid using err() and errx() in tests

2017-05-08 Thread Ulf Hermann
fprintf() and exit() do the same job and are portable.

(v1 was missing the errno.h include in allfcts.c)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog  |  6 ++
 tests/allfcts.c  | 47 ---
 tests/buildid.c  |  6 +++---
 tests/debugaltlink.c |  6 +++---
 4 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index 6dab801..c2619d0 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * allfcts.c: Use fprintf and exit rather than err and errx.
+   * buildid.c: Likewise.
+   * debugaltlink.c: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* elfstrmerge.c: Don't fchmod or fchown the output file if fchmod or
fchown don't exist.
 
diff --git a/tests/allfcts.c b/tests/allfcts.c
index d3c8d26..84ac53d 100644
--- a/tests/allfcts.c
+++ b/tests/allfcts.c
@@ -18,12 +18,14 @@
 # include 
 #endif
 
-#include 
+#include 
 #include 
 #include ELFUTILS_HEADER(dw)
 #include ELFUTILS_HEADER(dwelf)
 #include 
 #include 
+#include 
+#include 
 
 
 static int
@@ -47,16 +49,24 @@ setup_alt (Dwarf *main)
   ssize_t ret = dwelf_dwarf_gnu_debugaltlink (main, _name, _id);
   if (ret == 0)
 return NULL;
-  if (ret == -1)
-errx (1, "dwelf_dwarf_gnu_debugaltlink: %s", dwarf_errmsg (-1));
+  if (ret == -1) {
+fprintf (stderr, "allfcts: dwelf_dwarf_gnu_debugaltlink: %s\n", 
dwarf_errmsg (-1));
+exit(1);
+  }
   int fd = open (alt_name, O_RDONLY);
-  if (fd < 0)
-err (1, "open (%s)", alt_name);
+  if (fd < 0) {
+fprintf (stderr, "allfcts: open (%s): %s\n", alt_name, strerror(errno));
+exit(1);
+  }
   Dwarf *dbg_alt = dwarf_begin (fd, DWARF_C_READ);
-  if (dbg_alt == NULL)
-errx (1, "dwarf_begin (%s): %s", alt_name, dwarf_errmsg (-1));
-  if (elf_cntl (dwarf_getelf (dbg_alt), ELF_C_FDREAD) != 0)
-errx (1, "elf_cntl (%s, ELF_C_FDREAD): %s", alt_name, elf_errmsg (-1));
+  if (dbg_alt == NULL) {
+fprintf (stderr, "dwarf_begin (%s): %s\n", alt_name, dwarf_errmsg (-1));
+exit(1);
+  }
+  if (elf_cntl (dwarf_getelf (dbg_alt), ELF_C_FDREAD) != 0) {
+fprintf (stderr, "elf_cntl (%s, ELF_C_FDREAD): %s\n", alt_name, elf_errmsg 
(-1));
+exit(1);
+  }
   close (fd);
   dwarf_setalt (main, dbg_alt);
   return dbg_alt;
@@ -68,8 +78,10 @@ main (int argc, char *argv[])
   for (int i = 1; i < argc; ++i)
 {
   int fd = open (argv[i], O_RDONLY);
-  if (fd < 0)
-   err (1, "open (%s)", argv[i]);
+  if (fd < 0) {
+   fprintf (stderr, "open (%s): %s\n", argv[i], strerror(errno));
+   exit(1);
+  }
 
   Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
   if (dbg != NULL)
@@ -89,9 +101,11 @@ main (int argc, char *argv[])
  do
{
  doff = dwarf_getfuncs (die, cb, NULL, doff);
- if (dwarf_errno () != 0)
-   errx (1, "dwarf_getfuncs (%s): %s",
- argv[i], dwarf_errmsg (-1));
+ if (dwarf_errno () != 0) {
+   fprintf (stderr, "dwarf_getfuncs (%s): %s\n",
+argv[i], dwarf_errmsg (-1));
+   exit(1);
+ }
}
  while (doff != 0);
 
@@ -102,7 +116,10 @@ main (int argc, char *argv[])
  dwarf_end (dbg);
}
   else
-   errx (1, "dwarf_begin (%s): %s", argv[i], dwarf_errmsg (-1));
+{
+ fprintf (stderr, "dwarf_begin (%s): %s\n", argv[i], dwarf_errmsg 
(-1));
+ exit(1);
+   }
 
   close (fd);
 }
diff --git a/tests/buildid.c b/tests/buildid.c
index 87c1877..2d33402 100644
--- a/tests/buildid.c
+++ b/tests/buildid.c
@@ -18,7 +18,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include ELFUTILS_HEADER(elf)
 #include ELFUTILS_HEADER(dwelf)
@@ -62,8 +61,9 @@ main (int argc, char *argv[])
  printf ("%s: \n", file);
  break;
case -1:
- errx (1, "dwelf_elf_gnu_build_id (%s): %s",
-   file, elf_errmsg (-1));
+ fprintf (stderr, "dwelf_elf_gnu_build_id (%s): %s\n",
+  file, elf_errmsg (-1));
+ return 1;
default:
  printf ("%s: build ID: ", file);
  const unsigned char *p = build_id;
diff --git a/tests/debugaltlink.c b/tests/debugaltlink.c
index 6d97d50..b470e31 100644
--- a/tests/debugaltlink.c
+++ b/tests/debugaltlink.c
@@ -18,7 +18,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include ELFUTILS_HEADER(dw)
 #include ELFUTILS_HEADER(dwelf)
@@ -64,8 +63,9 @@ main (int argc, char *argv[])
  printf ("%s: \n", file);
  break;
   

[PATCH] Use trees rather than hashes in ar.c

2017-05-04 Thread Ulf Hermann
The tree functions are more widely available.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog |  4 
 src/ar.c  | 77 ++-
 2 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 332b07c..32cd0c3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * ar.c: Use trees rather than hashes.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* ar.c: Use octal numbers instead of permission macros.
* elfcompress.c: Likewise.
* ranlib.c: Likewise.
diff --git a/src/ar.c b/src/ar.c
index cc47f10..a13420c 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -439,6 +439,20 @@ copy_content (Elf *elf, int newfd, off_t off, size_t n)
 
 
 static int
+string_compare (const void *a, const void *b)
+{
+  return strcmp((const char *)a, (const char *)b);
+}
+
+
+void
+free_node (void *node)
+{
+  (void) node;
+}
+
+
+static int
 do_oper_extract (int oper, const char *arfname, char **argv, int argc,
 long int instance)
 {
@@ -469,13 +483,11 @@ do_oper_extract (int oper, const char *arfname, char 
**argv, int argc,
   Elf *elf;
   int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, , NULL, false);
 
-  if (hcreate (2 * argc) == 0)
-error (EXIT_FAILURE, errno, gettext ("cannot create hash table"));
+  void *root = NULL;
 
   for (int cnt = 0; cnt < argc; ++cnt)
 {
-  ENTRY entry = { .key = argv[cnt], .data = [cnt] };
-  if (hsearch (entry, ENTER) == NULL)
+  if (tsearch (argv[cnt], , _compare) == NULL)
error (EXIT_FAILURE, errno,
   gettext ("cannot insert into hash table"));
 }
@@ -517,12 +529,10 @@ do_oper_extract (int oper, const char *arfname, char 
**argv, int argc,
   bool do_extract = argc <= 0;
   if (!do_extract)
{
- ENTRY entry;
- entry.key = arhdr->ar_name;
- ENTRY *res = hsearch (entry, FIND);
+ void *res = tfind (arhdr->ar_name, , _compare);
  if (res != NULL && (instance < 0 || instance-- == 0)
- && !found[(char **) res->data - argv])
-   found[(char **) res->data - argv] = do_extract = true;
+ && !found[(char **) res - argv])
+   found[(char **) res - argv] = do_extract = true;
}
 
   if (do_extract)
@@ -741,7 +751,8 @@ cannot rename temporary file to %.*s"),
error (1, 0, "%s: %s", arfname, elf_errmsg (-1));
 }
 
-  hdestroy ();
+  tdestroy(root, _node);
+  root = NULL;
 
   if (force_symtab)
 {
@@ -921,13 +932,11 @@ do_oper_delete (const char *arfname, char **argv, int 
argc,
   struct stat st;
   int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, , , false);
 
-  if (hcreate (2 * argc) == 0)
-error (EXIT_FAILURE, errno, gettext ("cannot create hash table"));
+  void *root = NULL;
 
   for (int cnt = 0; cnt < argc; ++cnt)
 {
-  ENTRY entry = { .key = argv[cnt], .data = [cnt] };
-  if (hsearch (entry, ENTER) == NULL)
+  if (tsearch (argv[cnt], , _compare) == NULL)
error (EXIT_FAILURE, errno,
   gettext ("cannot insert into hash table"));
 }
@@ -949,12 +958,10 @@ do_oper_delete (const char *arfname, char **argv, int 
argc,
   bool do_delete = argc <= 0;
   if (!do_delete)
{
- ENTRY entry;
- entry.key = arhdr->ar_name;
- ENTRY *res = hsearch (entry, FIND);
+ void *res = tfind (arhdr->ar_name, , _compare);
  if (res != NULL && (instance < 0 || instance-- == 0)
- && !found[(char **) res->data - argv])
-   found[(char **) res->data - argv] = do_delete = true;
+ && !found[(char **) res - argv])
+   found[(char **) res - argv] = do_delete = true;
}
 
   if (do_delete)
@@ -995,7 +1002,8 @@ do_oper_delete (const char *arfname, char **argv, int argc,
 
   arlib_finalize ();
 
-  hdestroy ();
+  tdestroy (root, _node);
+  root = NULL;
 
   /* Create a new, temporary file in the same directory as the
  original file.  */
@@ -1093,6 +1101,13 @@ no0print (bool ofmt, char *buf, int bufsize, long int 
val)
 
 
 static int
+basename_compare(const void *a, const void *b)
+{
+  return strcmp(basename((const char *)a), basename((const char *)b));
+}
+
+
+static int
 do_oper_insert (int oper, const char *arfname, char **argv, int argc,
const char *member)
 {
@@ -1100,6 +1115,7 @@ do_oper_insert (int oper, const char *arfname, char 
**argv, int argc,
   Elf *elf;
   struct stat st;
   int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, , , oper != 
oper_move);
+  void *root = NULL;
 
   /* List of the files we keep.  */
   struct armem *all = NULL;
@@ -1127,15 +1143,9 @@ do_oper_insert (int oper, const char *ar

[PATCH v2] Close files before renaming or unlinking them

2017-05-04 Thread Ulf Hermann
On windows we cannot rename or unlink open files.

(strip.c was missing)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libasm/ChangeLog |  4 
 libasm/asm_end.c | 15 +++
 src/ChangeLog|  4 
 src/strip.c  |  5 -
 tests/ChangeLog  |  9 +
 tests/newfile.c  |  7 +--
 tests/newscn.c   |  3 ++-
 tests/update1.c  |  1 +
 tests/update2.c  |  1 +
 tests/update3.c  |  1 +
 tests/update4.c  |  1 +
 11 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 2b499c7..0e67657 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * asm_end.c: Rename the output file only after freeing resources.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* asm_end.c: Don't fchmod the new file if fchmod is unavailable.
 
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index 7fabe94..7891fbb 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -521,16 +521,23 @@ asm_end (AsmCtx_t *ctx)
 }
 #endif
 
+  char *tmp_fname = strdup (ctx->tmp_fname);
+  char *fname = strdup (ctx->fname);
+
+  /* Free the resources.  */
+  __libasm_finictx (ctx);
+
   /* Rename output file.  */
-  if (rename (ctx->tmp_fname, ctx->fname) != 0)
+  result = rename (tmp_fname, fname);
+  free (tmp_fname);
+  free (fname);
+
+  if (result != 0)
 {
   __libasm_seterrno (ASM_E_CANNOT_RENAME);
   return -1;
 }
 
-  /* Free the resources.  */
-  __libasm_finictx (ctx);
-
   return 0;
 }
 
diff --git a/src/ChangeLog b/src/ChangeLog
index 0d1e57d..a474331 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * strip.c: Close and reopen file when renaming.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* addr2line.c: Don't assume unix file system conventions.
* size.c: Likewise.
* strip.c: Likewise.
diff --git a/src/strip.c b/src/strip.c
index 60f6700..99d7dd1 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -2006,7 +2006,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const 
char *fname,
 
   /* Create the real output file.  First rename, then change the
 mode.  */
-  if (rename (tmp_debug_fname, debug_fname) != 0
+  close (debug_fd);
+  int rename_result = rename (tmp_debug_fname, debug_fname);
+  debug_fd = open (debug_fname, O_RDONLY | O_BINARY);
+  if (rename_result != 0 || debug_fd == -1
 #if HAVE_DECL_FCHMOD
  || fchmod (debug_fd, mode) != 0
 #endif
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 5e29f82..b8de138 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,14 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * newfile.c: Close the file when we're done and unlink it afterwards.
+   * newscn.c: Likewise.
+   * update1.c: Likewise.
+   * update2.c: Likewise.
+   * update3.c: Likewise.
+   * update4.c: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* asm-tst4.c: Don't assume unix file system conventions.
* asm-tst5.c: Likewise.
* asm-tst6.c: Likewise.
diff --git a/tests/newfile.c b/tests/newfile.c
index 5eabdcb..a279317 100644
--- a/tests/newfile.c
+++ b/tests/newfile.c
@@ -63,8 +63,6 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   printf ("cannot create temporary file: %m\n");
   exit (1);
 }
-  /* Remove the file when we exit.  */
-  unlink (fname);
 
   elf_version (EV_CURRENT);
   elf = elf_begin (fd, ELF_C_WRITE, NULL);
@@ -166,5 +164,10 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   (void) elf_end (elf);
 }
 
+  close (fd);
+
+  /* Remove the file when we exit.  */
+  unlink (fname);
+
   return result;
 }
diff --git a/tests/newscn.c b/tests/newscn.c
index 466f2f6..de8951d 100644
--- a/tests/newscn.c
+++ b/tests/newscn.c
@@ -46,7 +46,6 @@ main (void)
   fprintf (stderr, "Failed to open fdput file: %s\n", name);
   exit (1);
 }
-  unlink (name);
 
   elf = elf_begin (fd, ELF_C_WRITE, NULL);
   if (elf == NULL)
@@ -62,5 +61,7 @@ main (void)
   elf_end (elf);
   close (fd);
 
+  unlink (name);
+
   return 0;
 }
diff --git a/tests/update1.c b/tests/update1.c
index a571618..548c6d8 100644
--- a/tests/update1.c
+++ b/tests/update1.c
@@ -121,6 +121,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
diff --git a/tests/update2.c b/tests/update2.c
index 3e22879..1dcff3f 100644
--- a/tests/update2.c
+++ b/tests/update2.c
@@ -144,6 +144,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
diff --git a/tests/update3.c b/tests/update3.c
index d619bed..9d4f880 100644
--- a/tests/update3.c
+++ b/tests/u

[PATCH] Define uid_t and gid_t in system-elf-libelf-test.c if necessary

2017-05-04 Thread Ulf Hermann
elf.h does include features.h which should define those. However, on
windows there is no features.h. We have the empty features.h in libgnu
that depends on config.h being included before (which we can't), and the
features.h in lib that is only available when installed in selfcontained
mode. Therefore we need a workaround here.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog| 4 
 tests/system-elf-libelf-test.c | 5 +
 2 files changed, 9 insertions(+)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index 1a77c02..678a882 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -11,6 +11,10 @@
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * system-elf-libelf-test.c: Define uid_t and gid_t on windows.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* elfstrmerge.c: Use 0 instead of ALLPERMS.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/tests/system-elf-libelf-test.c b/tests/system-elf-libelf-test.c
index 7dfe498..d9b9cd5 100644
--- a/tests/system-elf-libelf-test.c
+++ b/tests/system-elf-libelf-test.c
@@ -16,6 +16,11 @@
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+#define uid_t int
+#define gid_t int
+#endif
+
 #include 
 #include 
 #include "../libelf/libelf.h"
-- 
2.1.4



[PATCH] Remove previous test files before running the next round

2017-05-04 Thread Ulf Hermann
strip explicitly creates the new files. This will not work on windows if
the files already exist.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog  | 5 +
 tests/run-strip-reloc.sh | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index f43aeba..1a77c02 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -6,6 +6,11 @@
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * run-strip-reloc.sh: Remove previous testfiles before running the
+   next test.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* elfstrmerge.c: Use 0 instead of ALLPERMS.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
index 50dddbf..f44991d 100755
--- a/tests/run-strip-reloc.sh
+++ b/tests/run-strip-reloc.sh
@@ -32,6 +32,8 @@ runtest() {
   outfile2=out.stripped2
   debugfile2=out.debug2
 
+  rm -f $outfile1 $debugfile1 $outfile2 $debugfile2
+
   testrun ${abs_top_builddir}/src/strip -o $outfile1 -f $debugfile1 $infile ||
   { echo "*** failure strip $infile"; status=1; }
 
-- 
2.1.4



[PATCH] Correctly determine STACKCMD on windows

2017-05-04 Thread Ulf Hermann
error() will only output the file name, but with ".exe" on windows.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog   | 6 ++
 tests/run-stack-d-test.sh | 5 +
 tests/run-stack-demangled-test.sh | 5 +
 tests/run-stack-i-test.sh | 5 +
 4 files changed, 21 insertions(+)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9c04404..f43aeba 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * run-stack-d-test.sh: Correctly detect STACKCMD on windows.
+   * run-stack-demangled-test.sh: Likewise.
+   * run-stack-i-test.sh: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* elfstrmerge.c: Use 0 instead of ALLPERMS.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/tests/run-stack-d-test.sh b/tests/run-stack-d-test.sh
index a9f0380..ef3c6e8 100755
--- a/tests/run-stack-d-test.sh
+++ b/tests/run-stack-d-test.sh
@@ -64,6 +64,11 @@ testfiles testfiledwarfinlines testfiledwarfinlines.core
 # the error message, which we also try to match.
 if test "$elfutils_testrun" = "installed"; then
 STACKCMD=${bindir}/`program_transform stack`
+if test -f ${STACKCMD}.exe; then
+STACKCMD=`program_transform stack`.exe
+fi
+elif test -f ${abs_top_builddir}/src/stack.exe; then
+STACKCMD=stack.exe
 else
 STACKCMD=${abs_top_builddir}/src/stack
 fi
diff --git a/tests/run-stack-demangled-test.sh 
b/tests/run-stack-demangled-test.sh
index c26918f..f6899bb 100755
--- a/tests/run-stack-demangled-test.sh
+++ b/tests/run-stack-demangled-test.sh
@@ -33,6 +33,11 @@ testfiles testfiledwarfinlines testfiledwarfinlines.core
 # the error message, which we also try to match.
 if test "$elfutils_testrun" = "installed"; then
 STACKCMD=${bindir}/`program_transform stack`
+if test -f ${STACKCMD}.exe; then
+STACKCMD=`program_transform stack`.exe
+fi
+elif test -f ${abs_top_builddir}/src/stack.exe; then
+STACKCMD=stack.exe
 else
 STACKCMD=${abs_top_builddir}/src/stack
 fi
diff --git a/tests/run-stack-i-test.sh b/tests/run-stack-i-test.sh
index 3722ab0..a09e46d 100755
--- a/tests/run-stack-i-test.sh
+++ b/tests/run-stack-i-test.sh
@@ -25,6 +25,11 @@ testfiles testfiledwarfinlines testfiledwarfinlines.core
 # the error message, which we also try to match.
 if test "$elfutils_testrun" = "installed"; then
 STACKCMD=${bindir}/`program_transform stack`
+if test -f ${STACKCMD}.exe; then
+STACKCMD=`program_transform stack`.exe
+fi
+elif test -f ${abs_top_builddir}/src/stack.exe; then
+STACKCMD=stack.exe
 else
 STACKCMD=${abs_top_builddir}/src/stack
 fi
-- 
2.1.4



[PATCH] Use octal numbers rather than permission macros

2017-05-04 Thread Ulf Hermann
The permission macros are not guaranteed to be defined and the octal
numbers are rather well known.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog   | 7 +++
 src/ar.c| 8 
 src/elfcompress.c   | 4 ++--
 src/ranlib.c| 2 +-
 src/strip.c | 2 +-
 tests/ChangeLog | 4 
 tests/elfstrmerge.c | 4 ++--
 7 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 44b4395..15cd55f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * ar.c: Use octal numbers instead of permission macros.
+   * elfcompress.c: Likewise.
+   * ranlib.c: Likewise.
+   * strip.c: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* unstrip.c: Use strndup and free instead of strndupa.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/src/ar.c b/src/ar.c
index 91391b1..cc47f10 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -799,7 +799,7 @@ cannot rename temporary file to %.*s"),
 #if HAVE_DECL_FCHMOD
  /* Set the mode of the new file to the same values the
 original file has.  */
- fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+ fchmod (newfd, st.st_mode & 0) != 0 ||
 #endif
  (
 #if HAVE_DECL_FCHOWN
@@ -1057,7 +1057,7 @@ do_oper_delete (const char *arfname, char **argv, int 
argc,
 #if HAVE_DECL_FCHMOD
   /* Set the mode of the new file to the same values the original file
  has.  */
-  fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+  fchmod (newfd, st.st_mode & 0) != 0 ||
 #endif
   (
 #if HAVE_DECL_FCHOWN
@@ -1399,7 +1399,7 @@ do_oper_insert (int oper, const char *arfname, char 
**argv, int argc,
 newfd = mkstemp (tmpfname);
   else
 {
-  newfd = open (arfname, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 
DEFFILEMODE);
+  newfd = open (arfname, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0666);
   if (newfd == -1 && errno == EEXIST)
/* Bah, first the file did not exist, now it does.  Restart.  */
return do_oper_insert (oper, arfname, argv, argc, member);
@@ -1521,7 +1521,7 @@ do_oper_insert (int oper, const char *arfname, char 
**argv, int argc,
 #if HAVE_DECL_FCHMOD
   /* Set the mode of the new file to the same values the original file
  has.  */
-  fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+  fchmod (newfd, st.st_mode & 0) != 0 ||
 #endif
  (
 #if HAVE_DECL_FCHOWN
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 5dbeb57..6080db7 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -542,7 +542,7 @@ process_file (const char *fname)
   else
 {
   fnew = xstrdup (foutput);
-  fdnew = open (fnew, O_WRONLY | O_BINARY | O_CREAT, st.st_mode & 
ALLPERMS);
+  fdnew = open (fnew, O_WRONLY | O_BINARY | O_CREAT, st.st_mode & 0);
 }
 
   if (fdnew < 0)
@@ -1237,7 +1237,7 @@ process_file (const char *fname)
 
 #if HAVE_DECL_FCHMOD
   /* Try to match mode and owner.group of the original file.  */
-  if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
+  if (fchmod (fdnew, st.st_mode & 0) != 0)
 if (verbose >= 0)
   error (0, errno, "Couldn't fchmod %s", fnew);
 #endif
diff --git a/src/ranlib.c b/src/ranlib.c
index 41057de..22aac28 100644
--- a/src/ranlib.c
+++ b/src/ranlib.c
@@ -261,7 +261,7 @@ handle_file (const char *fname)
 #if HAVE_DECL_FCHMOD
  /* Set the mode of the new file to the same values the
 original file has.  */
- fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+ fchmod (newfd, st.st_mode & 0) != 0 ||
 #endif
  (
 #if HAVE_DECL_FCHOWN
diff --git a/src/strip.c b/src/strip.c
index 60f6700..14d2249 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -347,7 +347,7 @@ process_file (const char *fname)
   switch (elf_kind (elf))
 {
 case ELF_K_ELF:
-  result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
+  result = handle_elf (fd, elf, NULL, fname, st.st_mode & 0777,
   preserve_dates ? tv : NULL);
   break;
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
index fef6f55..9c04404 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * elfstrmerge.c: Use 0 instead of ALLPERMS.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* elfshphehdr.c: For writing, use /dev/null rather than /dev/zero.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/tests/elfstrmerge.c b/tests/elfstrmerge.c
index ff15f57..5405ed8 100644
--- a/tests/elfstrmerge.c
+++ b/tests/elfstrmerge.c
@@ -367,7 +367,7 @@ main (int argc, char **argv)
   else
 {
   fnew = argv[2];
-  fdnew = open (fne

[PATCH] Write to /dev/null rather than /dev/zero

2017-05-04 Thread Ulf Hermann
/dev/zero is meant for reading zeroes. /dev/null is for writing into
nirvana.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog | 4 
 tests/elfshphehdr.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index b8de138..fef6f55 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * elfshphehdr.c: For writing, use /dev/null rather than /dev/zero.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* newfile.c: Close the file when we're done and unlink it afterwards.
* newscn.c: Likewise.
* update1.c: Likewise.
diff --git a/tests/elfshphehdr.c b/tests/elfshphehdr.c
index d1ab633..e0f0712 100644
--- a/tests/elfshphehdr.c
+++ b/tests/elfshphehdr.c
@@ -152,7 +152,7 @@ main (int argc __attribute__ ((unused)), char **argv 
__attribute ((unused)))
 {
   elf_version (EV_CURRENT);
 
-  int fd = fd = open("/dev/zero", O_WRONLY | O_BINARY);
+  int fd = fd = open("/dev/null", O_WRONLY | O_BINARY);
   check ("open", fd >= 0);
 
   Elf *elf;
-- 
2.1.4



[PATCH] Increase stack usage limit to 512k

2017-05-04 Thread Ulf Hermann
On windows x86_64 we need more stack in some places.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 config/ChangeLog | 4 
 config/eu.am | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/config/ChangeLog b/config/ChangeLog
index 0f240ea..642d765 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eu.am: Increase stack limit to 512k.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* eu.am: Disable textrel_check if we're not building ELF files.
diff --git a/config/eu.am b/config/eu.am
index 637a2c2..d7befba 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -39,9 +39,9 @@ endif
 # with deterministic archives.
 ARFLAGS = cr
 
-# Warn about stack usage of more than 256K = 262144 bytes.
+# Warn about stack usage of more than 512K = 524288 bytes.
 if ADD_STACK_USAGE_WARNING
-STACK_USAGE_WARNING=-Wstack-usage=262144
+STACK_USAGE_WARNING=-Wstack-usage=524288
 else
 STACK_USAGE_WARNING=
 endif
-- 
2.1.4



[PATCH] Provide a windows-specific ORIGINDIR for eblopenbackend

2017-05-04 Thread Ulf Hermann
$ORIGIN and $LIB are not supported by all implementations of dlopen() and
on windows we need backslashes as directory separators.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libebl/ChangeLog| 5 +
 libebl/eblopenbackend.c | 4 
 2 files changed, 9 insertions(+)

diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index f9f5d89..7de7236 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eblopenbackend.c: On windows use an ORIGINDIR without $ORIGIN and
+   $LIB.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Forward LIBPREFIX and LIBEXT as defined by configure.
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 0b261e7..4048f12 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -312,7 +312,11 @@ openbackend (Elf *elf, const char *emulation, GElf_Half 
machine)
 #ifndef LIBEBL_SUBDIR
 # define LIBEBL_SUBDIR PACKAGE
 #endif
+#if (defined _WIN32 || defined __WIN32__)
+#define ORIGINDIR "..\\lib\\" LIBEBL_SUBDIR "\\"
+#else
 #define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
+#endif
 #define LIBEBL_PREFIX LIBPREFIX "ebl_"
 
/* Give it a try.  At least the machine type matches.  First
-- 
2.1.4



[PATCH] Drop the trickery in printversion.h

2017-05-04 Thread Ulf Hermann
The mechanism of moving argp_program_version_hook and
argp_program_bug_address to .rodata is not portable and two pointers
per program are not worth the effort to make it portable. Revert the
pointers to be non-const.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 lib/ChangeLog  |  5 +
 lib/printversion.h | 10 +++---
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 59939bd..0433f02 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * printversion.h: Define ARGP_PROGRAM_VERSION_HOOK_DEF and
+   ARGP_BUG_ADDRESS_DEF to be non-const and drop the asm tricks.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* system.h: Define FILE_SYSTEM_PREFIX_LEN, ISDIRSEP, DIRSEP, PATHSEP,
and IS_ABSOLUTE_PATH to help with handling file system paths.
 
diff --git a/lib/printversion.h b/lib/printversion.h
index a9e059f..090b53a 100644
--- a/lib/printversion.h
+++ b/lib/printversion.h
@@ -36,14 +36,10 @@
 void print_version (FILE *stream, struct argp_state *state);
 
 /* We need define two variables, argp_program_version_hook and
-   argp_program_bug_address, in all programs.  argp.h declares these
-   variables as non-const (which is correct in general).  But we can
-   do better, it is not going to change.  So we want to move them into
-   the .rodata section.  Define macros to do the trick.  */
+   argp_program_bug_address, in all programs. */
 #define ARGP_PROGRAM_VERSION_HOOK_DEF \
-  void (*const apvh) (FILE *, struct argp_state *) \
-   __asm ("argp_program_version_hook")
+  void (*argp_program_version_hook) (FILE *, struct argp_state *)
 #define ARGP_PROGRAM_BUG_ADDRESS_DEF \
-  const char *const apba__ __asm ("argp_program_bug_address")
+  const char *argp_program_bug_address
 
 #endif // PRINTVERSION_H
-- 
2.1.4



[PATCH] Close files before renaming or unlinking them

2017-05-04 Thread Ulf Hermann
On windows we cannot rename or unlink open files.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libasm/ChangeLog |  4 
 libasm/asm_end.c | 15 +++
 tests/ChangeLog  |  9 +
 tests/newfile.c  |  7 +--
 tests/newscn.c   |  3 ++-
 tests/update1.c  |  1 +
 tests/update2.c  |  1 +
 tests/update3.c  |  1 +
 tests/update4.c  |  1 +
 9 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 2b499c7..0e67657 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * asm_end.c: Rename the output file only after freeing resources.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* asm_end.c: Don't fchmod the new file if fchmod is unavailable.
 
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index 7fabe94..7891fbb 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -521,16 +521,23 @@ asm_end (AsmCtx_t *ctx)
 }
 #endif
 
+  char *tmp_fname = strdup (ctx->tmp_fname);
+  char *fname = strdup (ctx->fname);
+
+  /* Free the resources.  */
+  __libasm_finictx (ctx);
+
   /* Rename output file.  */
-  if (rename (ctx->tmp_fname, ctx->fname) != 0)
+  result = rename (tmp_fname, fname);
+  free (tmp_fname);
+  free (fname);
+
+  if (result != 0)
 {
   __libasm_seterrno (ASM_E_CANNOT_RENAME);
   return -1;
 }
 
-  /* Free the resources.  */
-  __libasm_finictx (ctx);
-
   return 0;
 }
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 5e29f82..b8de138 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,14 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * newfile.c: Close the file when we're done and unlink it afterwards.
+   * newscn.c: Likewise.
+   * update1.c: Likewise.
+   * update2.c: Likewise.
+   * update3.c: Likewise.
+       * update4.c: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* asm-tst4.c: Don't assume unix file system conventions.
* asm-tst5.c: Likewise.
* asm-tst6.c: Likewise.
diff --git a/tests/newfile.c b/tests/newfile.c
index 5eabdcb..a279317 100644
--- a/tests/newfile.c
+++ b/tests/newfile.c
@@ -63,8 +63,6 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   printf ("cannot create temporary file: %m\n");
   exit (1);
 }
-  /* Remove the file when we exit.  */
-  unlink (fname);
 
   elf_version (EV_CURRENT);
   elf = elf_begin (fd, ELF_C_WRITE, NULL);
@@ -166,5 +164,10 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   (void) elf_end (elf);
 }
 
+  close (fd);
+
+  /* Remove the file when we exit.  */
+  unlink (fname);
+
   return result;
 }
diff --git a/tests/newscn.c b/tests/newscn.c
index 466f2f6..de8951d 100644
--- a/tests/newscn.c
+++ b/tests/newscn.c
@@ -46,7 +46,6 @@ main (void)
   fprintf (stderr, "Failed to open fdput file: %s\n", name);
   exit (1);
 }
-  unlink (name);
 
   elf = elf_begin (fd, ELF_C_WRITE, NULL);
   if (elf == NULL)
@@ -62,5 +61,7 @@ main (void)
   elf_end (elf);
   close (fd);
 
+  unlink (name);
+
   return 0;
 }
diff --git a/tests/update1.c b/tests/update1.c
index a571618..548c6d8 100644
--- a/tests/update1.c
+++ b/tests/update1.c
@@ -121,6 +121,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
diff --git a/tests/update2.c b/tests/update2.c
index 3e22879..1dcff3f 100644
--- a/tests/update2.c
+++ b/tests/update2.c
@@ -144,6 +144,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
diff --git a/tests/update3.c b/tests/update3.c
index d619bed..9d4f880 100644
--- a/tests/update3.c
+++ b/tests/update3.c
@@ -199,6 +199,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
diff --git a/tests/update4.c b/tests/update4.c
index 8196b8c..a762e0a 100644
--- a/tests/update4.c
+++ b/tests/update4.c
@@ -351,6 +351,7 @@ main (int argc, char *argv[] __attribute__ ((unused)))
   exit (1);
 }
 
+  close (fd);
   unlink (fname);
 
   return 0;
-- 
2.1.4



[PATCH] Adapt debug info fstat check for windows

2017-05-04 Thread Ulf Hermann
On windows the resulting ino and dev entries are always 0, so the file
would always be discarded. We apply a heuristic instead: If the ctime,
mtime, mode and size of the two files are all equal then we consider
them to be the same. It's exceedingly unlikely to produce two different
files for which that holds by chance.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdwfl/ChangeLog| 5 +
 libdwfl/find-debuginfo.c | 9 +
 2 files changed, 14 insertions(+)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ee550d0..517ba21 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * find-debuginfo.c: On windows, check various extra parameters of
+   struct stat to determine if two files are the same.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* dwfl_build_id_find_elf.c: Don't assume unix file system conventions.
* find-debuginfo.c: Likewise.
* linux-kernel-modules.c: Likewise.
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index ac568d0..3a65eda 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -63,10 +63,19 @@ try_open (const struct stat *main_stat,
   if (fd < 0)
 free (fname);
   else if (fstat (fd, ) == 0
+#if defined _WIN32 || defined __WIN32__
+  /* On windows, st_ino and st_dev are not unique, so we apply a 
heuristic */
+  && st.st_size == main_stat->st_size
+  && st.st_mode == main_stat->st_mode
+  && st.st_mtime == main_stat->st_mtime
+  && st.st_ctime == main_stat->st_ctime
+#endif
   && st.st_ino == main_stat->st_ino
   && st.st_dev == main_stat->st_dev)
 {
   /* This is the main file by another name.  Don't look at it again.  */
+  /* This doesn't happen on windows as windows doesn't have proper links. 
However, on windows
+ st_ino and st_dev is always 0. */
   free (fname);
   close (fd);
   errno = ENOENT;
-- 
2.1.4



[PATCH] Use OS-specific paths

2017-05-04 Thread Ulf Hermann
In general we need to use ';' as path separator and '\' and directory
separator on windows. The shell will automatically translate paths to
some extent, but we have to call "pwd -W" rather than plain "pwd" to
get something useful.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 lib/ChangeLog|   5 ++
 lib/system.h |  16 ++
 libdwfl/ChangeLog|   8 +++
 libdwfl/dwfl_build_id_find_elf.c |   5 +-
 libdwfl/find-debuginfo.c | 106 ++-
 libdwfl/libdwflP.h   |   4 ++
 libdwfl/linux-kernel-modules.c   |   3 +-
 libdwfl/linux-proc-maps.c|   4 +-
 src/ChangeLog|   6 ++
 src/addr2line.c  |   4 +-
 src/size.c   |   4 +-
 src/strip.c  |   4 +-
 tests/ChangeLog  |  10 
 tests/asm-tst4.c |   7 ++-
 tests/asm-tst5.c |   6 +-
 tests/asm-tst6.c |   6 +-
 tests/run-addr2line-alt-debugpath.sh |   4 +-
 tests/run-addrname-test.sh   |   8 +--
 tests/run-prelink-addr-test.sh   |  60 ++--
 tests/test-subr.sh   |   1 +
 20 files changed, 171 insertions(+), 100 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 9fa8ff0..59939bd 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * system.h: Define FILE_SYSTEM_PREFIX_LEN, ISDIRSEP, DIRSEP, PATHSEP,
+   and IS_ABSOLUTE_PATH to help with handling file system paths.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* eu-config.h: Define O_BINARY to 0 if it doesn't exist.
 
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/lib/system.h b/lib/system.h
index ffa2bc7..3a6b8e9 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -51,6 +51,22 @@
 # error "Unknown byte order"
 #endif
 
+#if (defined _WIN32 || defined __WIN32__)
+# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' <= 'z' 
- 'a')
+# define FILE_SYSTEM_PREFIX_LEN(filename) \
+  (_IS_DRIVE_LETTER ((filename)[0]) && (filename)[1] == ':' ? 2 : 0)
+# define ISDIRSEP(c) ((c) == '/' || (c) == '\\')
+# define DIRSEP '\\'
+# define PATHSEP ';'
+# define IS_ABSOLUTE_PATH(f) ISDIRSEP ((f)[FILE_SYSTEM_PREFIX_LEN (f)])
+#else
+# define FILE_SYSTEM_PREFIX_LEN(filename) 0
+# define ISDIRSEP(c) ((c) == '/')
+# define DIRSEP '/'
+# define PATHSEP ':'
+# define IS_ABSOLUTE_PATH(p) (ISDIRSEP ((p)[0]))
+#endif
+
 #ifndef MAX
 #define MAX(m, n) ((m) < (n) ? (n) : (m))
 #endif
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 6f3a561..ee550d0 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,13 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * dwfl_build_id_find_elf.c: Don't assume unix file system conventions.
+   * find-debuginfo.c: Likewise.
+   * linux-kernel-modules.c: Likewise.
+   * linux-proc-maps.c: Likewise.
+   * libdwflP.h: Add a windows-compatible default debuginfo path.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* argp-std.c: Open files in O_BINARY.
* dwfl_build_id_find_elf.c: Likewise.
* dwfl_build_id_find_elf.c: Likewise.
diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c
index 6ce2c1c..cf2a0f1 100644
--- a/libdwfl/dwfl_build_id_find_elf.c
+++ b/libdwfl/dwfl_build_id_find_elf.c
@@ -79,13 +79,14 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, 
char **file_name,
   int fd = -1;
   char *dir;
   char *paths = path;
-  while (fd < 0 && (dir = strsep (, ":")) != NULL)
+  char pathsep[] = { PATHSEP, '\0' };
+  while (fd < 0 && (dir = strsep (, pathsep)) != NULL)
 {
   if (dir[0] == '+' || dir[0] == '-')
++dir;
 
   /* Only absolute directory names are useful to us.  */
-  if (dir[0] != '/')
+  if (IS_ABSOLUTE_PATH(dir))
continue;
 
   size_t dirlen = strlen (dir);
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index 7f7e108..ac568d0 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -52,9 +52,10 @@ try_open (const struct stat *main_stat,
   if (unlikely (fname == NULL))
return -1;
 }
-  else if ((subdir == NULL ? asprintf (, "%s/%s", dir, debuglink)
-   : dir == NULL ? asprintf (, "%s/%s", subdir, debuglink)
-   : asprintf (, "%s/%s/%s", dir, subdir, debuglink)) < 0)
+  else if ((subdir == NULL ? asprintf (, "%s%c%s", dir, DIRSEP, 
debuglink)
+   : dir == NULL ? asprintf (, "%s%c%s", subdir, DIRSEP, 
debuglink)
+   : asprintf (, "%s%c%s%c%s", dir, DIRSEP, subdir, DIRSEP,
+debuglink)) < 0)
 return -1;
 
  

[PATCH] Have diff ignore line ending differences when testing

2017-05-04 Thread Ulf Hermann
This accounts for the CR/LF problem we get when producing text files on
windows.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 tests/ChangeLog | 7 +++
 tests/run-addr2line-test.sh | 8 
 tests/run-readelf-test1.sh  | 2 +-
 tests/run-unstrip-n.sh  | 2 +-
 tests/test-subr.sh  | 2 +-
 5 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index b091ae0..5616c74 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,12 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * run-addr2line-test.sh: Add --strip-trailing-cr option to diff.
+   * run-readelf-test1.sh: Likewise.
+   * run-unstrip-n.sh: Likewise.
+   * test-subr.sh: Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* alldts.c: Open files in O_BINARY.
* allfcts.c: Likewise.
* arextract.c: Likewise.
diff --git a/tests/run-addr2line-test.sh b/tests/run-addr2line-test.sh
index 1079c3e..0dae42d 100755
--- a/tests/run-addr2line-test.sh
+++ b/tests/run-addr2line-test.sh
@@ -56,7 +56,7 @@ EOF
 
 echo "# Everything from stdin (with newlines)."
 cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > 
stdin.nl.out || exit 1
-cmp good.out stdin.nl.out || exit 1
+diff --strip-trailing-cr good.out stdin.nl.out || exit 1
 
 cat > foo.out <<\EOF
 foo
@@ -65,11 +65,11 @@ EOF
 
 echo "# stdin without newline address, just EOF."
 echo -n "0x08048468" | testrun ${abs_top_builddir}/src/addr2line -f -e 
testfile > stdin.nonl.out || exit 1
-cmp foo.out stdin.nonl.out || exit 1
+diff --strip-trailing-cr foo.out stdin.nonl.out || exit 1
 
 echo "# stdin without newline symbol, just EOF."
 echo -n "foo" | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > 
stdin.nl.out || exit 1
-cmp foo.out stdin.nonl.out || exit 1
+diff --strip-trailing-cr foo.out stdin.nonl.out || exit 1
 
 tempfiles good.addr.out
 
@@ -105,7 +105,7 @@ cat good.addr.out | testrun_compare 
${abs_top_builddir}/src/addr2line -a -f -e t
 
 echo "# Everything from stdin (with newlines) with addresses."
 cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -a -f -e testfile > 
stdin.nl.out || exit 1
-cmp good.addr.out stdin.nl.out || exit 1
+diff --strip-trailing-cr good.addr.out stdin.nl.out || exit 1
 
 echo "# Pretty with functions and addresses."
 testrun_compare ${abs_top_builddir}/src/addr2line --pretty -a -f -e testfile 
0x08048468 0x0804845c << EOF
diff --git a/tests/run-readelf-test1.sh b/tests/run-readelf-test1.sh
index 4725049..40b664f 100755
--- a/tests/run-readelf-test1.sh
+++ b/tests/run-readelf-test1.sh
@@ -28,7 +28,7 @@ tempfiles testfile.temp
 
 testrun ${abs_top_builddir}/src/readelf -r testfile3 > testfile.temp
 
-diff -u - testfile.temp <$outfile2
-diff -u $outfile2 - <

[PATCH] Skip deleted test if fork(2) is unavailable

2017-05-04 Thread Ulf Hermann
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  4 
 configure.ac|  1 +
 tests/ChangeLog |  4 
 tests/deleted.c | 14 ++
 4 files changed, 23 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 662c633..2cf7bd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check for fork().
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check for posix_fallocate, posix_fadvise, fchown,
fchmod.
 
diff --git a/configure.ac b/configure.ac
index 6cbd70d..5fa20c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -608,6 +608,7 @@ AM_CONDITIONAL(HAVE_FEATURES_H, [test 
"x$ac_cv_header_features_h" = "xyes"])
 AC_CHECK_HEADERS(stdio_ext.h)
 AM_CONDITIONAL(HAVE_STDIO_EXT_H, [test "x$ac_cv_header_stdio_ext_h" = "xyes"])
 
+AC_CHECK_DECLS([fork], [], [], [[#include ]])
 AC_CHECK_DECLS([feof_unlocked, ferror_unlocked, fputc_unlocked, fputs_unlocked,
fwrite_unlocked, putc_unlocked, putchar_unlocked],
[], [], [[#include ]])
diff --git a/tests/ChangeLog b/tests/ChangeLog
index c2619d0..611b88a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,9 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * deleted.c: If fork() is unavailable, skip the test.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* allfcts.c: Use fprintf and exit rather than err and errx.
* buildid.c: Likewise.
* debugaltlink.c: Likewise.
diff --git a/tests/deleted.c b/tests/deleted.c
index 6be35bc..f11cb1b 100644
--- a/tests/deleted.c
+++ b/tests/deleted.c
@@ -29,6 +29,18 @@
 
 extern void libfunc (void);
 
+#if !HAVE_DECL_FORK
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  fprintf (stderr, "%s: fork() not supported for this architecture\n",
+  argv[0]);
+  return 77;
+}
+
+#else
+
 int
 main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
 {
@@ -56,3 +68,5 @@ main (int argc __attribute__ ((unused)), char **argv 
__attribute__ ((unused)))
   printf ("%d\n", pid);
   return EXIT_SUCCESS;
 }
+
+#endif
-- 
2.1.4



[PATCH v2] Check for existence of GNU-style strerror_r

2017-05-04 Thread Ulf Hermann
We cannot get GNU strerror_r from gnulib.

If we don't have it, we don't translate system error codes to strings in
dwfl_error.c.

(rebased on top of all the other patches)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog| 4 
 configure.ac | 2 ++
 libdwfl/ChangeLog| 5 +
 libdwfl/dwfl_error.c | 4 
 4 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 7a40c9d..662c633 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -48,6 +48,10 @@
 
 2017-04-21  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check for strerror_r and its variants.
+
+2017-04-21  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Add check for GNU-style basename.
 
 2017-02-15  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/configure.ac b/configure.ac
index e55360d..6cbd70d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -456,6 +456,8 @@ char *basename(const char *path);
 #endif
 ])
 
+AC_FUNC_STRERROR_R
+
 AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
 AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
 AM_CONDITIONAL(DEMANGLE, test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes")
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index a7e6e30..26a3599 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -100,6 +100,11 @@
the note name data is the empty string.
(dwfl_core_file_attach): Likewise.
 
+2017-02-22  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * dwfl_error.c: If we don't have a strerror_r returning a char*,
+   output a less useful message in case of a system error.
+
 2017-02-15  Ulf Hermann  <ulf.herm...@qt.io>
 
* linux-kernel-modules.c: Include system.h.
diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c
index 7bcf61c..aba3cca 100644
--- a/libdwfl/dwfl_error.c
+++ b/libdwfl/dwfl_error.c
@@ -154,7 +154,11 @@ dwfl_errmsg (int error)
   switch (error &~ 0x)
 {
 case OTHER_ERROR (ERRNO):
+#ifdef STRERROR_R_CHAR_P
   return strerror_r (error & 0x, "bad", 0);
+#else
+  return "Unknown error. See errno";
+#endif
 case OTHER_ERROR (LIBELF):
   return elf_errmsg (error & 0x);
 case OTHER_ERROR (LIBDW):
-- 
2.1.4



[PATCH] Skip fchown, fchmod, fadvise, fallocate if functions are unavailable

2017-05-04 Thread Ulf Hermann
If fchmod or fchown are unavailable, then the file permission model is
likely to be different from what we expect there. posix_fallocate is a
frather fragile affair already on linux, and not guaranteed to do
anything useful. If it's not available, the result will be the same as
when it's available and unreliable. fadvise is an optimization.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  5 +
 configure.ac|  3 +++
 libasm/ChangeLog|  4 
 libasm/asm_end.c|  2 ++
 libelf/ChangeLog|  5 +
 libelf/elf_update.c |  4 
 src/ChangeLog   |  9 
 src/ar.c| 59 +++--
 src/elfcompress.c   |  4 
 src/ranlib.c| 21 +++
 src/strings.c   |  2 ++
 src/strip.c |  5 -
 tests/ChangeLog |  5 +
 tests/elfstrmerge.c |  4 
 14 files changed, 103 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5a86247..7a40c9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check for posix_fallocate, posix_fadvise, fchown,
+   fchmod.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check for tdestroy and node_t. Declare tdestroy in
config.h if tdestroy is not available from search.h, but node_t is.
 
diff --git a/configure.ac b/configure.ac
index 88b9d0a..e55360d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -631,6 +631,9 @@ void tdestroy(void *root, void (*free_node)(void *nodep));
 #endif
 ])
 
+AC_CHECK_DECLS([posix_fallocate, posix_fadvise], [], [], [[#include 
]])
+AC_CHECK_DECLS([fchown, fchmod], [], [], [[#include ]])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 5321213..2b499c7 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * asm_end.c: Don't fchmod the new file if fchmod is unavailable.
+
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use the predefined common library names rather than
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index ced24f5..7fabe94 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -512,12 +512,14 @@ asm_end (AsmCtx_t *ctx)
   if (result != 0)
 return result;
 
+#if HAVE_DECL_FCHMOD
   /* Make the new file globally readable and user/group-writable.  */
   if (fchmod (ctx->fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) != 0)
 {
   __libasm_seterrno (ASM_E_CANNOT_CHMOD);
   return -1;
 }
+#endif
 
   /* Rename output file.  */
   if (rename (ctx->tmp_fname, ctx->fname) != 0)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 0a5200f..fd20ebb 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * elf_update.c: Don't try to posix_fallocate on systems where it isn't
+   available. Don't fchmod the output file if there is no fchmod.
+
 2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use the predefined common library names rather than
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 8ce0782..b6014cd 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -80,6 +80,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
 
   if (elf->map_address != NULL)
 {
+#if HAVE_DECL_POSIX_FALLOCATE
   /* When using mmap we want to make sure the file content is
 really there. Only using ftruncate might mean the file is
 extended, but space isn't allocated yet.  This might cause a
@@ -100,6 +101,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t 
shnum)
__libelf_seterrno (ELF_E_WRITE_ERROR);
return -1;
  }
+#endif
 
   /* The file is mmaped.  */
   if ((class == ELFCLASS32
@@ -129,6 +131,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t 
shnum)
   size = -1;
 }
 
+#if HAVE_DECL_FCHMOD
   /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID
  mode bits.  So make sure we restore them afterwards if they were set.
  This is not atomic if someone else chmod's the file while we operate.  */
@@ -140,6 +143,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t 
shnum)
   __libelf_seterrno (ELF_E_WRITE_ERROR);
   size = -1;
 }
+#endif
 
   if (size != -1 && elf->parent == NULL)
 elf->maximum_size = size;
diff --git a/src/ChangeLog b/src/ChangeLog
index 4a32604..e0df2e1 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * ar.c: Don't fchmod or fchown the output file if fchmod 

[PATCH] Define roundup() for strings.c if it doesn't exist

2017-05-04 Thread Ulf Hermann
Change-Id: I6ea7c1f894e89bbaaecb724473c4c00e67296f05
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog | 4 
 src/strings.c | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 64db1ca..4a32604 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * strings.c: If roundup() is not defined, define it.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use the predefined names for libelf, libdw, libasm,
diff --git a/src/strings.c b/src/strings.c
index d214356..22cbfac 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -450,6 +450,9 @@ process_chunk (const char *fname, const unsigned char *buf, 
off_t to,
 *unprinted = xstrndup ((const char *) start, curlen);
 }
 
+#ifndef roundup
+#define roundup(x, y) x) + ((y) - 1)) / (y)) * (y))
+#endif
 
 /* Map a file in as large chunks as possible.  */
 static void *
-- 
2.1.4



[PATCH] Add our own tdestroy if search.h exposes a node_t struct

2017-05-04 Thread Ulf Hermann
tdestroy is not necessarily available from search.h, but we need it.
gnulib cannot help us here as it will detect search.h to be available
and functional in that case. However, some search.h expose a node_t
struct which can be used to implement tdestroy. If that is the case, add
an implementation to libgnu.a.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog  |  5 +
 configure.ac   | 21 +
 libgnu/ChangeLog   |  5 +
 libgnu/Makefile.am |  6 +-
 libgnu/tdestroy.c  | 47 +++
 5 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/tdestroy.c

diff --git a/ChangeLog b/ChangeLog
index aa0759c..5a86247 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check for tdestroy and node_t. Declare tdestroy in
+   config.h if tdestroy is not available from search.h, but node_t is.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check for unlocked I/O functions.
 
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/configure.ac b/configure.ac
index bfdc53f..88b9d0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -610,6 +610,27 @@ AC_CHECK_DECLS([feof_unlocked, ferror_unlocked, 
fputc_unlocked, fputs_unlocked,
fwrite_unlocked, putc_unlocked, putchar_unlocked],
[], [], [[#include ]])
 
+AC_CHECK_DECLS([tdestroy], [], [],
+  [#include ])
+if test "x$ac_cv_have_decl_tdestroy" != "xyes"; then
+   AC_CHECK_MEMBERS([node_t.key, node_t.rlink, node_t.llink],
+[have_node_t="yes"], [have_node_t="no"],
+[#define _SEARCH_PRIVATE
+ #include ])
+   if test "x$have_node_t" = "xyes"; then
+   AC_DEFINE([USE_PRIVATE_TDESTROY], [1], [Implement tdestroy 
using private node_t from search.h])
+   fi
+fi
+AM_CONDITIONAL(USE_PRIVATE_TDESTROY, [test "x$have_node_t" = "xyes"])
+
+AH_VERBATIM([USE_PRIVATE_TDESTROY], [
+/* Declare tdestroy here if it is not available from a system header. */
+#undef USE_PRIVATE_TDESTROY
+#ifdef USE_PRIVATE_TDESTROY
+void tdestroy(void *root, void (*free_node)(void *nodep));
+#endif
+])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libgnu/ChangeLog b/libgnu/ChangeLog
index 3394de6..7b146b6 100644
--- a/libgnu/ChangeLog
+++ b/libgnu/ChangeLog
@@ -1,5 +1,10 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * Makefile.am: Use our own implementation of tdestroy if we have to.
+   * tdestroy.c: New file.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: If GNU basename is unavailable add our own
implementation.
* basename-gnu.c: New file.
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 32c9aa7..99abab0 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -36,7 +36,7 @@ MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
 EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c 
sysconf_win32.c ar.in.h features.in.h \
- stdio_ext.in.h fts.in.h basename-gnu.c
+ stdio_ext.in.h fts.in.h basename-gnu.c tdestroy.c
 CLEANFILES =
 SUFFIXES =
 
@@ -108,3 +108,7 @@ endif
 if !HAVE_BASENAME
 libgnu_a_SOURCES += basename-gnu.c
 endif
+
+if USE_PRIVATE_TDESTROY
+libgnu_a_SOURCES += tdestroy.c
+endif
diff --git a/libgnu/tdestroy.c b/libgnu/tdestroy.c
new file mode 100644
index 000..d14b875
--- /dev/null
+++ b/libgnu/tdestroy.c
@@ -0,0 +1,47 @@
+/* tdestroy, on systems where node is exposed from search.h
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include 
+
+#include 
+#define _SEARCH_PRIVATE
+#include 
+
+void
+tdestr

[PATCH] Check for existence of GNU-style basename()

2017-05-04 Thread Ulf Hermann
If it doesn't exist, add an implementation to libgnu.a and config.h.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog |  4 
 configure.ac  | 16 +++
 libgnu/ChangeLog  |  6 ++
 libgnu/Makefile.am|  6 +-
 libgnu/basename-gnu.c | 54 +++
 5 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/ChangeLog
 create mode 100644 libgnu/basename-gnu.c

diff --git a/ChangeLog b/ChangeLog
index 29013e8..aa0759c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -36,6 +36,10 @@
 
* .gitignore: Add fillfile and peel_type tests.
 
+2017-04-21  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Add check for GNU-style basename.
+
 2017-02-15  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Add check for mempcpy.
diff --git a/configure.ac b/configure.ac
index 0432bb1..bfdc53f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -440,6 +440,22 @@ AC_SUBST([zip_LIBS])
 
 AC_CHECK_DECLS([powerof2],[],[],[#include ])
 
+AC_CHECK_DECLS([basename],[],[],
+   [#define _GNU_SOURCE
+#include ])
+AM_CONDITIONAL(HAVE_BASENAME, [test "x$ac_cv_have_decl_basename" = "xyes"])
+
+if test "x$ac_cv_have_decl_basename" != "xyes"; then
+   AC_DEFINE([USE_REPLACEMENT_BASENAME], [1], [Use hand-rolled basename() 
replacement.])
+fi
+AH_VERBATIM([USE_REPLACEMENT_BASENAME],
+   [/* Define basename() here if it is not available from a system header. 
*/
+#undef USE_REPLACEMENT_BASENAME
+#ifdef USE_REPLACEMENT_BASENAME
+char *basename(const char *path);
+#endif
+])
+
 AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
 AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
 AM_CONDITIONAL(DEMANGLE, test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes")
diff --git a/libgnu/ChangeLog b/libgnu/ChangeLog
new file mode 100644
index 000..3394de6
--- /dev/null
+++ b/libgnu/ChangeLog
@@ -0,0 +1,6 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: If GNU basename is unavailable add our own
+   implementation.
+   * basename-gnu.c: New file.
+
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 1c8e6b8..32c9aa7 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -36,7 +36,7 @@ MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
 EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c 
sysconf_win32.c ar.in.h features.in.h \
- stdio_ext.in.h fts.in.h
+ stdio_ext.in.h fts.in.h basename-gnu.c
 CLEANFILES =
 SUFFIXES =
 
@@ -104,3 +104,7 @@ if USE_WIN32_SYSCONF
 libgnu_a_SOURCES += sysconf_win32.c
 endif
 endif
+
+if !HAVE_BASENAME
+libgnu_a_SOURCES += basename-gnu.c
+endif
diff --git a/libgnu/basename-gnu.c b/libgnu/basename-gnu.c
new file mode 100644
index 000..7feee81
--- /dev/null
+++ b/libgnu/basename-gnu.c
@@ -0,0 +1,54 @@
+/* Implementation of GNU-style basename()
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#include "dosname.h"
+#include 
+
+/* On windows, file names with ':' in them are invalid, so we don't have to
+   add a special case for them. If we get an invalid path as input, we may
+   return a nonsensical path as output. This assumption allows us to use the
+   simple strrpos() equivalent below, without any allocation. */
+
+char *
+basename (const char *name)
+{
+  size_t prefix = FILE_SYSTEM_PREFIX_LEN(name);
+  size_t length = strlen(name);
+
+  while (length > prefix) {
+--length;
+if (ISSLASH(name[length]))
+  return (char *)name + length + 1;
+  }
+
+  return (char *)name + prefix;
+}
-- 
2.1.4



[PATCH] Define unlocked io functions to locked ones if they are unavailable

2017-05-04 Thread Ulf Hermann
The locked IO functions will still do the job, albeit a bit slower.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  4 
 configure.ac|  4 
 lib/ChangeLog   |  5 +
 lib/eu-config.h | 28 
 4 files changed, 41 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index d43eeb6..29013e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Check for unlocked I/O functions.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Determine the binary format we're building natively.
diff --git a/configure.ac b/configure.ac
index f04a6c8..0432bb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -590,6 +590,10 @@ AM_CONDITIONAL(HAVE_FEATURES_H, [test 
"x$ac_cv_header_features_h" = "xyes"])
 AC_CHECK_HEADERS(stdio_ext.h)
 AM_CONDITIONAL(HAVE_STDIO_EXT_H, [test "x$ac_cv_header_stdio_ext_h" = "xyes"])
 
+AC_CHECK_DECLS([feof_unlocked, ferror_unlocked, fputc_unlocked, fputs_unlocked,
+   fwrite_unlocked, putc_unlocked, putchar_unlocked],
+   [], [], [[#include ]])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/lib/ChangeLog b/lib/ChangeLog
index ecc6179..321513c 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eu-config.h: Define unlocked I/O functions to locked ones if they
+   are unavailable.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* eu-config.h: Define attribute_hidden to be empty if the compiler
diff --git a/lib/eu-config.h b/lib/eu-config.h
index e69b213..6530044 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -206,4 +206,32 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define funlockfile(fp) /* nop */
 #endif
 
+#if !HAVE_DECL_FEOF_UNLOCKED
+#define feof_unlocked(x) feof (x)
+#endif
+
+#if !HAVE_DECL_FERROR_UNLOCKED
+#define ferror_unlocked(x) ferror (x)
+#endif
+
+#if !HAVE_DECL_FPUTC_UNLOCKED
+#define fputc_unlocked(x,y) fputc (x,y)
+#endif
+
+#if !HAVE_DECL_FPUTS_UNLOCKED
+#define fputs_unlocked(x,y) fputs (x,y)
+#endif
+
+#if !HAVE_DECL_FWRITE_UNLOCKED
+#define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
+#endif
+
+#if !HAVE_DECL_PUTC_UNLOCKED
+#define putc_unlocked(x,y) putc (x,y)
+#endif
+
+#if !HAVE_DECL_PUTCHAR_UNLOCKED
+#define putchar_unlocked(x) putchar (x)
+#endif
+
 #endif /* eu-config.h */
-- 
2.1.4



[PATCH] Add sysconf replacement for win32

2017-05-04 Thread Ulf Hermann
We cannot get sysconf() from gnulib and the only thing we need it for
is getting the page size. Therefore, of the various possible sysconf
parameters we only define and implement _SC_PAGESIZE in our replacement.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog  |  6 ++
 configure.ac   | 20 
 libgnu/ChangeLog   |  6 ++
 libgnu/Makefile.am |  8 +++-
 libgnu/sysconf_win32.c | 42 ++
 5 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/sysconf_win32.c

diff --git a/ChangeLog b/ChangeLog
index 2c0e34d..71c73e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check for sysconf() and GetSystemInfo(). Add a
+   declaration of sysconf to config.h if GetSystemInfo() is available,
+   but not sysconf().
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check for sys/mman.h or alternatively MapViewOfFile().
 
 2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/configure.ac b/configure.ac
index 6a2f991..2d3ad04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -557,6 +557,26 @@ if test "x$ac_cv_header_sys_mman_h" != "xyes"; then
 fi
 AM_CONDITIONAL(USE_WIN32_MMAN, [test "x$ac_cv_have_decl_MapViewOfFile" = 
"xyes"])
 
+AC_CHECK_DECLS([sysconf], [], [], [[#include ]])
+AM_CONDITIONAL(HAVE_SYSCONF, [test "x$ac_cv_have_decl_sysconf" = "xyes"])
+if test "x$ac_cv_have_decl_sysconf" != "xyes"; then
+   AC_CHECK_DECLS([GetSystemInfo], [], [], [[#include ]])
+fi
+AM_CONDITIONAL(USE_WIN32_SYSCONF, [test "x$ac_cv_have_decl_GetSystemInfo" = 
"xyes"])
+
+if test "x$ac_cv_have_decl_GetSystemInfo" = "xyes"; then
+   AC_DEFINE([USE_WIN32_SYSCONF], [1], [Use sysconf replacement for win32])
+fi
+
+AH_VERBATIM([USE_WIN32_SYSCONF],
+   [/* Define sysconf(3) here if it is not available from a system header. 
*/
+#undef USE_WIN32_SYSCONF
+#ifdef USE_WIN32_SYSCONF
+#define _SC_PAGESIZE 1
+long sysconf(int name);
+#endif
+])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libgnu/ChangeLog b/libgnu/ChangeLog
index 60a049f..aa0e603 100644
--- a/libgnu/ChangeLog
+++ b/libgnu/ChangeLog
@@ -1,5 +1,11 @@
 2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * Makefile.am: If sysconf() is unavailable, but GetSystemInfo() is
+   available, compile the win32 version of sysconf.
+   * sysconf_win32.c: New file.
+
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: If sys/mman.h is unavailable, but MapViewOfFile is,
then use our own implementation of mmap and related functions.
* mman_win32.c: New file.
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 5af121a..05a8f61 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -35,7 +35,7 @@ noinst_LIBRARIES =
 MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
-EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c
+EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c 
sysconf_win32.c
 CLEANFILES =
 SUFFIXES =
 
@@ -69,3 +69,9 @@ if USE_WIN32_MMAN
 libgnu_a_SOURCES += mman_win32.c
 endif
 endif
+
+if !HAVE_SYSCONF
+if USE_WIN32_SYSCONF
+libgnu_a_SOURCES += sysconf_win32.c
+endif
+endif
diff --git a/libgnu/sysconf_win32.c b/libgnu/sysconf_win32.c
new file mode 100644
index 000..34ddf4b
--- /dev/null
+++ b/libgnu/sysconf_win32.c
@@ -0,0 +1,42 @@
+/* Replacement for sysconf() on windows
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include 
+#include 
+#include 
+
+long int sysconf(int name) {
+  if (name == _SC_PAGESIZE) {
+SYSTEM_INFO info;
+GetSystemInfo();
+return info.dwPageSize;
+  } else {
+errno = EINVAL;
+return -1;
+  }
+}
-- 
2.1.4



[PATCH v2] Add mman.h/.c for win32

2017-05-04 Thread Ulf Hermann
We cannot get mmap() and friends from gnulib and they don't exist on windows.
The functionality we need can be implemnted using native win32 functions, 
though.

(changelog entries were missing in V1)

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |   4 ++
 configure.ac|   7 +++
 libgnu/ChangeLog|   7 +++
 libgnu/Makefile.am  |  17 +-
 libgnu/mman_win32.c | 140 
 libgnu/sys_mman.win32.h |  63 ++
 6 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/mman_win32.c
 create mode 100644 libgnu/sys_mman.win32.h

diff --git a/ChangeLog b/ChangeLog
index 01f3197..2c0e34d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Check for sys/mman.h or alternatively MapViewOfFile().
+
 2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Check if endian.h and byteswap.h are available.
diff --git a/configure.ac b/configure.ac
index 1e6c844..6a2f991 100644
--- a/configure.ac
+++ b/configure.ac
@@ -550,6 +550,13 @@ AM_CONDITIONAL(HAVE_ENDIAN_H, [test 
"x$ac_cv_have_decl_BYTE_ORDER" = "xyes"])
 AC_CHECK_DECLS([bswap_32], [], [], [[#include ]])
 AM_CONDITIONAL(HAVE_BYTESWAP_H, [test "x$ac_cv_have_decl_bswap_32" = "xyes"])
 
+AC_CHECK_HEADERS(sys/mman.h)
+AM_CONDITIONAL(HAVE_SYS_MMAN_H, [test "x$ac_cv_header_sys_mman_h" = "xyes"])
+if test "x$ac_cv_header_sys_mman_h" != "xyes"; then
+   AC_CHECK_DECLS([MapViewOfFile], [], [], [[#include ]])
+fi
+AM_CONDITIONAL(USE_WIN32_MMAN, [test "x$ac_cv_have_decl_MapViewOfFile" = 
"xyes"])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libgnu/ChangeLog b/libgnu/ChangeLog
index ca38be2..60a049f 100644
--- a/libgnu/ChangeLog
+++ b/libgnu/ChangeLog
@@ -1,3 +1,10 @@
+2017-05-04  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: If sys/mman.h is unavailable, but MapViewOfFile is,
+   then use our own implementation of mmap and related functions.
+   * mman_win32.c: New file.
+   * sys_mman.win32.h: New file.
+
 2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Make endian.h and byteswap.h available if they don't
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 37fdb9c..5af121a 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -35,7 +35,7 @@ noinst_LIBRARIES =
 MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
-EXTRA_DIST = endian.in.h byteswap.in.h
+EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c
 CLEANFILES =
 SUFFIXES =
 
@@ -53,4 +53,19 @@ BUILT_SOURCES += byteswap.h
 MOSTLYCLEANFILES += byteswap.h
 endif
 
+if !HAVE_SYS_MMAN_H
+if USE_WIN32_MMAN
+sys/mman.h: sys_mman.win32.h
+   $(AM_V_GEN)rm -f $@ && mkdir -p sys && cat $< > $@
+BUILT_SOURCES += sys/mman.h
+MOSTLYCLEANFILES += sys/mman.h
+endif
+endif
+
 include gnulib.am
+
+if !HAVE_SYS_MMAN_H
+if USE_WIN32_MMAN
+libgnu_a_SOURCES += mman_win32.c
+endif
+endif
diff --git a/libgnu/mman_win32.c b/libgnu/mman_win32.c
new file mode 100644
index 000..78966c2
--- /dev/null
+++ b/libgnu/mman_win32.c
@@ -0,0 +1,140 @@
+/* Replacement for mmap(2) and friends on windows
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include 
+#include 
+#include 
+#include 
+
+void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t 
offset)
+{
+if (fd == -1) {
+errno = EBADF;
+return MAP_FAILED;
+}
+
+HANDLE file = (HANDLE)_get_osfhandle(fd);
+if (file == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return MAP_FAILED;
+}
+
+// Apparently there is no writeonly - we might get the write-copy mode 

[PATCH] Add mman.h/.c for win32

2017-05-04 Thread Ulf Hermann
We cannot get mmap() and friends from gnulib and they don't exist on windows.
The functionality we need can be implemnted using native win32 functions, 
though.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 configure.ac|   7 +++
 libgnu/Makefile.am  |  17 +-
 libgnu/mman_win32.c | 140 
 libgnu/sys_mman.win32.h |  63 ++
 4 files changed, 226 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/mman_win32.c
 create mode 100644 libgnu/sys_mman.win32.h

diff --git a/configure.ac b/configure.ac
index 1e6c844..6a2f991 100644
--- a/configure.ac
+++ b/configure.ac
@@ -550,6 +550,13 @@ AM_CONDITIONAL(HAVE_ENDIAN_H, [test 
"x$ac_cv_have_decl_BYTE_ORDER" = "xyes"])
 AC_CHECK_DECLS([bswap_32], [], [], [[#include ]])
 AM_CONDITIONAL(HAVE_BYTESWAP_H, [test "x$ac_cv_have_decl_bswap_32" = "xyes"])
 
+AC_CHECK_HEADERS(sys/mman.h)
+AM_CONDITIONAL(HAVE_SYS_MMAN_H, [test "x$ac_cv_header_sys_mman_h" = "xyes"])
+if test "x$ac_cv_header_sys_mman_h" != "xyes"; then
+   AC_CHECK_DECLS([MapViewOfFile], [], [], [[#include ]])
+fi
+AM_CONDITIONAL(USE_WIN32_MMAN, [test "x$ac_cv_have_decl_MapViewOfFile" = 
"xyes"])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 37fdb9c..5af121a 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -35,7 +35,7 @@ noinst_LIBRARIES =
 MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
-EXTRA_DIST = endian.in.h byteswap.in.h
+EXTRA_DIST = endian.in.h byteswap.in.h sys_mman.win32.h mman_win32.c
 CLEANFILES =
 SUFFIXES =
 
@@ -53,4 +53,19 @@ BUILT_SOURCES += byteswap.h
 MOSTLYCLEANFILES += byteswap.h
 endif
 
+if !HAVE_SYS_MMAN_H
+if USE_WIN32_MMAN
+sys/mman.h: sys_mman.win32.h
+   $(AM_V_GEN)rm -f $@ && mkdir -p sys && cat $< > $@
+BUILT_SOURCES += sys/mman.h
+MOSTLYCLEANFILES += sys/mman.h
+endif
+endif
+
 include gnulib.am
+
+if !HAVE_SYS_MMAN_H
+if USE_WIN32_MMAN
+libgnu_a_SOURCES += mman_win32.c
+endif
+endif
diff --git a/libgnu/mman_win32.c b/libgnu/mman_win32.c
new file mode 100644
index 000..78966c2
--- /dev/null
+++ b/libgnu/mman_win32.c
@@ -0,0 +1,140 @@
+/* Replacement for mmap(2) and friends on windows
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include 
+#include 
+#include 
+#include 
+
+void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t 
offset)
+{
+if (fd == -1) {
+errno = EBADF;
+return MAP_FAILED;
+}
+
+HANDLE file = (HANDLE)_get_osfhandle(fd);
+if (file == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return MAP_FAILED;
+}
+
+// Apparently there is no writeonly - we might get the write-copy mode to 
work, though.
+DWORD flProtect = PROT_NONE;
+if (prot & PROT_READ) {
+if (prot & PROT_WRITE) {
+if (prot & PROT_EXEC) {
+if (flags & MAP_PRIVATE)
+flProtect = PAGE_EXECUTE_WRITECOPY;
+else
+flProtect = PAGE_EXECUTE_READWRITE;
+} else {
+if (flags & MAP_PRIVATE)
+flProtect = PAGE_WRITECOPY;
+else
+flProtect = PAGE_READWRITE;
+}
+} else if (prot & PROT_EXEC) {
+flProtect = PAGE_EXECUTE_READ;
+}
+} else if (prot & PROT_EXEC) {
+flProtect = PAGE_EXECUTE;
+} else {
+errno = EPERM;
+return MAP_FAILED;
+}
+
+HANDLE fileMapping = CreateFileMapping(file, NULL, flProtect, 0, 0, NULL);
+if (fileMapping == NULL) {
+errno = EINVAL; // windows docs say this happens on disk full. EINVAL 
is close enough.
+return MAP_FAILE

[PATCH] Add replacement endian.h and byteswap.h to libgnu

2017-05-03 Thread Ulf Hermann
Some systems don't provide endian.h and byteswap.h. The required
functions are trivial to define using sys/param.h and gcc builtins,
though.

Also, include endian.h in dwelf_scn_gnu_compressed_size.c as that uses
be64toh().

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog|  4 ++
 configure.ac |  6 +++
 libdwelf/ChangeLog   |  4 ++
 libdwelf/dwelf_scn_gnu_compressed_size.c |  1 +
 libgnu/ChangeLog |  6 +++
 libgnu/Makefile.am   | 17 +++-
 libgnu/byteswap.in.h | 38 
 libgnu/endian.in.h   | 75 
 8 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100644 libgnu/ChangeLog
 create mode 100644 libgnu/byteswap.in.h
 create mode 100644 libgnu/endian.in.h

diff --git a/ChangeLog b/ChangeLog
index d43eeb6..01f3197 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Check if endian.h and byteswap.h are available.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Determine the binary format we're building natively.
diff --git a/configure.ac b/configure.ac
index a854013..1e6c844 100644
--- a/configure.ac
+++ b/configure.ac
@@ -544,6 +544,12 @@ else
 fi
 AC_SUBST([intl_LDADD])
 
+AC_CHECK_DECLS([BYTE_ORDER], [], [], [[#include ]])
+AM_CONDITIONAL(HAVE_ENDIAN_H, [test "x$ac_cv_have_decl_BYTE_ORDER" = "xyes"])
+
+AC_CHECK_DECLS([bswap_32], [], [], [[#include ]])
+AM_CONDITIONAL(HAVE_BYTESWAP_H, [test "x$ac_cv_have_decl_bswap_32" = "xyes"])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libdwelf/ChangeLog b/libdwelf/ChangeLog
index a332655..29af410 100644
--- a/libdwelf/ChangeLog
+++ b/libdwelf/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * dwelf_scn_gnu_compressed_size.c: Include endian.h.
+
 2015-10-11  Akihiko Odaki  <akihiko.odaki...@stu.hosei.ac.jp>
 
* dwelf_strtab.c: Remove sys/param.h include.
diff --git a/libdwelf/dwelf_scn_gnu_compressed_size.c 
b/libdwelf/dwelf_scn_gnu_compressed_size.c
index d39b702..6bad8af 100644
--- a/libdwelf/dwelf_scn_gnu_compressed_size.c
+++ b/libdwelf/dwelf_scn_gnu_compressed_size.c
@@ -30,6 +30,7 @@
 # include 
 #endif
 
+#include 
 #include "libdwelfP.h"
 #include "libelfP.h"
 
diff --git a/libgnu/ChangeLog b/libgnu/ChangeLog
new file mode 100644
index 000..ca38be2
--- /dev/null
+++ b/libgnu/ChangeLog
@@ -0,0 +1,6 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Make endian.h and byteswap.h available if they don't
+   exist.
+   * byteswap.in.h: New file.
+   * endian.in.h: New file.
diff --git a/libgnu/Makefile.am b/libgnu/Makefile.am
index 0d31e69..37fdb9c 100644
--- a/libgnu/Makefile.am
+++ b/libgnu/Makefile.am
@@ -35,7 +35,22 @@ noinst_LIBRARIES =
 MOSTLYCLEANFILES =
 MOSTLYCLEANDIRS =
 BUILT_SOURCES =
-EXTRA_DIST =
+EXTRA_DIST = endian.in.h byteswap.in.h
 CLEANFILES =
 SUFFIXES =
+
+if !HAVE_ENDIAN_H
+endian.h: endian.in.h
+   $(AM_V_GEN)rm -f $@ && cat $< > $@
+BUILT_SOURCES += endian.h
+MOSTLYCLEANFILES += endian.h
+endif
+
+if !HAVE_BYTESWAP_H
+byteswap.h: byteswap.in.h
+   $(AM_V_GEN)rm -f $@ && cat $< > $@
+BUILT_SOURCES += byteswap.h
+MOSTLYCLEANFILES += byteswap.h
+endif
+
 include gnulib.am
diff --git a/libgnu/byteswap.in.h b/libgnu/byteswap.in.h
new file mode 100644
index 000..e7b4f29
--- /dev/null
+++ b/libgnu/byteswap.in.h
@@ -0,0 +1,38 @@
+/* Byteswapping functions for windows
+   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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef LIB_BYTESWAP_H
+#define LIB_BYTESWAP_H 1
+
+#include 
+
+#define bswap_16

[PATCH] If f(un)lockfile is unavailable define it away

2017-05-03 Thread Ulf Hermann
Sometimes _POSIX_THREAD_SAFE_FUNCTIONS is still set in this case, which
in turn leads to build problems in getopt.c (which would define the
functions to nop anyway if it knew they aren't present).

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 lib/ChangeLog   | 5 +
 lib/eu-config.h | 7 +++
 2 files changed, 12 insertions(+)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index ecc6179..58ee43f 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eu-config.h: Define flockfile and funlockfile away if gnulib hasn't
+   detected them.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* eu-config.h: Define attribute_hidden to be empty if the compiler
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 135803e..e69b213 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -198,5 +198,12 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define COMPAT_VERSION(name, version, prefix) error "should use #ifdef 
SYMBOL_VERSIONING"
 #endif
 
+#if !HAVE_FLOCKFILE
+# define flockfile(fp) /* nop */
+#endif
+
+#if !HAVE_FUNLOCKFILE
+# define funlockfile(fp) /* nop */
+#endif
 
 #endif /* eu-config.h */
-- 
2.1.4



[PATCH v2] Detect if symbol versioning is supported (was "Disable symbol versioning if .symver doesn't work")

2017-05-03 Thread Ulf Hermann
If not, throw an error unless symbol versioning was explicitly
disabled.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog|  4 
 configure.ac | 15 +++
 2 files changed, 19 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 01f88f3..22c46c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Test if symbol versioning is supported.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Check if the compiler supports
diff --git a/configure.ac b/configure.ac
index 0266a36..48b06de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -376,6 +376,21 @@ AS_IF([test "x$enable_textrelcheck" != "xno"],
 AC_ARG_ENABLE([symbol-versioning],
 AS_HELP_STRING([--disable-symbol-versioning],
[Disable symbol versioning in shared objects]))
+
+AC_CACHE_CHECK([whether symbol versioning is supported], 
ac_cv_symbol_versioning, [dnl
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+#define NEW_VERSION(name, version) \
+  asm (".symver " #name "," #name "@@@" #version);
+int foo(int x) { return x + 1; }
+NEW_VERSION (foo, ELFUTILS_12.12)
+])], ac_cv_symbol_versioning=yes, ac_cv_symbol_versioning=no)])
+if test "$ac_cv_symbol_versioning" = "no"; then
+if test "x$enable_symbol_versioning" != "xno"; then
+AC_MSG_ERROR([Symbol versioning is not supported.
+  Use --disable-symbol-versioning to build without.])
+fi
+fi
+
 AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
 AS_IF([test "x$enable_symbol_versioning" = "xno"],
   [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.])
-- 
2.1.4



Re: pending patches

2017-05-03 Thread Ulf Hermann
> - Check for -z,defs, -z,relro, -fPIC, -fPIE before using them
>   There are actually two versions, I haven't looked yet how they differ.
> - Check if gcc complains about __attribute__ (visibility(..))
> - Disable symbol versioning if .symver doesn't work
> - Check if rpath is supported before setting it
> 
> In all of the above cases checking for support is a good thing.
> But I am a little hesitant about automatically disabling support.
> For example our binary compatibility depends on having symbol versioning
> support. It seems bad to "silently" break that. And without rpath
> support backends aren't found and stuff will mysteriously break. So I
> think I prefer configure to error out and have an explicit override
> option someone would have to use indicating they are building a broken
> elfutils.

That can be done. I will post new versions of the patches to add a configure 
switch.

My problem right now is that I have about 50 more patches pending locally and I 
will be gone from May 12th to sometime in August. So, I probably won't manage 
to post and fix all of them here before autumn. Yet, I still need them for the 
Qt Creator (and perfparser) 4.4 release, for which the feature freeze will 
happen when I'm gone.

To deal with this, right now I have a fork of elfutils at 
http://code.qt.io/cgit/qt-creator/elfutils.git/ which receives the patches 
before they get here. This is not great and I want to merge it eventually, but 
I can't clone myself.

> - Check if we need -lintl for linking gettext
>   This looks OK, but I don't know much about gettext support.

It's just that mingw doesn't really have a libc and msvcrt.dll doesn't have 
gettext. So we need to link libintl.a or libintl.dll (as provided by mingw) 
separately.

> - Generalize library names
>   This looks like a nice cleanup, but I don't know anything about how
>   non-gnu/linux systems do library sonames (I also use a local hack
>   sometimes to explicitly set a different version that I should upstream
>   myself).

Well, not at all. It's called dll hell :(. The patch provides binaries with the 
version encoded into the file name, which can make things somewhat better. 
However, as dw.dll (and dw1.dll and dw-0.168.dll) link against plain elf.dll, 
extra hackery is required if you want to use the files with versions encoded. 
Also you cannot do "-lelf" then, but rather "-lelf1".

Ulf


[PATCH] Check if gcc supports -rdynamic and don't use it if not

2017-05-03 Thread Ulf Hermann
On some platforms the symbols are automatically exported and -rdynamic 
will produce a warning.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog |  4 
 configure.ac  | 11 +++
 tests/ChangeLog   |  5 +
 tests/Makefile.am |  2 +-
 4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index d43eeb6..eaea959 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Add check for -rdynamic.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Determine the binary format we're building natively.
diff --git a/configure.ac b/configure.ac
index 18ef6d6..e45584e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,6 +237,17 @@ fi
 
 AC_SUBST([dso_LDFLAGS])
 
+rdynamic_LDFLAGS="-rdynamic"
+AC_CACHE_CHECK([whether gcc supports $rdynamic_LDFLAGS], ac_cv_rdynamic, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$rdynamic_LDFLAGS $save_LDFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_rdynamic=yes, ac_cv_rdynamic=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_rdynamic" = "no"; then
+   rdynamic_LDFLAGS=""
+fi
+
 AC_CACHE_CHECK([for rpath support], ac_cv_rpath, [dnl
 save_LDFLAGS="$LDFLAGS"
 LDFLAGS="$save_LDFLAGS -Wl,--enable-new-dtags,-rpath,/foo/bar"
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ab1a3788..b00c848 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-03  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Skip -rdynamic when compiling deleted-lib.so with a
+   compiler that doesn't support it.
+
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
* run-disasm-x86-64.sh: Disable if the native binary format is not
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 943c694..114ab7a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -520,7 +520,7 @@ endif
 system_elf_libelf_test_LDADD = $(libelf) $(libgnu)
 
 deleted-lib$(LIBEXT): deleted-lib.c $(libgnu)
-   $(AM_V_CCLD)$(COMPILE) $(fpic_CFLAGS) -fasynchronous-unwind-tables 
-shared -rdynamic -o $@ $^
+   $(AM_V_CCLD)$(COMPILE) $(fpic_CFLAGS) -fasynchronous-unwind-tables 
-shared $(rdynamic_LDFLAGS) -o $@ $^
 
 if GCOV
 check: check-am coverage
-- 
2.1.4



Re: [PATCH] Avoid double-including config.h

2017-05-02 Thread Ulf Hermann

Maybe we can cleanup that last
one once we integrate gnulib (which I believe has a good/64-off_t fts.h
already).


gnulib is among the bad ones. Or, at least we detect it as bad.

Ulf


[PATCH] Check native binary format

2017-04-28 Thread Ulf Hermann
If our native binary format is not ELF, there is no point in doing the
textrel check and we have to exclude some tests that compile source
code with the native compiler and then check something on the resulting
binary with elfutils.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog  |  4 
 config/ChangeLog   |  4 
 config/eu.am   |  4 
 configure.ac   |  3 +++
 tests/ChangeLog| 16 
 tests/run-disasm-x86-64.sh |  5 +
 tests/run-disasm-x86.sh|  5 +
 tests/run-dwfllines.sh |  5 +
 tests/run-elf_cntl_gelf_getshdr.sh |  5 +
 tests/run-elflint-self.sh  |  5 +
 tests/run-low_high_pc.sh   |  6 ++
 tests/run-native-test.sh   |  5 +
 tests/run-nm-self.sh   |  5 +
 tests/run-readelf-self.sh  |  5 +
 tests/run-strip-reloc.sh   |  5 +
 tests/run-strip-strmerge.sh|  5 +
 tests/test-nlist.c |  6 +-
 17 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 3613beb..d43eeb6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Determine the binary format we're building natively.
+
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Determine library naming conventions and define
LIBPREFIX, LIBEXT and common names for elf, dw, asm accordingly.
 
diff --git a/config/ChangeLog b/config/ChangeLog
index 59569e3..0f240ea 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * eu.am: Disable textrel_check if we're not building ELF files.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* eu.am: Use fpic_CFLAGS.
diff --git a/config/eu.am b/config/eu.am
index bc8c767..e692341 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -107,7 +107,11 @@ textrel_found = $(textrel_msg); exit 1
 else
 textrel_found = $(textrel_msg)
 endif
+if NATIVE_ELF
 textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); 
fi
+else
+textrel_check =
+endif
 
 print-%:
@echo $*=$($*)
diff --git a/configure.ac b/configure.ac
index b2e03bb..18ef6d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,9 @@ AC_SUBST([LIBPREFIX])
 AC_DEFINE_UNQUOTED(LIBPREFIX, "$LIBPREFIX")
 AH_TEMPLATE([LIBPREFIX], [Host system file name prefix for dynamic libraries.])
 AM_CONDITIONAL(POSTFIX_LIB_VERSION, test "$eu_postfix_lib_version" = "yes")
+AM_CONDITIONAL(NATIVE_ELF, test "$LIBEXT" = ".so")
+AM_CONDITIONAL(NATIVE_PE, test "$LIBEXT" = ".dll")
+AM_CONDITIONAL(NATIVE_MACHO, test "$LIBEXT" = ".dylib")
 
 eu_LIBNAME(elf,1)
 eu_LIBNAME(dw,1)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d5bda6d..a9bc6fa 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,21 @@
 2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * run-disasm-x86-64.sh: Disable if the native binary format is not
+   ELF.
+   * run-disasm-x86.sh: Likewise.
+   * run-dwfllines.sh: Likewise.
+   * run-elf_cntl_gelf_getshdr.sh: Likewise.
+   * run-elflint-self.sh: Likewise.
+   * run-low_high_pc.sh: Likewise.
+   * run-native-test.sh: Likewise.
+   * run-nm-self.sh: Likewise.
+   * run-readelf-self.sh: Likewise.
+   * run-strip-reloc.sh: Likewise.
+   * run-strip-strmerge.sh: Likewise.
+   * test-nlist.c: Likewise.
+
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use the predefined names for libelf, libdw, libasm,
rather than hardcoding to the elf conventions and add the right
extension to deleted-lib..
diff --git a/tests/run-disasm-x86-64.sh b/tests/run-disasm-x86-64.sh
index a6be62b..c5256b7 100755
--- a/tests/run-disasm-x86-64.sh
+++ b/tests/run-disasm-x86-64.sh
@@ -17,6 +17,11 @@
 
 . $srcdir/test-subr.sh
 
+if ! grep -q -F '#define LIBEXT ".so"' ${abs_top_builddir}/config.h; then
+  echo "only works with native ELF binaries."
+  exit 77
+fi
+
 # Run x86-64 test.
 case "`uname -m`" in
   x86_64)
diff --git a/tests/run-disasm-x86.sh b/tests/run-disasm-x86.sh
index 28a3df7..e0b6ee3 100755
--- a/tests/run-disasm-x86.sh
+++ b/tests/run-disasm-x86.sh
@@ -17,6 +17,11 @@
 
 . $srcdir/test-subr.sh
 
+if ! grep -q -F '#define LIBEXT ".so"' ${abs_top_builddir}/config.h; then
+  echo "only works with native ELF binaries."
+  exit 77
+fi
+
 # Run x86 test.
 case "`uname -m`" in
   x86_64 | i?86 )
diff --git a/tests/run-dwfllines.sh b/tests/run-dwfllines.sh
index b384de0..c228d7d 100755
--- a/tests/run-dwfllines.sh
+++ b/tests/run-dwfllines.sh
@@ -83,6 +83,11 @@ mod:  CU: [9e4] m.c
  time: 0, len

[PATCH] Generalize library names

2017-04-28 Thread Ulf Hermann
On windows library names end with ".dll" and the prefix "lib" us usually
omitted. Take this into account and also drop the $(EXEEXT) workaround.
We don't need to use noinst_PROGRAMS as there is also noinst_DATA.

Change-Id: I7e4ba2432811d5ad85051ea0c9d5674eabf79b3c
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  5 +
 backends/ChangeLog  |  5 +
 backends/Makefile.am| 33 +
 configure.ac| 30 ++
 libasm/ChangeLog|  5 +
 libasm/Makefile.am  | 28 +---
 libdw/ChangeLog |  5 +
 libdw/Makefile.am   | 28 +---
 libebl/ChangeLog|  6 ++
 libebl/Makefile.am  |  2 ++
 libebl/eblopenbackend.c |  9 +
 libelf/ChangeLog|  5 +
 libelf/Makefile.am  | 26 --
 m4/ChangeLog|  4 
 m4/libname.m4   | 38 ++
 src/ChangeLog   |  5 +
 src/Makefile.am |  6 +++---
 tests/ChangeLog |  8 
 tests/Makefile.am   | 22 +-
 tests/run-deleted.sh|  8 +---
 20 files changed, 199 insertions(+), 79 deletions(-)
 create mode 100644 m4/libname.m4

diff --git a/ChangeLog b/ChangeLog
index 01f88f3..3613beb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Determine library naming conventions and define
+   LIBPREFIX, LIBEXT and common names for elf, dw, asm accordingly.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Check if the compiler supports
diff --git a/backends/ChangeLog b/backends/ChangeLog
index baeb7b9..e2f0529 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-28  Ulf Hermann <ulf.herm...@qt.io>
+
+   * Makefile.am: Have the backend file names follow the platform's
+   convention for naming shared libraries.
+
 2017-04-27  Ulf Hermann <ulf.herm...@qt.io>
 
* Makefile.am: Use dso_LDFLAGS.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 6dc2022..55ff871 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -40,11 +40,12 @@ libebl_pic = libebl_i386_pic.a libebl_sh_pic.a 
libebl_x86_64_pic.a\
 libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \
 libebl_m68k_pic.a libebl_bpf_pic.a
 noinst_LIBRARIES = $(libebl_pic)
-noinst_DATA = $(libebl_pic:_pic.a=.so)
+libebl_pic_prefixed = $(libebl_pic:lib%=$(LIBPREFIX)%)
+noinst_DATA = $(libebl_pic_prefixed:_pic.a=$(LIBEXT))
 
 
-libelf = ../libelf/libelf.so
-libdw = ../libdw/libdw.so
+libelf = ../libelf/$(libelf_BARE)
+libdw = ../libdw/$(libdw_BARE)
 if USE_GNULIB
 libgnu = ../libgnu/libgnu.a
 else
@@ -134,32 +135,32 @@ 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) $(libgnu)
-   @rm -f $(@:.so=.map)
+$(LIBPREFIX)ebl_%$(LIBEXT) $(LIBPREFIX)ebl_%.map: libebl_%_pic.a $(libelf) 
$(libdw) $(libgnu)
+   @rm -f $(@:$(LIBEXT)=.map)
$(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: 
*; };' \
- > $(@:.so=.map)
-   $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \
+ > $(@:$(LIBEXT)=.map)
+   $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=$(LIBEXT)) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-   -Wl,--version-script,$(@:.so=.map) \
+   -Wl,--version-script,$(@:$(LIBEXT)=.map) \
-Wl,--as-needed $(libelf) $(libdw) $(libgnu) $(intl_LDADD)
@$(textrel_check)
 
-libebl_i386.so: $(cpu_i386)
-libebl_x86_64.so: $(cpu_x86_64)
-libebl_bpf.so: $(cpu_bpf)
+$(LIBPREFIX)ebl_i386$(LIBEXT): $(cpu_i386)
+$(LIBPREFIX)ebl_x86_64$(LIBEXT): $(cpu_x86_64)
+$(LIBPREFIX)ebl_bpf$(LIBEXT): $(cpu_bpf)
 
 install: install-am install-ebl-modules
 install-ebl-modules:
$(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
for m in $(modules); do \
- $(INSTALL_PROGRAM) libebl_$${m}.so 
$(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
- ln -fs libebl_$${m}-$(PACKAGE_VERSION).so 
$(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+ $(INSTALL_PROGRAM) $(LIBPREFIX)ebl_$${m}$(LIBEXT) 
$(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/$(LIBPREFIX)ebl_$${m}-$(PACKAGE_VERSION)$(LIBEXT);
 \
+ ln -fs $(LIBPREFIX)ebl_$${m}-$(PACKAGE_VERSION)$(LIBEXT) 
$(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/$(LIBPREFIX)ebl_$${m}$(LIBEXT); \
done
 
 uninstall: uninstall-am
for m in $(modules); do \
- rm -f 
$(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
- rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+ rm -f 
$(DESTDIR)$(libdir)/$(LIBE

[PATCH] Disable symbol versioning if .symver doesn't work

2017-04-28 Thread Ulf Hermann

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog|  5 +
 configure.ac | 12 
 2 files changed, 17 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 01f88f3..fb7317c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Test if symbol versioning is supported and
+   automatically disable it if not.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Check if the compiler supports
diff --git a/configure.ac b/configure.ac
index 0266a36..efcd3c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -376,6 +376,18 @@ AS_IF([test "x$enable_textrelcheck" != "xno"],
 AC_ARG_ENABLE([symbol-versioning],
 AS_HELP_STRING([--disable-symbol-versioning],
[Disable symbol versioning in shared objects]))
+
+AC_CACHE_CHECK([whether symbol versioning is supported], 
ac_cv_symbol_versioning, [dnl
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+#define NEW_VERSION(name, version) \
+  asm (".symver " #name "," #name "@@@" #version);
+int foo(int x) { return x + 1; }
+NEW_VERSION (foo, ELFUTILS_12.12)
+])], ac_cv_symbol_versioning=yes, ac_cv_symbol_versioning=no)])
+if test "$ac_cv_symbol_versioning" = "no"; then
+   enable_symbol_versioning=no
+fi
+
 AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
 AS_IF([test "x$enable_symbol_versioning" = "xno"],
   [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.])
-- 
2.1.4



[PATCH] Check if we need -lintl for linking gettext

2017-04-28 Thread Ulf Hermann
We might not have gettext available from libc and we cannot get it from
gnulib either.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog|  5 +
 backends/ChangeLog   |  4 
 backends/Makefile.am |  2 +-
 configure.ac | 25 +
 libasm/ChangeLog |  4 
 libasm/Makefile.am   |  2 +-
 libcpu/ChangeLog |  4 
 libcpu/Makefile.am   |  2 +-
 libdw/ChangeLog  |  4 
 libdw/Makefile.am|  2 +-
 libelf/ChangeLog |  4 
 libelf/Makefile.am   |  2 +-
 src/ChangeLog|  4 
 src/Makefile.am  | 30 +++---
 tests/ChangeLog  |  4 
 tests/Makefile.am| 18 +-
 16 files changed, 87 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 01f88f3..ccfb3ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Check for availability of dgettext from either libc or
+   a separate libintl.
+
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Check if the compiler supports
diff --git a/backends/ChangeLog b/backends/ChangeLog
index baeb7b9..a35d83a 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-28  Ulf Hermann <ulf.herm...@qt.io>
+
+   * Makefile.am: Use intl_LDADD.
+
 2017-04-27  Ulf Hermann <ulf.herm...@qt.io>
 
* Makefile.am: Use dso_LDFLAGS.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 3e1992e..6dc2022 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -141,7 +141,7 @@ libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) 
$(libgnu)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-Wl,--version-script,$(@:.so=.map) \
-   -Wl,--as-needed $(libelf) $(libdw) $(libgnu)
+   -Wl,--as-needed $(libelf) $(libdw) $(libgnu) $(intl_LDADD)
@$(textrel_check)
 
 libebl_i386.so: $(cpu_i386)
diff --git a/configure.ac b/configure.ac
index 165149d..0266a36 100644
--- a/configure.ac
+++ b/configure.ac
@@ -431,6 +431,31 @@ CFLAGS="$old_CFLAGS"])
 AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING,
   [test "x$ac_cv_implicit_fallthrough" != "xno"])
 
+dnl Check if gettext is available form libc
+AC_LINK_IFELSE(
+   [AC_LANG_PROGRAM(
+   [#include ],
+   [dgettext("foo", "bar"); return 0;]
+   )],
+   [libc_has_gettext="true"],
+   [libc_has_gettext="false"]
+)
+
+dnl If our libc doesn't provide gettext, then test for libintl
+if test "$libc_has_gettext" = "false" ; then
+   AC_MSG_WARN("libc does not have gettext")
+   AC_CHECK_LIB([intl], [dgettext], [have_intl="true"], 
[have_intl="false"], [-liconv])
+
+   if test "$have_intl" = "false"; then
+   AC_MSG_ERROR("no libintl found")
+   else
+   intl_LDADD="-lintl -liconv"
+   fi
+else
+   intl_LDADD=""
+fi
+AC_SUBST([intl_LDADD])
+
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 971492a..066c64e 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Use intl_LDADD.
+
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use dso_LDFLAGS.
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index a5fc9fc..30f7fa9 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -55,7 +55,7 @@ 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_LDLIBS = $(intl_LDADD)
 if USE_LOCKS
 libasm_so_LDLIBS += -lpthread
 endif
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index ef5da58..42cfb58 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-28  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * Makefile.am: Use intl_LDADD.
+
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Use fpic_CFLAGS.
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index 9ca0f43..d277583 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -90,7 +90,7 @@ i386_lex_CFLAGS = -Wno-unused-label -Wno-unused-function 
-Wno-sign-compare
 i386_parse.o: i386_parse.c i386.mnemonics
 i386_parse_CFLAGS = -DNMNES="`wc -l < i386.mnemonics`"
 i386_lex.o: i386_parse.h
-i386_gendis_LDADD = $(libeu) $(libgnu) -lm
+i386_gendis_LDADD = $(libeu) $(libgnu) $(intl_LDADD) -lm
 
 i386_

Re: [PATCH] Make elf section sorting more deterministic

2017-04-28 Thread Ulf Hermann
On 04/27/2017 09:41 PM, Mark Wielaard wrote:
> On Thu, Apr 20, 2017 at 04:54:26PM +0200, Ulf Hermann wrote:
>> At least one test (dwfl-addr-sect) depends on the order of elf sections
>> with equal addresses. This is not guaranteed by the code. Compare also
>> by end address and name to tell entries apart.
> 
> O, interesting find. If the start addresses match the order depends on
> the specific qsort algorithm. So you need a real tie breaker.
> 
> I think it is simpler and more predictable if we just take the section
> number into account. It seem to have the added benefit that it provide
> the same ordering as before with the glibc qsort, so no testcases need
> to be adjusted. Does the following work for you?
> 
> diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c
> index 439a24e..0d10672 100644
> --- a/libdwfl/derelocate.c
> +++ b/libdwfl/derelocate.c
> @@ -63,7 +63,10 @@ compare_secrefs (const void *a, const void *b)
>if ((*p1)->start > (*p2)->start)
>  return 1;
>  
> -  return 0;
> +  /* Same start address, then just compare which section came first.  */
> +  size_t n1 = elf_ndxscn ((*p1)->scn);
> +  size_t n2 = elf_ndxscn ((*p2)->scn);
> +  return n1 - n2;

I would inline the whole thing to

return elf_ndxscn (p1->scn) - elf_ndxscn (p2->scn);

There is no point in forcing the compiler to keep the intermediate numbers as 
(signed) size_t. Also, I would still keep the check for p1->end and p2->end 
before this. If we have a section of size 0, and another one of size > 0 
starting at the same place, we want them to be sorted by end address. The 
zero-sized section should be squeezed in before the one that actually has a 
size, not after it.

Ulf


Re: [PATCH] On elf_update, remember when we mmap()

2017-04-28 Thread Ulf Hermann
On 04/28/2017 12:23 AM, Mark Wielaard wrote:
> On Thu, Apr 20, 2017 at 04:57:41PM +0200, Ulf Hermann wrote:
>> Otherwise we skip the munmap() later. This leaks resources.
> 
> Oops. Good find. Applied to master.
> 
> When configured --with-valgrind the tests are run under valgrind
> and memory leaks will fail the tests. But since this is mmap
> valgrind won't report it. How did you find it?

On windows you cannot rename or unlink files if there are still open views on 
it (and the win32 view mechanism is how I implement mmap on windows). So, the 
test cases fail then because the directories are not empty.

Ulf


Re: [PATCH] Don't look for kernel version if not running on linux

2017-04-28 Thread Ulf Hermann
On 04/27/2017 08:02 PM, Mark Wielaard wrote:
> On Thu, Apr 20, 2017 at 04:08:48PM +0200, Ulf Hermann wrote:
>> We don't want to use it, even if it exists.
> 
> I am not sure this is really the right place to patch.
> The value is retrieved through uname () which is POSIX and so should
> be available even on non-GNU/Linux systems. When kernel_release ()
> returns NULL the callers expect errno to be set so they can use it
> to return a failure code.

You can get uname() on Windows through gnulib, but at the cost at linking to 
additional windows DLLs. It calls gethostname and for that we need to link 
against ws2_32.dll. That's an unreasonable dependency for getting something we 
cannot use anyway. I suggest we just set errno to ENOTSUP then.

Ulf


[PATCH] Check if gcc complains about __attribute__ (visibility(..))

2017-04-27 Thread Ulf Hermann
If so, define attribute_hidden to be empty. Also, use attribute_hidden
in all places where we hide symbols.

Change-Id: I37353459710dbbd1c6c6c46110514fc18515c814
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog   |  5 +
 configure.ac| 16 
 lib/ChangeLog   |  5 +
 lib/eu-config.h |  4 
 libdw/ChangeLog |  5 +
 libdw/libdwP.h  |  2 +-
 libdw/libdw_alloc.c |  2 +-
 libelf/ChangeLog|  4 
 libelf/libelfP.h|  2 +-
 9 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 36c3cc7..01f88f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * configure.ac: Check if the compiler supports
+   __attribute__((visibility(...))).
+
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs,
and -Wl,-z,relro are supported by the compiler.
 
diff --git a/configure.ac b/configure.ac
index 107762f..165149d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,22 @@ CFLAGS="$old_CFLAGS"])
 AS_IF([test "x$ac_cv_c99" != xyes],
   AC_MSG_ERROR([gcc with GNU99 support required]))
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))],
+   ac_cv_visibility, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+int __attribute__((visibility("hidden")))
+foo (int a)
+{
+  return a;
+}])], ac_cv_visibility=yes, ac_cv_visibility=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_visibility" = "yes"; then
+   AC_DEFINE([HAVE_VISIBILITY], [1],
+ [Defined if __attribute__((visibility())) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
 save_CFLAGS="$CFLAGS"
 CFLAGS="$save_CFLAGS -fPIC -Werror"
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 605b9b9..ecc6179 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * eu-config.h: Define attribute_hidden to be empty if the compiler
+   doesn't support it.
+
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use fpic_CFLAGS.
 
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 400cdc6..0709828 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -68,8 +68,12 @@
 #define internal_strong_alias(name, aliasname) \
   extern __typeof (name) aliasname __attribute__ ((alias (#name))) 
internal_function;
 
+#ifdef HAVE_VISIBILITY
 #define attribute_hidden \
   __attribute__ ((visibility ("hidden")))
+#else
+#define attribute_hidden /* empty */
+#endif
 
 /* Define ALLOW_UNALIGNED if the architecture allows operations on
unaligned memory locations.  */
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index d15c861..79c3898 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,10 @@
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * libdwP.h: Use attribute_hidden.
+       * libdw_alloc.c: Likewise.
+
+2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
 
 2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 5d095a7..cefcafd 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -433,7 +433,7 @@ extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, 
size_t align)
  __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
 
 /* Default OOM handler.  */
-extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
+extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden;
 
 /* Allocate the internal data for a unit not seen before.  */
 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c
index 28a8cf6..d6af23a 100644
--- a/libdw/libdw_alloc.c
+++ b/libdw/libdw_alloc.c
@@ -70,7 +70,7 @@ dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler)
 
 
 void
-__attribute ((noreturn, visibility ("hidden")))
+__attribute ((noreturn)) attribute_hidden
 __libdw_oom (void)
 {
   while (1)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 1c6cce2..fd58ed3 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * libelfP.h: Use attribute_hidden.
+
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
 
 2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 7ee6625..a4a0a3a 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -578,7 +578,7 @@ extern Elf_Data *__elf64_xlatetof_internal (Elf_Data 
*__dest,
 extern unsig

[PATCH] Drop handrolled or #ifdef'ed libc replacements

2017-04-27 Thread Ulf Hermann
mempcpy, memrchr, rawmemchr, and argp are provided by gnulib now. We
don't need to define them locally and we don't need to search for an
external libargp.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 ChangeLog  |  4 
 configure.ac   | 31 ---
 lib/ChangeLog  |  5 +
 lib/system.h   |  5 -
 lib/xstrndup.c |  2 +-
 libasm/ChangeLog   |  4 
 libasm/disasm_str.c|  2 +-
 libdw/ChangeLog|  4 
 libdw/Makefile.am  |  2 +-
 libdwfl/ChangeLog  |  4 
 libdwfl/linux-kernel-modules.c |  1 -
 libebl/ChangeLog   |  5 +
 libebl/eblmachineflagname.c|  1 -
 libebl/eblopenbackend.c|  1 -
 libelf/ChangeLog   |  5 +
 libelf/elf_getarsym.c  |  8 
 libelf/elf_strptr.c| 11 ---
 src/ChangeLog  |  4 
 src/Makefile.am| 30 +++---
 tests/ChangeLog|  5 +
 tests/Makefile.am  | 32 
 tests/elfstrmerge.c|  1 -
 22 files changed, 74 insertions(+), 93 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a2a0f63..6fe525c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * configure.ac: Drop checks for memrchr, rawmemchr, mempcpy, argp.
+
 2017-04-21  Ulf Hermann  <ulf.herm...@qt.io>
 
* .gitignore: Add generated gnulib headers.
diff --git a/configure.ac b/configure.ac
index a5aea7f..a48b13e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -290,13 +290,7 @@ zip_LIBS="$LIBS"
 LIBS="$save_LIBS"
 AC_SUBST([zip_LIBS])
 
-AC_CHECK_DECLS([memrchr, rawmemchr],[],[],
-   [#define _GNU_SOURCE
-#include ])
 AC_CHECK_DECLS([powerof2],[],[],[#include ])
-AC_CHECK_DECLS([mempcpy],[],[],
-   [#define _GNU_SOURCE
-#include ])
 
 AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
 AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
@@ -369,31 +363,6 @@ CFLAGS="$old_CFLAGS"])
 AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING,
   [test "x$ac_cv_implicit_fallthrough" != "xno"])
 
-dnl Check if we have argp available from our libc
-AC_LINK_IFELSE(
-   [AC_LANG_PROGRAM(
-   [#include ],
-   [int argc=1; char *argv[]={"test"}; 
argp_parse(0,argc,,0,0,0); return 0;]
-   )],
-   [libc_has_argp="true"],
-   [libc_has_argp="false"]
-)
-
-dnl If our libc doesn't provide argp, then test for libargp
-if test "$libc_has_argp" = "false" ; then
-   AC_MSG_WARN("libc does not have argp")
-   AC_CHECK_LIB([argp], [argp_parse], [have_argp="true"], 
[have_argp="false"])
-
-   if test "$have_argp" = "false"; then
-   AC_MSG_ERROR("no libargp found")
-   else
-   argp_LDADD="-largp"
-   fi
-else
-   argp_LDADD=""
-fi
-AC_SUBST([argp_LDADD])
-
 dnl Check if we have  for EM_BPF disassembly.
 AC_CHECK_HEADERS(linux/bpf.h)
 AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 8cac7af..82c009e 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * system.h: Drop mempcpy replacement.
+   * xstrndup.c: Don't include system.h.
+
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
* crc32.c: include config.h.
diff --git a/lib/system.h b/lib/system.h
index 9203335..ffa2bc7 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -63,11 +63,6 @@
 #define powerof2(x) (((x) & ((x) - 1)) == 0)
 #endif
 
-#if !HAVE_DECL_MEMPCPY
-#define mempcpy(dest, src, n) \
-((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
-#endif
-
 /* A special gettext function we use if the strings are too short.  */
 #define sgettext(Str) \
   ({ const char *__res = strrchr (gettext (Str), '|');   \
diff --git a/lib/xstrndup.c b/lib/xstrndup.c
index a257aa9..d43e3b9 100644
--- a/lib/xstrndup.c
+++ b/lib/xstrndup.c
@@ -33,7 +33,7 @@
 #include 
 #include 
 #include "libeu.h"
-#include "system.h"
+
 
 /* Return a newly allocated copy of STRING.  */
 char *
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index ef183a6..80aa7de 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * disasm_str.c: Don't include system.h
+
 2017-02-21  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am: Link libasm agaist libgnu.a if requested.
diff --git a/libasm/disasm_str.c b/li

[PATCH] Fix nesting of braces

2017-04-27 Thread Ulf Hermann

The way it was before it didn't actually test if elf_update failed, but
rather did something random. !!() is a boolean and boolean
true can be represented as anything non-0, including negative numbers.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libasm/ChangeLog | 4 
 libasm/asm_end.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 1656842..d2bc408 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * asm_end.c (binary_end): Fix nesting of braces.
+
 2017-02-12  Mark Wielaard  <m...@redhat.com>
* asm_newsym.c (asm_newsym): Increase TEMPSYMLEN to 13.
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index 191a535..ced24f5 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -464,7 +464,7 @@ binary_end (AsmCtx_t *ctx)
   gelf_update_ehdr (ctx->out.elf, ehdr);
/* Write out the ELF file.  */
-  if (unlikely (elf_update (ctx->out.elf, ELF_C_WRITE_MMAP)) < 0)
+  if (unlikely (elf_update (ctx->out.elf, ELF_C_WRITE_MMAP) < 0))
 {
   __libasm_seterrno (ASM_E_LIBELF);
   result = -1;
--
2.8.1.windows.1



Re: [PATCH 5/5] Add frame pointer unwinding for aarch64

2017-04-26 Thread Ulf Hermann
On 04/26/2017 04:33 PM, Mark Wielaard wrote:
> On Tue, 2017-04-25 at 15:38 +0200, Ulf Hermann wrote:
>>> My question is about this "initial frame". In our testcase we don't have
>>> this case since the backtrace starts in a function that has some CFI.
>>> But I assume you have some tests that rely on this behavior.
>>
>> Actually the test I provided does exercise this code. The initial
>> __libc_do_syscall() frame does not have CFI. Only raise() has. You can
>> check that by dropping the code for pc & 0x1.
> 
> Maybe I am using the wrong binaries (exec and core), but for me there is
> no difference.

In fact, with the new binaries there is no difference. I was confused, sorry.

However, if you strip .eh_frame and .eh_frame_hdr from the exe (thus triggering 
the fp unwinding on the first frame), you will see that it skips sigusr2. At 
the same time it invents another frame 0x403f40 on the main thread. Apparently 
pthread_join creates two stack frames. As it correctly unwinds the rest, the 
latter seemed harmless to me.

With .eh_frame and .eh_frame_hdr:

ulf@zebra:~/dev/build-elfutils/tests$ ./backtrace 
--core=backtrace.aarch64.fp.core -e backtrace.aarch64.fp.exec
0x400x4a3000/home/ulf/backtrace.aarch64.fp.exec
0x7fb6380x7fb6381000linux-vdso.so.1
TID 350:
# 0 0x40583craise
# 1 0x401aac - 1sigusr2
# 2 0x401ba8 - 1stdarg
# 3 0x401c04 - 1backtracegen
# 4 0x401c10 - 1start
# 5 0x402f44 - 1start_thread
# 6 0x41dc70 - 1__clone
TID 349:
# 0 0x403fccpthread_join
# 1 0x401810 - 1main
# 2 0x406544 - 1__libc_start_main
# 3 0x401918 - 1$x
./backtrace: dwfl_thread_getframes: address out of range

Without .eh_frame and .eh_frame_hdr, code from PATCH V2:

ulf@zebra:~/dev/build-elfutils/tests$ ./backtrace 
--core=backtrace.aarch64.fp.core -e backtrace.aarch64.fp.stripped 
0x400x4a3000/home/ulf/backtrace.aarch64.fp.exec
0x7fb6380x7fb6381000linux-vdso.so.1
TID 350:
# 0 0x40583c(null)
# 1 0x401aac - 1(null)
# 2 0x401ba8 - 1(null)
# 3 0x401c04 - 1(null)
# 4 0x401c10 - 1(null)
# 5 0x402f44 - 1(null)
# 6 0x41dc70 - 1(null)
./backtrace: dwfl_thread_getframes: address out of range
TID 349:
# 0 0x403fcc(null)
# 1 0x403f40 - 1(null)
# 2 0x401810 - 1(null)
# 3 0x406544 - 1(null)
# 4 0x401918 - 1(null)
./backtrace: dwfl_thread_getframes: address out of range

Without .eh_frame and .eh_frame_hdr, without initial frame adjustment:

ulf@zebra:~/dev/build-elfutils/tests$ ./backtrace 
--core=backtrace.aarch64.fp.core -e backtrace.aarch64.fp.stripped 
0x400x4a3000/home/ulf/backtrace.aarch64.fp.exec
0x7fb6380x7fb6381000linux-vdso.so.1
TID 350:
# 0 0x40583c(null)
# 1 0x401ba8 - 1(null)
# 2 0x401c04 - 1(null)
# 3 0x401c10 - 1(null)
# 4 0x402f44 - 1(null)
# 5 0x41dc70 - 1(null)
./backtrace: dwfl_thread_getframes: address out of range
TID 349:
# 0 0x403fcc(null)
# 1 0x401810 - 1(null)
# 2 0x406544 - 1(null)
# 3 0x401918 - 1(null)
./backtrace: dwfl_thread_getframes: address out of range

You have to drop all the asserts from backtrace.c to actually test this:

diff --git a/tests/backtrace.c b/tests/backtrace.c
index 1ff6353..a910a77 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -71,14 +71,14 @@ static void
 callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
 const char *symname, Dwfl *dwfl)
 {
-  static bool seen_main = false;
+//  static bool seen_main = false;
   if (symname && *symname == '.')
 symname++;
-  if (symname && strcmp (symname, "main") == 0)
-seen_main = true;
+//  if (symname && strcmp (symname, "main") == 0)
+//seen_main = true;
   if (pc == 0)
 {
-  assert (seen_main);
+//  assert (seen_main);
   return;
 }
   if (check_tid == 0)
@@ -103,11 +103,11 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr 
pc,
   && (strcmp (symname, "__kernel_vsyscall") == 0
   || strcmp (symname, "__libc_do_syscall") == 0))
reduce_frameno = true;
-  else
-   assert (symname && strcmp (symname, "raise") == 0);
+//  else
+// assert (symname && strcmp (symname, "raise") == 0);
   break;
 case 1:
-  assert (symname != NULL && strcmp (symname, "sigusr2") == 0);
+//  assert (symname != NULL && strcmp (symname, "sigusr2") == 0);
   break;
 case 2: // x86_64 only
   /* __restore_rt - glibc maybe does not have to have this symbol.  */
@@ -125,11 +125,11 @@ callback_verify (pid_t tid, unsigned frameno, Dwa

Re: frame unwinding patches

2017-04-26 Thread Ulf Hermann
> I dropped the arm32 frame pointer unwinder for now (maybe we need a less
> demanding testcase for that or, more awesome, add code to translate the
> exidx section for that).

Another problem is that QV4-generated code on a new frame pushes LR first and 
then FP. Code generated by gcc with "-arm -mapcs-frame -fno-omit-frame-pointer" 
pushes FP first and then LR. The libc raise() I have here miraculously does the 
same as QV4. Also, QV4 can alternatively use either r11 or r7 for LR, depending 
on if we're in ARM or THUMB mode (which I cannot detect in the unwind hook). As 
that is written somewhere in AAPCS, I guess you can coax gcc to do the same 
thing (but just leaving out the "-arm" above simply leads to no frame pointers 
at all).

Well, let's forget about this for now. I'll keep something that works with QV4 
in ARM mode and ignore everything else.

Ulf


Re: [PATCH 4/5] Add i386 frame pointer unwinder.

2017-04-25 Thread Ulf Hermann
On 04/25/2017 02:49 PM, Mark Wielaard wrote:
> Add a simple i386_unwind.c frame pointer unwinder as fallback if DWARF/CFI
> unwinding fails.

Looks good to me. The logic could be relaxed a bit so that failure to e.g. 
write the new value for sp would not be fatal. Then we might be able to unwind 
even more frames. But refusing to unwind obviously broken frames is acceptable, 
too.

Ulf


Re: [PATCH 2/5] tests: Add core backtracegen chec and regenerate ppc32 backtrace test files.

2017-04-25 Thread Ulf Hermann
On 04/25/2017 02:49 PM, Mark Wielaard wrote:
> Add a check to check_core to make sure the backtracegen function is
> found in the backtrace. This function is in the middle of the backtrace
> in the main executable and if not found it means the backtrace was
> incomplete or the frame was skipped (which could happen on a bad frame
> pointer only unwind).
> 
> This showed that the ppc32 backtrace test files were missing DWARF CFI
> for the main executable. Regenerated them to include full CFI.

Looks good to me.

Ulf


Re: [PATCH v2] Add frame pointer unwinding for aarch64

2017-04-25 Thread Ulf Hermann
On 04/24/2017 04:53 PM, Mark Wielaard wrote:
> I got these separately. I assume they are as in the email you sent on
> Mon, 10 Apr 2017 14:48:06 +0200 (which didn't hit the list because it
> had the binaries attached...)

Yes. Those are the right binaries.

> This description doesn't seem to match anymore. Should this be:
> 
> # The binary is generated by compiling with eh_frame CFI, but with frame
> # pointers.
> #
> # gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
> # -D_GNU_SOURCE -pthread -o tests/backtrace.x86_64.fp.exec -I. -Ilib \
> # tests/backtrace-child.c

Almost right. It's backtrace.aarch64.fp.exec.

Thanks for taking care of this,
Ulf


[PATCH] Add missing entries to .gitignore

2017-04-21 Thread Ulf Hermann
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 .gitignore | 2 ++
 ChangeLog  | 4 
 2 files changed, 6 insertions(+)

diff --git a/.gitignore b/.gitignore
index 0ee3af7..43a8d6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,7 @@ Makefile.in
 /tests/elfstrmerge
 /tests/elfstrtab
 /tests/emptyfile
+/tests/fillfile
 /tests/find-prologues
 /tests/funcretval
 /tests/funcscopes
@@ -139,6 +140,7 @@ Makefile.in
 /tests/newdata
 /tests/newfile
 /tests/newscn
+/tests/peel_type
 /tests/rdwrmmap
 /tests/rerequest_tag
 /tests/saridx
diff --git a/ChangeLog b/ChangeLog
index 48185c3..735a335 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-21  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * .gitignore: Add fillfile and peel_type tests.
+
 2017-02-15  Ulf Hermann  <ulf.herm...@qt.io>
 
* configure.ac: Add check for mempcpy.
-- 
2.1.4



porting to windows

2017-04-20 Thread Ulf Hermann
I have a total of 85 patches to port elfutils to windows. I will post them all 
here, once I get around to write all the ChangeLog entries, but I'm fairly sure 
you won't like all of them. You can see them all (and also comment if you like) 
on the qt code review system.

See 
https://codereview.qt-project.org/#/q/status:open+project:qt-creator/elfutils+branch:master,n,z
 .

I might push some of them into my elfutils fork, though. Then they're not 
"open" anymore.

br,
Ulf


[PATCH] Add EXEEXT to gendis

2017-04-20 Thread Ulf Hermann
Otherwise the build will fail on systems that actually need file
extension for executables.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libcpu/ChangeLog   | 4 
 libcpu/Makefile.am | 6 +++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index e59e876..7fe4345 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * Makefile.am: Add EXEEXT to gendis.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* i386_parse.y: Eliminate comparison_fn_t.
 
 2016-11-02  Mark Wielaard  <m...@redhat.com>
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index b98b583..31fc906 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -58,10 +58,10 @@ endif
 if MAINTAINER_MODE
 noinst_HEADERS = memory-access.h i386_parse.h i386_data.h
 
-noinst_PROGRAMS = i386_gendis
+noinst_PROGRAMS = i386_gendis$(EXEEXT)
 
-$(srcdir)/%_dis.h: %_defs i386_gendis
-   $(AM_V_GEN)./i386_gendis $< > $@T
+$(srcdir)/%_dis.h: %_defs i386_gendis$(EXEEXT)
+   $(AM_V_GEN)./i386_gendis$(EXEEXT) $< > $@T
$(AM_V_at)mv -f $@T $@
 
 else
-- 
2.1.4



[PATCH] On elf_update, remember when we mmap()

2017-04-20 Thread Ulf Hermann
Otherwise we skip the munmap() later. This leaks resources.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libelf/ChangeLog| 4 
 libelf/elf_update.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index fa768f8..225c7c8 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * elf_update.c: Set ELF_F_MMAPPED flag if we mmap from elf_update.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* libelfP.h: Don't include config.h.
 
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index c635eb3..8ce0782 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -74,6 +74,8 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
   MAP_SHARED, elf->fildes, 0);
   if (unlikely (elf->map_address == MAP_FAILED))
elf->map_address = NULL;
+  else
+   elf->flags |= ELF_F_MMAPPED;
 }
 
   if (elf->map_address != NULL)
-- 
2.1.4



[PATCH] Make elf section sorting more deterministic

2017-04-20 Thread Ulf Hermann
At least one test (dwfl-addr-sect) depends on the order of elf sections
with equal addresses. This is not guaranteed by the code. Compare also
by end address and name to tell entries apart.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdwfl/ChangeLog   |  5 +
 libdwfl/derelocate.c| 17 +++--
 tests/ChangeLog |  6 ++
 tests/run-dwfl-addr-sect.sh |  2 +-
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index f605f46..a1ed675 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * derelocate.c (compare_secrefs): Compare by end address and then by
+   name if start addresses are equal.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* elf-from-memory.c: Explicitly cast phnum to size_t.
 
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c
index e5c3e12..8d965af 100644
--- a/libdwfl/derelocate.c
+++ b/libdwfl/derelocate.c
@@ -57,17 +57,22 @@ struct secref
 static int
 compare_secrefs (const void *a, const void *b)
 {
-  struct secref *const *p1 = a;
-  struct secref *const *p2 = b;
+  struct secref const *p1 = *(struct secref *const *)a;
+  struct secref const *p2 = *(struct secref *const *)b;
 
   /* No signed difference calculation is correct here, since the
  terms are unsigned and could be more than INT64_MAX apart.  */
-  if ((*p1)->start < (*p2)->start)
+  if (p1->start < p2->start)
 return -1;
-  if ((*p1)->start > (*p2)->start)
+  if (p1->start > p2->start)
 return 1;
-
-  return 0;
+  if (p1->end < p2->end)
+return -1;
+  if (p1->end > p2->end)
+return 1;
+  if (p1->name == NULL)
+return p2->name == NULL ? 0 : -1;
+  return p2->name == NULL ? 1 : strcmp(p1->name, p2->name);
 }
 
 static int
diff --git a/tests/ChangeLog b/tests/ChangeLog
index c4e76d1..4da049b 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
 
+   * run-dwfl-addr-sect.sh: Expect section with alphabetically smaller
+   name when requesting the start address of two otherwise equal
+   zero-sized sections.
+
+2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
+
* run-readelf-dwz-multi.sh: Expect readelf to output "yes" for flags
that are set.
* run-readelf-zdebug-rel.sh: Likewise.
diff --git a/tests/run-dwfl-addr-sect.sh b/tests/run-dwfl-addr-sect.sh
index 80da008..e257bfc 100755
--- a/tests/run-dwfl-addr-sect.sh
+++ b/tests/run-dwfl-addr-sect.sh
@@ -20,7 +20,7 @@
 testfiles testfile43 testfile50
 
 testrun_compare ${abs_builddir}/dwfl-addr-sect -e testfile43 0x64 0x8 0x98 
<<\EOF
-address 0x64 => module "" section 4 + 0
+address 0x64 => module "" section 3 + 0
 address 0x8 => module "" section 1 + 0x8
 address 0x98 => module "" section 7 + 0
 EOF
-- 
2.1.4



[PATCH] Avoid signed/unsigned comparison

2017-04-20 Thread Ulf Hermann
Some compilers implicitly cast the result of uint_fast16_t *
uint_fast16_t to something signed and then complain about the
comparison to (unsigned) size_t.

Casting phnum to size_t is a good idea anyway as 16bit multiplication
can easily overflow and we are not checking for this.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdwfl/ChangeLog | 4 
 libdwfl/elf-from-memory.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index cddafe2..c9bd4f0 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * elf-from-memory.c: Explicitly cast phnum to size_t.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* libdwflP.h: Don't include config.h.
* argp-std.c: Include config.h.
* cu.c: Likewise.
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index dd42e95..12a0a1b 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -172,7 +172,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
 {
   /* Read in the program headers.  */
 
-  if (initial_bufsize < phnum * phentsize)
+  if (initial_bufsize < (size_t)phnum * phentsize)
{
  unsigned char *newbuf = realloc (buffer, phnum * phentsize);
  if (newbuf == NULL)
-- 
2.1.4



[PATCH] Include strings.h to make ffs available

2017-04-20 Thread Ulf Hermann
We cannot rely on it to be available from any of the other headers.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog | 4 
 src/readelf.c | 1 +
 2 files changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 1521d80..cbb77fc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * readelf.c: Include strings.h.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* unstrip.c: Check shnum for 0 before subtracting from it.
 
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
diff --git a/src/readelf.c b/src/readelf.c
index 6f6095d..40d4913 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.1.4



[PATCH] Avoid double-including config.h

2017-04-20 Thread Ulf Hermann
config.h doesn't have include guards, so including it twice is bad. We
deal with this by checking for PACKAGE_NAME, but only in some places.
Once we start using gnulib, we will need to include config.h before any
gnulib-generated headers. This is problematic if we include it
transitively through our own private headers.

In order to set a clear rule about inclusion of config.h, it is now
included in every .c file as first header, but not in any header. This
will definitely avoid double-inclusion and satisfy the condition that it
has to be included before gnulib headers. It comes at the price of
adding some redundancy, but there is no clean way to avoid this.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 lib/ChangeLog   |  5 +++
 lib/crc32.c |  4 ++
 lib/system.h|  4 --
 libdwfl/ChangeLog   | 58 +
 libdwfl/argp-std.c  |  4 ++
 libdwfl/cu.c|  4 ++
 libdwfl/derelocate.c|  4 ++
 libdwfl/dwfl_addrdie.c  |  4 ++
 libdwfl/dwfl_addrdwarf.c|  4 ++
 libdwfl/dwfl_addrmodule.c   |  4 ++
 libdwfl/dwfl_begin.c|  4 ++
 libdwfl/dwfl_build_id_find_debuginfo.c  |  4 ++
 libdwfl/dwfl_build_id_find_elf.c|  4 ++
 libdwfl/dwfl_cumodule.c |  4 ++
 libdwfl/dwfl_dwarf_line.c   |  4 ++
 libdwfl/dwfl_end.c  |  4 ++
 libdwfl/dwfl_frame.c|  4 ++
 libdwfl/dwfl_frame_regs.c   |  4 ++
 libdwfl/dwfl_getdwarf.c |  4 ++
 libdwfl/dwfl_getmodules.c   |  4 ++
 libdwfl/dwfl_getsrc.c   |  4 ++
 libdwfl/dwfl_getsrclines.c  |  4 ++
 libdwfl/dwfl_line_comp_dir.c|  4 ++
 libdwfl/dwfl_linecu.c   |  4 ++
 libdwfl/dwfl_lineinfo.c |  4 ++
 libdwfl/dwfl_linemodule.c   |  4 ++
 libdwfl/dwfl_module.c   |  4 ++
 libdwfl/dwfl_module_addrdie.c   |  4 ++
 libdwfl/dwfl_module_addrname.c  |  4 ++
 libdwfl/dwfl_module_addrsym.c   |  4 ++
 libdwfl/dwfl_module_build_id.c  |  4 ++
 libdwfl/dwfl_module_dwarf_cfi.c |  4 ++
 libdwfl/dwfl_module_eh_cfi.c|  4 ++
 libdwfl/dwfl_module_getdwarf.c  |  4 ++
 libdwfl/dwfl_module_getelf.c|  4 ++
 libdwfl/dwfl_module_getsrc.c|  4 ++
 libdwfl/dwfl_module_getsrc_file.c   |  4 ++
 libdwfl/dwfl_module_getsym.c|  4 ++
 libdwfl/dwfl_module_info.c  |  4 ++
 libdwfl/dwfl_module_nextcu.c|  4 ++
 libdwfl/dwfl_module_register_names.c|  4 ++
 libdwfl/dwfl_module_report_build_id.c   |  4 ++
 libdwfl/dwfl_module_return_value_location.c |  4 ++
 libdwfl/dwfl_nextcu.c   |  4 ++
 libdwfl/dwfl_onesrcline.c   |  4 ++
 libdwfl/dwfl_report_elf.c   |  4 ++
 libdwfl/dwfl_validate_address.c |  4 ++
 libdwfl/dwfl_version.c  |  4 ++
 libdwfl/find-debuginfo.c|  4 ++
 libdwfl/gzip.c  |  4 ++
 libdwfl/image-header.c  |  4 ++
 libdwfl/libdwflP.h  |  3 --
 libdwfl/lines.c |  4 ++
 libdwfl/linux-core-attach.c |  4 ++
 libdwfl/linux-pid-attach.c  |  4 ++
 libdwfl/linux-proc-maps.c   |  4 ++
 libdwfl/offline.c   |  4 ++
 libdwfl/open.c  |  4 ++
 libdwfl/relocate.c  |  4 ++
 libdwfl/segment.c   |  4 ++
 libelf/ChangeLog|  4 ++
 libelf/libelfP.h|  4 --
 62 files changed, 291 insertions(+), 11 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 84290f7..8cac7af 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * crc32.c: include config.h.
+   * system.h: Don't include config.h.
+
 2017-02-16  Ulf Hermann  <ulf.herm...@qt.io>
 
* Makefile.am (libeu_a_SOURCES): Remove version.c, add printversion.c
diff --git a/lib/crc32.c b/lib/crc32.c
index 1a76b1b..758602e 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -25,6 +25,10 @@
the GNU Lesser General Public License along with this program.  If
not, see <http://www.gnu.org/licenses/>.  */
 
+#if HAVE_CONFIG_H
+#include 
+#endif
+
 #include 
 #include "system.h"
 
diff --git a/lib/system.h b/lib/system.h
index 2d05702..9203335 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -29,10 +29,6 @@
 #ifndef LIB_SYSTEM_H
 #define LIB_SY

[PATCH] Protect against integer overflow on shnum

2017-04-20 Thread Ulf Hermann
If shnum is 0, the many "shnum - 1" would result in an overflow. Check it
for 0, and only subtract once, rather than on every usage.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdwfl/ChangeLog  |  5 +
 libdwfl/dwfl_module_getdwarf.c | 18 ++
 src/ChangeLog  |  4 
 src/unstrip.c  | 25 ++---
 4 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 0a572ad..de73d79 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * dwfl_module_getdwarf.c: Check shnum for 0 before subtracting from
+   it.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* libdwfl.h: Use __const_attribute__.
 
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 46caece..c8b839d 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -349,12 +349,14 @@ find_prelink_address_sync (Dwfl_Module *mod, struct 
dwfl_file *file)
 
   /* Since prelink does not store the zeroth section header in the undo
  section, it cannot support SHN_XINDEX encoding.  */
-  if (unlikely (shnum >= SHN_LORESERVE)
+  if (unlikely (shnum >= SHN_LORESERVE) || unlikely(shnum == 0)
   || unlikely (undodata->d_size != (src.d_size
+ phnum * phentsize
+ (shnum - 1) * shentsize)))
 return DWFL_E_BAD_PRELINK;
 
+  --shnum;
+
   /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections.  (Most
  every file will have some SHT_PROGBITS sections, but it's possible to
  have one with nothing but .bss, i.e. SHT_NOBITS.)  The special sections
@@ -431,12 +433,12 @@ find_prelink_address_sync (Dwfl_Module *mod, struct 
dwfl_file *file)
 
   src.d_buf += src.d_size;
   src.d_type = ELF_T_SHDR;
-  src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
+  src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum, EV_CURRENT);
 
   size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
-  if (unlikely (shnum - 1  > SIZE_MAX / shdr_size))
+  if (unlikely (shnum > SIZE_MAX / shdr_size))
 return DWFL_E_NOMEM;
-  const size_t shdrs_bytes = (shnum - 1) * shdr_size;
+  const size_t shdrs_bytes = shnum * shdr_size;
   void *shdrs = malloc (shdrs_bytes);
   if (unlikely (shdrs == NULL))
 return DWFL_E_NOMEM;
@@ -488,16 +490,16 @@ find_prelink_address_sync (Dwfl_Module *mod, struct 
dwfl_file *file)
   highest = 0;
   if (class32)
{
- Elf32_Shdr (*s32)[shnum - 1] = shdrs;
- for (size_t i = 0; i < shnum - 1; ++i)
+ Elf32_Shdr (*s32)[shnum] = shdrs;
+ for (size_t i = 0; i < shnum; ++i)
consider_shdr (undo_interp, (*s32)[i].sh_type,
   (*s32)[i].sh_flags, (*s32)[i].sh_addr,
   (*s32)[i].sh_size, );
}
   else
{
- Elf64_Shdr (*s64)[shnum - 1] = shdrs;
- for (size_t i = 0; i < shnum - 1; ++i)
+ Elf64_Shdr (*s64)[shnum] = shdrs;
+ for (size_t i = 0; i < shnum; ++i)
consider_shdr (undo_interp, (*s64)[i].sh_type,
   (*s64)[i].sh_flags, (*s64)[i].sh_addr,
   (*s64)[i].sh_size, );
diff --git a/src/ChangeLog b/src/ChangeLog
index e0a591e..1521d80 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * unstrip.c: Check shnum for 0 before subtracting from it.
+
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
 
* readelf.c: Replace YESSTR and NOSTR with gettext ("yes") and
diff --git a/src/unstrip.c b/src/unstrip.c
index 6e57a6b..5074909 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1027,21 +1027,24 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data 
*debug_shstrtab,
  shnum = ehdr.e64.e_shnum;
}
 
+  bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+  size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
+  if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
+   error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
+  (size_t) shnum, ".gnu.prelink_undo");
+
+  --shnum;
+
   size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT);
   src.d_buf += src.d_size + phsize;
-  src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum - 1, EV_CURRENT);
+  src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum, EV_CURRENT);
   src.d_type = ELF_T_SHDR;
   if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
  || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
error

[PATCH] Use F_GETFD rather than F_GETFL to check validity of file descriptor

2017-04-20 Thread Ulf Hermann
F_GETFD is both cheaper and easier to port, and otherwise has the same
effect here.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libelf/ChangeLog   | 4 
 libelf/elf_begin.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 23cd942..e32590a 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,9 @@
 2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * elf_begin.c: Use F_GETFD rather than F_GETFL.
+
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
* libelf.h: Define macros for various function attributes and use
them.
 
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 5e9099c..6f85038 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -1075,7 +1075,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
   if (ref != NULL)
 /* Make sure the descriptor is not suddenly going away.  */
 rwlock_rdlock (ref->lock);
-  else if (unlikely (fcntl (fildes, F_GETFL) == -1 && errno == EBADF))
+  else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
 {
   /* We cannot do anything productive without a file descriptor.  */
   __libelf_seterrno (ELF_E_INVALID_FILE);
-- 
2.1.4



[PATCH] Make __attribute__ conditional in all installed headers

2017-04-20 Thread Ulf Hermann
__attribute__ is a GNU extension. If we want to link against the
libraries using a different compiler, it needs to be disabled. It was
already disabled in libdw.h, and this patch extends this to the other
headers. We move the defines to libelf.h as that is included in all
the others.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 libdw/ChangeLog   |  5 +
 libdw/libdw.h | 23 +--
 libdwfl/ChangeLog |  4 
 libdwfl/libdwfl.h |  2 +-
 libebl/ChangeLog  |  4 
 libebl/libebl.h   |  6 +++---
 libelf/ChangeLog  |  5 +
 libelf/libelf.h   | 38 +++---
 8 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 3f63a17..c9ae664 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * libdw.h: Remove attribute macro declarations and use
+   __noreturn_attribute__ as defined in libelf.h.
+
 2017-03-30  Mark Wielaard  <m...@redhat.com>
 
* dwarf_peel_type.c (dwarf_peel_type): Call dwarf_attr_integrate on
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 473e1a2..9ae80eb 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -34,23 +34,6 @@
 #include 
 #include 
 
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
-# define __deprecated_attribute__ __attribute__ ((__deprecated__))
-#else
-# define __nonnull_attribute__(args...)
-# define __deprecated_attribute__
-#endif
-
-
-#ifdef __GNUC_STDC_INLINE__
-# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__))
-#else
-# define __libdw_extern_inline extern __inline
-#endif
-
-
 /* Mode for the session.  */
 typedef enum
   {
@@ -242,11 +225,7 @@ typedef struct Dwarf Dwarf;
 
 
 /* Out-Of-Memory handler.  */
-#if __GNUC__ < 4
-typedef void (*Dwarf_OOM) (void);
-#else
-typedef void (*__attribute__ ((noreturn)) Dwarf_OOM) (void);
-#endif
+typedef void (*__noreturn_attribute__ Dwarf_OOM) (void);
 
 
 #ifdef __cplusplus
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 705b93d..0a572ad 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * libdwfl.h: Use __const_attribute__.
+
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
 
* dwfl_frame.c: Drop unused sys/ptrace.h include.
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index aea8b99..a0c1d35 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -385,7 +385,7 @@ extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void 
**userdata,
 
 /* Standard argument parsing for using a standard callback set.  */
 struct argp;
-extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const));
+extern const struct argp *dwfl_standard_argp (void) __const_attribute__;
 
 
 /*** Relocation of addresses from Dwfl ***/
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 719d08d..506915b 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * libebl.h: Use __pure_attribute__.
+
 2017-02-15  Ulf Hermann  <ulf.herm...@qt.io>
 
* eblmachineflagname.c: Include system.h.
diff --git a/libebl/libebl.h b/libebl/libebl.h
index c8e01fe..87896e4 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -73,13 +73,13 @@ extern void ebl_closebackend (Ebl *bh);
 /* Information about the descriptor.  */
 
 /* Get ELF machine.  */
-extern int ebl_get_elfmachine (Ebl *ebl) __attribute__ ((__pure__));
+extern int ebl_get_elfmachine (Ebl *ebl) __pure_attribute__;
 
 /* Get ELF class.  */
-extern int ebl_get_elfclass (Ebl *ebl) __attribute__ ((__pure__));
+extern int ebl_get_elfclass (Ebl *ebl) __pure_attribute__;
 
 /* Get ELF data encoding.  */
-extern int ebl_get_elfdata (Ebl *ebl) __attribute__ ((__pure__));
+extern int ebl_get_elfdata (Ebl *ebl) __pure_attribute__;
 
 
 /* Function to call the callback functions including default ELF
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 23a4fb9..23cd942 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-20  Ulf Hermann  <ulf.herm...@qt.io>
+
+   * libelf.h: Define macros for various function attributes and use
+   them.
+
 2017-03-27  Mark Wielaard  <m...@klomp.org>
 
* elf32_updatefile.c (updatemmap): Always update last_positition.
diff --git a/libelf/libelf.h b/libelf/libelf.h
index c0d6389..547c0f5 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -64,6 +64,30 @@
  #define ELFCOMPRESS_HIPROC 0x7fff /* End of processor-specific.  */
 #endif
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
+# define __deprecated_attribute__ __attribute__ ((__deprecated__))
+# define __pure_attribute__ __attr

[PATCH] Avoid YESSTR and NOSTR

2017-04-20 Thread Ulf Hermann
Those are deprecated and apparently some implementations of nl_langinfo
return empty strings for them. The tests even tested for those empty
strings even though the intention of the code was clearly to output
"yes" or "no" there.

Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 src/ChangeLog   |  5 +
 src/readelf.c   |  6 +++---
 tests/ChangeLog |  6 ++
 tests/run-readelf-dwz-multi.sh  | 30 +++---
 tests/run-readelf-zdebug-rel.sh |  6 +++---
 5 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index a1bec19..e0a591e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
+
+   * readelf.c: Replace YESSTR and NOSTR with gettext ("yes") and
+   gettext ("no"), respectively.
+
 2017-04-05  Mark Wielaard  <m...@klomp.org>
 
* elflint.c (check_elf_header): Decompress all sections.
diff --git a/src/readelf.c b/src/readelf.c
index 97a43b0..6f6095d 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6132,7 +6132,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 
   printf ("   %*s%-20s (%s) %s\n",
  (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
+ dwarf_form_name (form), flag ? gettext ("yes") : gettext ("no"));
   break;
 
 case DW_FORM_flag_present:
@@ -6140,7 +6140,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
break;
   printf ("   %*s%-20s (%s) %s\n",
  (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), nl_langinfo (YESSTR));
+ dwarf_form_name (form), gettext ("yes"));
   break;
 
 case DW_FORM_exprloc:
@@ -7650,7 +7650,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod 
__attribute__ ((unused)),
  if (readp + 1 > readendp)
goto invalid_data;
  val = *readp++;
- printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
+ printf (" %s", val != 0 ? gettext ("yes") : gettext 
("no"));
  break;
 
case DW_FORM_string:
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ebcd7bc..c4e76d1 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
 
+   * run-readelf-dwz-multi.sh: Expect readelf to output "yes" for flags
+   that are set.
+   * run-readelf-zdebug-rel.sh: Likewise.
+
+2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
+
* backtrace-child.c: Include sys/ptrace.h only on linux.
* backtrace-dwarf.c: Likewise.
 
diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh
index 27e0f38..23ca944 100755
--- a/tests/run-readelf-dwz-multi.sh
+++ b/tests/run-readelf-dwz-multi.sh
@@ -98,17 +98,17 @@ DWARF section [28] '.debug_info' at offset 0x1078:
  byte_size(data1) 8
  type (GNU_ref_alt) [53]
  [31]subprogram
- external (flag_present) 
+ external (flag_present) yes
  name (strp) "main"
  decl_file(data1) 1
  decl_line(data1) 3
- prototyped   (flag_present) 
+ prototyped   (flag_present) yes
  type (GNU_ref_alt) [3e]
  low_pc   (addr) 0x004006ac 
  high_pc  (udata) 44 (0x004006d8)
  frame_base   (exprloc) 
   [   0] call_frame_cfa
- GNU_all_tail_call_sites (flag_present) 
+ GNU_all_tail_call_sites (flag_present) yes
  sibling  (ref_udata) [6e]
  [48]  formal_parameter
name (strp) "argc"
@@ -159,17 +159,17 @@ DWARF section [28] '.debug_info' at offset 0x1078:
  byte_size(data1) 8
  type (GNU_ref_alt) [53]
  [31]subprogram
- external (flag_present) 
+ external (flag_present) yes
  name (strp) "main"
  decl_file(data1) 1
  decl_line(data1) 3
- prototyped   (flag_present) 
+ prototyped   (flag_present) yes
  type (GNU_ref_alt) [3e]
  low_pc   (addr) 0x004006ac 
  high_pc  (udata) 44 (0x00

[PATCH] Clean up linux-specific system includes

2017-04-20 Thread Ulf Hermann
We only include them where we actually need them and only on linux.

Change-Id: Ic3065ffab67ba1177f63204fb91a92c5f4336dbb
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 backends/ChangeLog | 8 
 backends/aarch64_initreg.c | 4 ++--
 backends/arm_initreg.c | 4 +++-
 backends/ppc_initreg.c | 4 ++--
 backends/s390_initreg.c| 4 ++--
 backends/x86_64_initreg.c  | 2 +-
 libdwfl/ChangeLog  | 7 +++
 libdwfl/dwfl_frame.c   | 1 -
 libdwfl/frame_unwind.c | 1 -
 libdwfl/linux-pid-attach.c | 5 +++--
 tests/ChangeLog| 5 +
 tests/backtrace-child.c| 2 +-
 tests/backtrace-dwarf.c| 2 +-
 13 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/backends/ChangeLog b/backends/ChangeLog
index 39390cb..c6e0e08 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,11 @@
+2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
+
+   * aarch64_initreg.c: Compile register initialization only on linux.
+   * arm_initreg.c: Likewise.
+   * ppc_initreg.c: Likewise.
+   * s390_initreg.c: Likewise.
+   * x86_64_initreg.c: Likewise.
+
 2017-02-15  Mark Wielaard  <m...@klomp.org>
 
* ppc64_init.c (ppc64_init): Add check_object_attribute HOOK.
diff --git a/backends/aarch64_initreg.c b/backends/aarch64_initreg.c
index 9706205..daf6f37 100644
--- a/backends/aarch64_initreg.c
+++ b/backends/aarch64_initreg.c
@@ -32,7 +32,7 @@
 
 #include "system.h"
 #include 
-#ifdef __aarch64__
+#if defined(__aarch64__) && defined(__linux__)
 # include 
 # include 
 # include 
@@ -51,7 +51,7 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ 
((unused)),
  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
void *arg __attribute__ ((unused)))
 {
-#ifndef __aarch64__
+#if !defined(__aarch64__) || !defined(__linux__)
   return false;
 #else /* __aarch64__ */
 
diff --git a/backends/arm_initreg.c b/backends/arm_initreg.c
index a0a9be9..efcabaf 100644
--- a/backends/arm_initreg.c
+++ b/backends/arm_initreg.c
@@ -30,6 +30,7 @@
 # include 
 #endif
 
+#ifdef __linux__
 #if defined __arm__
 # include 
 # include 
@@ -45,6 +46,7 @@
 #  define user_regs_struct user_pt_regs
 # endif
 #endif
+#endif
 
 #define BACKEND arm_
 #include "libebl_CPU.h"
@@ -54,7 +56,7 @@ arm_set_initial_registers_tid (pid_t tid __attribute__ 
((unused)),
  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
   void *arg __attribute__ ((unused)))
 {
-#if !defined __arm__ && !defined __aarch64__
+#if !defined(__linux__) || (!defined __arm__ && !defined __aarch64__)
   return false;
 #else  /* __arm__ || __aarch64__ */
 #if defined __arm__
diff --git a/backends/ppc_initreg.c b/backends/ppc_initreg.c
index 64f5379..69d623b 100644
--- a/backends/ppc_initreg.c
+++ b/backends/ppc_initreg.c
@@ -32,7 +32,7 @@
 
 #include "system.h"
 #include 
-#ifdef __powerpc__
+#if defined(__powerpc__) && defined(__linux__)
 # include 
 # include 
 #endif
@@ -70,7 +70,7 @@ ppc_set_initial_registers_tid (pid_t tid __attribute__ 
((unused)),
  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
   void *arg __attribute__ ((unused)))
 {
-#ifndef __powerpc__
+#if !defined(__powerpc__) || !defined(__linux__)
   return false;
 #else /* __powerpc__ */
   union
diff --git a/backends/s390_initreg.c b/backends/s390_initreg.c
index b4c4b67..011305c 100644
--- a/backends/s390_initreg.c
+++ b/backends/s390_initreg.c
@@ -32,7 +32,7 @@
 
 #include "system.h"
 #include 
-#ifdef __s390__
+#if defined(__s390__) && defined(__linux__)
 # include 
 # include 
 # include 
@@ -46,7 +46,7 @@ s390_set_initial_registers_tid (pid_t tid __attribute__ 
((unused)),
  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
void *arg __attribute__ ((unused)))
 {
-#ifndef __s390__
+#if !defined(__s390__) || !defined(__linux__)
   return false;
 #else /* __s390__ */
   struct user user_regs;
diff --git a/backends/x86_64_initreg.c b/backends/x86_64_initreg.c
index db9216e..50e9002 100644
--- a/backends/x86_64_initreg.c
+++ b/backends/x86_64_initreg.c
@@ -31,7 +31,7 @@
 #endif
 
 #include 
-#ifdef __x86_64__
+#if defined(__x86_64__) && defined(__linux__)
 # include 
 # include 
 #endif
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 1ed9dd4..705b93d 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,12 @@
 2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
 
+   * dwfl_frame.c: Drop unused sys/ptrace.h include.
+   * frame_unwind.c: Likewise.
+   * linux-pid-attach.c: Include sys/ptrace.h and sys/syscall.h only on
+   linux.
+
+2017-04-20  Ulf Hermann <ulf.herm...@qt.io>
+
* linux-kernel-modules.c: Include sys/types.h before fts.h
 
 2017-03-24  

[PATCH v2] Add frame pointer unwinding for aarch64

2017-04-20 Thread Ulf Hermann
If we don't find any debug information for a given frame, we usually
cannot unwind any further. However, the binary in question might have
been compiled with frame pointers, in which case we can look up the
well known frame pointer locations in the stack snapshot and use them
to bridge the frames without debug information.

Change-Id: I3b2285542e368906883579b505e2f45313fede31
Signed-off-by: Ulf Hermann <ulf.herm...@qt.io>
---
 backends/ChangeLog |   6 +++
 backends/Makefile.am   |   2 +-
 backends/aarch64_init.c|   1 +
 backends/aarch64_unwind.c  |  96 +
 tests/ChangeLog|   7 +++
 tests/Makefile.am  |   3 ++
 tests/backtrace.aarch64.fp.core.bz2| Bin 0 -> 7302 bytes
 tests/backtrace.aarch64.fp.exec.bz2| Bin 0 -> 272102 bytes
 tests/run-backtrace-fp-core-aarch64.sh |  33 
 9 files changed, 147 insertions(+), 1 deletion(-)
 create mode 100644 backends/aarch64_unwind.c
 create mode 100644 tests/backtrace.aarch64.fp.core.bz2
 create mode 100755 tests/backtrace.aarch64.fp.exec.bz2
 create mode 100755 tests/run-backtrace-fp-core-aarch64.sh

diff --git a/backends/ChangeLog b/backends/ChangeLog
index eec9923..b8aa1c2 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,5 +1,11 @@
 2017-02-09  Ulf Hermann  <ulf.herm...@qt.io>
 
+   * aarch64_unwind.c: New file
+   * Makefile.am (aarch64_SRCS): Add aarch64_unwind.c
+   * aarch64_init.c (aarch64_init): Hook aarch64_unwind
+
+2017-02-09  Ulf Hermann  <ulf.herm...@qt.io>
+
* x86_64_unwind.c: New file
* Makefile.am (x86_64_SRCS): Add x86_64_unwind.c
* x86_64_init.c (x86_64_init): Hook x86_64_unwind
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 60917b9..8e91bd3 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -80,7 +80,7 @@ am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
 
 aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c  \
   aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \
-  aarch64_initreg.c
+  aarch64_initreg.c aarch64_unwind.c
 libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS)
 am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os)
 
diff --git a/backends/aarch64_init.c b/backends/aarch64_init.c
index 6395f11..0866494 100644
--- a/backends/aarch64_init.c
+++ b/backends/aarch64_init.c
@@ -63,6 +63,7 @@ aarch64_init (Elf *elf __attribute__ ((unused)),
  + ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */
   eh->frame_nregs = 97;
   HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
 
   return MODVERSION;
 }
diff --git a/backends/aarch64_unwind.c b/backends/aarch64_unwind.c
new file mode 100644
index 000..cac4ebd
--- /dev/null
+++ b/backends/aarch64_unwind.c
@@ -0,0 +1,96 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#define BACKEND aarch64_
+#define FP_REG 29
+#define LR_REG 30
+#define SP_REG 31
+#define FP_OFFSET 0
+#define LR_OFFSET 8
+#define SP_OFFSET 16
+
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind 
from that?  */
+
+bool
+EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc 
__attribute__ ((unused)),
+ ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t 
*getfunc,
+ ebl_pid_memory_read_t *readfunc, void *arg,
+ bool *signal_framep __attribute__ ((unused)))
+{
+  Dwarf_Word fp, lr, sp;
+
+  if (!getfunc(LR_REG, 1, , arg))
+return false;
+
+  if (!getfunc(FP_REG, 1, , arg))
+fp = 0;
+
+  if (!getfunc(SP_REG, 1, , arg))
+sp = 0;
+
+  Dwarf_Word newPc, newLr, newFp, newSp;
+
+  // The initial frame is special. We are expected to return lr directly in 
this case, and we'll
+  // come back to the sam

Re: frame unwinding patches

2017-04-20 Thread Ulf Hermann

> That might just mean that the testcase is slightly unrealistic.
> Getting a reliable backtrace through signal handlers when not having
> full CFI is probably not something we can expect to work. That doesn't
> mean having a frame pointer based fallback is a bad thing. We probably
> should find a more realistic testcase. And maybe in the future add an
> interface to allow people to unwind through "pure CFI" or mixed mode
> with frame markers that tell the caller whether the registers can be
> trusted or not.

The x86_64 case already works with the test case I sent. Maybe we can accept 
that one before the others. The aarch64 case almost works, but seems to 
generally duplicate the first entry it unwinds by frame pointer after unwinding 
anything by CFI. That should be fixable. I will research it and post a follow 
up patch. The 32bit arm case is a horrible mess and we may indeed need to lower 
our expectations for that one. Or maybe I can find a raise() that follows the 
same frame conventions as the gcc I'm using ...

br,
Ulf


Re: dwfl_attach_state alternative taking Ebl?

2017-04-11 Thread Ulf Hermann

/* [...] Architecture of DWFL
   modules is specified by ELF, ELF must remain valid during DWFL lifetime.
   Use NULL ELF to detect architecture from DWFL, the function will then detect
   it from arbitrary Dwfl_Module of DWFL.  [...]  */

So would that be an alternative for you? How do you create the Dwfl? Do
you add modules to it (how?) and when do you need to call
dwfl_attach_state?


This is what we do. We parse perf.data. perf.data may contain 
information about file mappings at any point, and it may take a while 
until the first valid one shows up. So we postpone dwfl_attach_state 
until we have a mapping we can resolve to a local elf file.


The code would be cleaner if we could attach_state before starting to 
parse. And there might be pathological cases where no valid elf file can 
ever be found but we can still unwind by frame pointer.


br,
Ulf


Re: frame unwinding patches

2017-04-11 Thread Ulf Hermann

> I do agree with Jan that frame pointer unwinding is notoriously
> untrustworthy. Even with some sanity checks it is hard to know whether
> you are doing a correct unwind. gdb gets away with it through pretty
> advanced frame sniffers, which take a lot of low-level compiler
> generation knowledge to get correct (and even then...). You only restore
> the pc, stack and frame pointer registers (maybe incorrectly). So
> afterwards, even if you got valid CFI data you might be stuck.

Yes, especially with mixed stack traces, where part of the stack has CFI and 
part of it doesn't, we quickly run into guesswork. I've regenerated the 
binaries as suggested, with the result being that raise() from libc actually 
has CFI, but doesn't set a frame pointer. So, the frame pointer unwinder can 
find raise() in the link register, but it sets up the FP register with the 
wrong value. Then raise() is unwound using CFI, which mixes up the registers 
some more. At that point we're lost. I don't see an easy way out of this.

I will keep a version of the frame unwinding for perfparser as it's still 
better than not unwinding at all, but I do understand that it's not really 
suitable for mainline elfutils.

br,
Ulf


Re: frame unwinding patches

2017-04-03 Thread Ulf Hermann

Ping? Any progress on merging this functionality upstream? It can make quite a
difference in unwinding.


The patches have also been in perfparser releases for over a year now. I 
would like to see them upstream.


best,
Ulf


  1   2   >