[PATCH] Fix section corruption bug
by Thilo Schulz
Hi,
When adding data to existing sections in ELF files, libelf may corrupt
those sections, i.e. overwrite the existing data if certain conditions are
met.
If an Elf_Scn structure has seen a call to elf_rawdata(scn) before but no
call to elf_getdata(scn), scn->read_data flag is set, but not
scn->data_list_rear.
Thus, elf_newdata(scn) incorrectly detects a "new user added section" when
really it is a section with live, valid data that will be overwritten by
elf_update(), corrupting the section.
This patch fixes this incorrect behaviour.
Signed-off-by: Thilo Schulz <thilo(a)tjps.eu>
---
libelf/elf_newdata.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c
index 90d1813..f90eb0a 100644
--- a/libelf/elf_newdata.c
+++ b/libelf/elf_newdata.c
@@ -64,7 +64,7 @@ elf_newdata (Elf_Scn *scn)
rwlock_wrlock (scn->elf->lock);
- if (scn->data_read && scn->data_list_rear == NULL)
+ if (scn->data_read && scn->data_list_rear == NULL && !scn->rawdata.s)
{
/* This means the section was created by the user and this is the
first data. */
--
1.7.10.4
9 years
elfutils 0.160 released
by Mark Wielaard
A new release of elfutils is available now at:
https://fedorahosted.org/releases/e/l/elfutils/0.160/
* NEWS *
Version 0.160
libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die.
dwarf.h remove non-existing DW_TAG_mutable_type.
libdwfl: Handle LZMA .ko.xz compressed kernel modules.
unstrip: New option -F, --force to combining files even if some
ELF headers don't seem to match.
backends: Handle ARM THUMB functions.
Add support for ppc64le ELFv2 abi.
* GIT SHORTLOG *
Jan Kratochvil (1):
Fix report_r_debug for prelinked libraries
Josh Stone (1):
Prevent premature @AR@ replacement in a sed expression.
Kurt Roeckx (1):
Make the attach code build again on non-Linux hosts.
Kyle McMartin (1):
aarch64: use <sys/user.h> defined register structures
Mark Wielaard (20):
unstrip: Add --force to force combining files when ELF headers
don't match.
unstrip: Allow prelinked, but non-split .bss section.
readelf: Don't print 'for section' when rela section sh_info is
zero.
readelf: Skip section if name is NULL in print_debug.
libdwfl: dwfl_standard_argp should not fail when not able to
attach Dwfl.
libdwfl: Record dwfl_attach_state error and return it on failure.
libdwfl: linux-core-attach.c handle possible unaligned data
access.
tests: backtrace-subr.sh add check_native_unsupported.
tests: backtrace.c accept __libc_do_syscall as first frame
symname.
tests/backtrace.c (frame_callback): Error on seeing more than 16
frames.
libebl: Add ebl_func_addr_mask plus ARM backend implementation.
dwarf.h: Remove non-existing DW_TAG_mutable_type.
backends: aarch64_return_value_location should handle
DW_ATE_boolean.
Update elf.h from glibc.
Add ppc64le ELFv2 abi support to backends and elflint.
m4: Handle cross-compile situations in biarch.m4 tests.
libdwfl: Handle LZMA .ko.xz compressed kernel modules.
libdw: Add new function dwarf_cu_getdwarf.
libdw: Add new function dwarf_cu_die.
Prepare 0.160 release.
Petr Machata (1):
backends (*_return_value_location): call dwarf_peeled_die_type
9 years, 6 months
Prevent premature @AR@ replacement in a sed expression.
by Josh Stone
FYI, I just pushed commit f1ec744b5747 to shield a sed expression from
autoconf's replacement. That was causing every instance of "ar" in
make-debug-archive to be replaced with a full path.
This phenomenon was reported by SamB on IRC.
---
This is free softw/usr/local/bin/are
There is NO w/usr/local/bin/arranty
9 years, 6 months
Preparing for elfutils 0.160
by Mark Wielaard
Hi,
It has been 3 months since elfutils 0.159, since then we have seen more
than 20 commits, fixing several bugs and adding some new features
(ppc64le ELFv2 abi, arm thumb support, unstrip -F, dwarf_cu_getdwarf,
dwarf_cu_die). There are some bugs in the bugtracker, that I want to go
over, but none of them look like regressions:
https://bugzilla.redhat.com/buglist.cgi?bug_status=NEW&bug_status=ASSIGNE...
It would be nice to get some more fixes in, but I don't believe any of
them are block a new release. Is there something someone thinks should
go in before we do a release?
I would like to push for a 0.160 release in a week, around Wednesday 27
August. And then aim for the next release in ~3 months again, before the
end of the year, to keep things moving forward.
Cheers,
Mark
9 years, 6 months
[PATCH 1/2] libdw: Add new function dwarf_cu_getdwarf.
by Mark Wielaard
In both systemtap and libabigail there is a need to get the actual Dwarf
underlying an Dwarf_Die or Dwarf_Attribute. Following a DIE reference
might end up in an alternate Dwarf since the addition of DWZ multifile
forms. Both Dwarf_Die and Dwarf_Attribute already contain a Dwarf_CU
handle. Add a function dwarf_cu_getdwarf to retrieve the underlying
Dwarf using the Dwarf_CU.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 4 ++++
NEWS | 2 ++
libdw/ChangeLog | 8 ++++++++
libdw/Makefile.am | 2 +-
libdw/dwarf_cu_getdwarf.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
libdw/libdw.h | 9 ++++++++-
libdw/libdw.map | 5 +++++
7 files changed, 75 insertions(+), 2 deletions(-)
create mode 100644 libdw/dwarf_cu_getdwarf.c
diff --git a/ChangeLog b/ChangeLog
index b470b3d..dd92265 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-08-15 Mark Wielaard <mjw(a)redhat.com>
+
+ * NEWS: Add dwarf_cu_getdwarf.
+
2014-07-18 Mark Wielaard <mjw(a)redhat.com>
* configure.ac (AC_CHECK_TYPE): Test for struct user_regs_struct.
diff --git a/NEWS b/NEWS
index 4050200..3e4e8cc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
Version 0.160
+libdw: New function dwarf_cu_getdwarf.
+
unstrip: New option -F, --force to combining files even if some ELF headers
don't seem to match.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 2884419..8dfd11e 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2014-08-15 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_cu_getdwarf.c: New file.
+ * Makefile.am (libdw_a_SOURCES): Add dwarf_cu_getdwarf.c.
+ * libdw.h (Dwarf_CU): New typedef.
+ (dwarf_cu_getdwarf): New function declaration.
+ * libdw.map (ELFUTILS_0.160): New. Add dwarf_cu_getdwarf.
+
2014-06-18 Mark Wielaard <mjw(a)redhat.com>
* dwarf.h: Remove DW_TAG_mutable_type.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 8538d36..e39ab9a 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -86,7 +86,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \
dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \
dwarf_getlocation_die.c dwarf_getlocation_attr.c \
- dwarf_getalt.c dwarf_setalt.c
+ dwarf_getalt.c dwarf_setalt.c dwarf_cu_getdwarf.c
if MAINTAINER_MODE
BUILT_SOURCES = $(srcdir)/known-dwarf.h
diff --git a/libdw/dwarf_cu_getdwarf.c b/libdw/dwarf_cu_getdwarf.c
new file mode 100644
index 0000000..f8a2e9b
--- /dev/null
+++ b/libdw/dwarf_cu_getdwarf.c
@@ -0,0 +1,47 @@
+/* Retrieve Dwarf descriptor underlying a Dwarf_CU.
+ Copyright (C) 2014 Red Hat, Inc.
+ 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 <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+Dwarf *
+dwarf_cu_getdwarf (cu)
+ Dwarf_CU *cu;
+{
+ if (cu == NULL)
+ /* Some error occurred before. */
+ return NULL;
+
+ return cu->dbg;
+}
diff --git a/libdw/libdw.h b/libdw/libdw.h
index a4654c4..61d3b38 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -1,5 +1,5 @@
/* Interfaces for libdw.
- Copyright (C) 2002-2010, 2013 Red Hat, Inc.
+ Copyright (C) 2002-2010, 2013, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -112,6 +112,7 @@ typedef struct Dwarf_Aranges_s Dwarf_Aranges;
/* CU representation. */
struct Dwarf_CU;
+typedef struct Dwarf_CU Dwarf_CU;
/* Macro information. */
typedef struct Dwarf_Macro_s Dwarf_Macro;
@@ -260,6 +261,12 @@ extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp);
/* Retrieve ELF descriptor used for DWARF access. */
extern Elf *dwarf_getelf (Dwarf *dwarf);
+/* Retieve DWARF descriptor used for a Dwarf_Die or Dwarf_Attribute.
+ A Dwarf_Die or a Dwarf_Attribute is associated with a particular
+ Dwarf_CU handle. This function returns the DWARF descriptor for
+ that Dwarf_CU. */
+extern Dwarf *dwarf_cu_getdwarf (Dwarf_CU *cu);
+
/* Retrieves the DWARF descriptor for debugaltlink data. Returns NULL
if no alternate debug data has been supplied. */
extern Dwarf *dwarf_getalt (Dwarf *main);
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 899e13e..27e2273 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -301,3 +301,8 @@ ELFUTILS_0.159 {
dwelf_elf_gnu_debuglink;
dwelf_elf_gnu_build_id;
} ELFUTILS_0.158;
+
+ELFUTILS_0.160 {
+ global:
+ dwarf_cu_getdwarf;
+} ELFUTILS_0.159;
\ No newline at end of file
--
1.8.3.1
9 years, 7 months
[PATCH] libdwfl: Handle LZMA .ko.xz compressed kernel modules.
by Mark Wielaard
Linux kernel modules can not just be compressed with gz and bz2, but also
with xz.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 4 ++++
libdwfl/linux-kernel-modules.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ab47c40..e792998 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2014-08-14 Mark Wielaard <mjw(a)redhat.com>
+
+ * linux-kernel-modules.c (check-suffix): Also TRY .ko.yz.
+
2014-07-24 Jan Kratochvil <jan.kratochvil(a)redhat.com>
Fix report_r_debug for prelinked libraries.
diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 1ad7d2f..61b06b6 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -302,6 +302,9 @@ check_suffix (const FTSENT *f, size_t namelen)
#if USE_BZLIB
TRY (".ko.bz2");
#endif
+#ifdef USE_LZMA
+ TRY (".ko.xz");
+#endif
return 0;
--
1.8.3.1
9 years, 7 months
MIPS and -msym32
by Crestez Dan Leonard
Hello,
I've been playing around with systemtap on mips.
I used the elfutils mips patch from debian:
http://sources.debian.net/src/elfutils/0.159-4/debian/patches/mips_backen...
For systemtap I ported some old patches from cisco on top of release 2.5. Here is the link to the patches on top of 1.6:
https://sourceware.org/git/gitweb.cgi?p=systemtap.git;a=log;h=refs/heads/...
One of the issues I encountered is that by default 64-bit mips kernels are compiled with -msym32. This causes gcc to emit dwarf information with a pointer size of 4, even though the file is 64bit. In theory this can be disabled by passing KBUILD_SYM32=no to the kernel make commandline. This is a bad idea. It would disable some optimizations which have been enabled on mips for many years. I actually tried to do it locally but it broke module loading and I was unable to boot.
The generated dwarf files confuse systemtap is multiple ways.
When fetching some parameters systemtap relies on address_size from dwarf_diecu to determine max_fetch_size. This caused an error like "semantic error: single register too big for fetch/store ???: identifier '$data' at ..." for an unsigned long variable.
Here is a hack I used to get around this:
--- a/libdw/dwarf_diecu.c
+++ b/libdw/dwarf_diecu.c
@@ -47,7 +47,22 @@ dwarf_diecu (die, result, address_sizep, offset_sizep)
*result = CUDIE (die->cu);
if (address_sizep != NULL)
+ {
*address_sizep = die->cu->address_size;
+ /* Hack: */
+ if (1)
+ {
+ struct Elf *elf = die->cu->dbg->elf;
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr* ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr &&
+ ehdr->e_machine == EM_MIPS &&
+ ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ {
+ *address_sizep = 8;
+ }
+ }
+ }
if (offset_sizep != NULL)
*offset_sizep = die->cu->offset_size;
This is obviously evil. What is worse is that -msym32 seems to break systemtap address mapping. Earlier I had to do the following hack inside systemtap.
diff --git a/tapsets.cxx b/tapsets.cxx
index 4e42403..94ee230 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1265,6 +1265,22 @@ dwarf_query::add_probe_point(const string& dw_funcname,
else
{
assert (has_kernel || has_module);
+ if (1)
+ {
+ Dwarf_Addr bias;
+ Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias))
+ ?: dwfl_module_getelf (dw.module, &bias));
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
+ int elf_machine = em->e_machine;
+ if (elf_machine == EM_MIPS)
+ {
+ if (sess.verbose > 1)
+ clog << "Hack reloc=" << hex << reloc_addr
+ << " from addr=" << hex << addr;
+ reloc_addr = addr - 0xc0000400;
+ }
+ }
results.push_back (new dwarf_derived_probe(funcname, filename, line,
module, reloc_section, addr, reloc_addr,
*this, scope_die));
At the time I did the hack I was unaware of -msym32, I just wanted something to work. If I compile with KBUILD_SYM32=no it seems that the above hack might no longer be necessary (the addresses "look" right). I can't actually test the generated probes because my system won't boot with KBUILD_SYM32=no.
Apparently the gcc folks decided that this -msym32 behavior was too confusing and changed it to generate dwarf with a pointer size of 8:
https://gcc.gnu.org/ml/gcc/2009-01/msg00611.html
In the future this might not matter, but my cross-compiler is based on gcc-4.3.3. I'm posting this here because maybe somebody has a better idea about how to deal with this strange flavor of dwarf.
If this could be detected and handled inside systemtap fully then maybe you could apply the patches. Elfutils seems mostly blameless to me, it's just reading the information that GCC wrote.
Regards,
Leonard
9 years, 7 months
prevernt -m32 testing in configure
by daggs
Greetings,
I'm trying to compile elfutils-0.159 on a 64 bit system.
in the configure stage I'm getting to this situation:
checking whether gcc -m32 makes executables we can run.. and it fails.
I assume that this is because I don't have 32bit libs on my system.
now here is my issue, I cannot install 32bit libs, infact I need libelf to be 64 bit only.
my question is how I can disable that test and build libelf for 64 only?
Thanks.
9 years, 7 months
[PATCH] aarch64: use <sys/user.h> defined register structures
by Kyle McMartin
glibc now supplies these (compatible) structs instead of including the
kernel's <asm/ptrace.h> header, so let's use them. Annoyingly this will
cause new elfutils to FTBFS on old glibc, and vice versa, but that seems
unavoidable in the growth of a new port, and the workaround of checking
for header defines and defining one to the other seems unpleasant as
well. Therefore, bite the bullet, and let packaging systems alter their
build requires accordingly.
--- a/backends/aarch64_initreg.c
+++ b/backends/aarch64_initreg.c
@@ -51,7 +51,7 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
#else /* __aarch64__ */
/* General registers. */
- struct user_pt_regs gregs;
+ struct user_regs_struct gregs;
struct iovec iovec;
iovec.iov_base = &gregs;
iovec.iov_len = sizeof (gregs);
@@ -69,7 +69,7 @@ aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
/* ELR cannot be found. */
/* FP registers (only 64bits are used). */
- struct user_fpsimd_state fregs;
+ struct user_fpsimd_struct fregs;
iovec.iov_base = &fregs;
iovec.iov_len = sizeof (fregs);
if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) != 0)
diff --git a/backends/arm_initreg.c b/backends/arm_initreg.c
index 5837383..1edf62b 100644
--- a/backends/arm_initreg.c
+++ b/backends/arm_initreg.c
@@ -67,7 +67,7 @@ arm_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
#elif defined __aarch64__
/* Compat mode: arm compatible code running on aarch64 */
int i;
- struct user_pt_regs gregs;
+ struct user_regs_struct gregs;
struct iovec iovec;
iovec.iov_base = &gregs;
iovec.iov_len = sizeof (gregs);
9 years, 7 months