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 
---
 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  
 
+   * Makefile.am: Add EXEEXT to gendis.
+
+2017-04-20  Ulf Hermann  
+
* i386_parse.y: Eliminate comparison_fn_t.
 
 2016-11-02  Mark Wielaard  
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 
---
 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  
 
+   * elf_update.c: Set ELF_F_MMAPPED flag if we mmap from elf_update.
+
+2017-04-20  Ulf Hermann  
+
* libelfP.h: Don't include config.h.
 
 2017-04-20  Ulf Hermann  
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 
---
 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  
 
+   * derelocate.c (compare_secrefs): Compare by end address and then by
+   name if start addresses are equal.
+
+2017-04-20  Ulf Hermann  
+
* elf-from-memory.c: Explicitly cast phnum to size_t.
 
 2017-04-20  Ulf Hermann  
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 
 
+   * 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 
+
* 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 
---
 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  
 
+   * elf-from-memory.c: Explicitly cast phnum to size_t.
+
+2017-04-20  Ulf Hermann  
+
* 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



Re: [PATCH] Include sys/types.h before fts.h

2017-04-20 Thread Dmitry V. Levin
On Thu, Apr 20, 2017 at 03:26:47PM +0200, Ulf Hermann wrote:
> The bad fts not only needs to be included before config.h, but also
> requires various special types without including sys/types.h.

Please do not include  before  unconditionally.
If bad fts needs , then do it [BAD_FTS].


-- 
ldv


signature.asc
Description: PGP signature


[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 
---
 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  
 
+   * readelf.c: Include strings.h.
+
+2017-04-20  Ulf Hermann  
+
* unstrip.c: Check shnum for 0 before subtracting from it.
 
 2017-04-20  Ulf Hermann 
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 
---
 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  
+
+   * crc32.c: include config.h.
+   * system.h: Don't include config.h.
+
 2017-02-16  Ulf Hermann  
 
* 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 .  */
 
+#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_SYSTEM_H   1
 
-#ifdef HAVE_CONFIG_H
-# 

[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 
---
 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  
 
+   * dwfl_module_getdwarf.c: Check shnum for 0 before subtracting from
+   it.
+
+2017-04-20  Ulf Hermann  
+
* libdwfl.h: Use __const_attribute__.
 
 2017-04-20  Ulf Hermann 
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  
+
+   * unstrip.c: Check shnum for 0 before subtracting from it.
+
 2017-04-20  Ulf Hermann 
 
* 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 (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
   ".gnu.prelink_undo");
 
-  bool class32 = 

[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 
---
 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  
 
+   * elf_begin.c: Use F_GETFD rather than F_GETFL.
+
+2017-04-20  Ulf Hermann  
+
* 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 
---
 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  
+
+   * libdw.h: Remove attribute macro declarations and use
+   __noreturn_attribute__ as defined in libelf.h.
+
 2017-03-30  Mark Wielaard  
 
* 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  
+
+   * libdwfl.h: Use __const_attribute__.
+
 2017-04-20  Ulf Hermann 
 
* 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  
+
+   * libebl.h: Use __pure_attribute__.
+
 2017-02-15  Ulf Hermann  
 
* 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  
+
+   * libelf.h: Define macros for various function attributes and use
+   them.
+
 2017-03-27  Mark Wielaard  
 
* 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__ __attribute__ ((__pure__))
+# define __const_attribute__ __attribute__ ((__const__))
+#else

[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 
---
 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 
+
+   * readelf.c: Replace YESSTR and NOSTR with gettext ("yes") and
+   gettext ("no"), respectively.
+
 2017-04-05  Mark Wielaard  
 
* 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 
 
+   * 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 
+
* 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 (0x004006d8)
  frame_base   (exprloc) 
   [   0] call_frame_cfa
- GNU_all_tail_call_sites (flag_present) 
+ GNU_all_tail_call_sites (flag_present) yes
  sibling

[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 
---
 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 
+
+   * 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  
 
* 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 
 
+   * 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 
+
* linux-kernel-modules.c: Include sys/types.h before fts.h
 
 2017-03-24  Mark Wielaard  
diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c
index d639939..1dc0c8d 100644
--- 

[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 
---
 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  
 
+   * 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  
+
* 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 .  */
+
+#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 same frame again in the next round.
+  if ((pc 

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