[PATCH] libdwfl: Fix wrong type to make gcc -fsanitize=undefined happy.
by Mark Wielaard
gcc -fsanitize=undefined would warn about calling dwfl_error accessing
the error string array: elfutils/libdwfl/dwfl_error.c:156:60:
runtime error: index 385 out of bounds for type 'char [9]'
This is because it thought we went beyond error string zero "no error",
which is indeed 9 chars. "Correct" the type of the pointer to make
ubsan happy.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 4 ++++
libdwfl/dwfl_error.c | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d4cd3f5..90c0a04 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2015-04-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwfl_error.c (msgstr): Define as const char *.
+
2015-04-02 Mark Wielaard <mjw(a)redhat.com>
* segment.c (insert): Check correct number of lookup_elts.
diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c
index d9ca9e7..c3648c0 100644
--- a/libdwfl/dwfl_error.c
+++ b/libdwfl/dwfl_error.c
@@ -65,7 +65,7 @@ static const struct msgtable
DWFL_ERRORS
#undef DWFL_ERROR
};
-#define msgstr (&msgtable.msg_NOERROR[0])
+#define msgstr ((const char *) &msgtable)
static const uint_fast16_t msgidx[] =
{
--
2.1.0
8 years, 7 months
[PATCH] libelf: Make sure version xlate dest buffer is fully defined.
by Mark Wielaard
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c16
contains an example of usage of undefined memory when version section
data needs to be translated, but the version xlate functions detect they
cannot fully transform the section data. To make sure the dest buffer
data is completely defined this patch makes sure all data is moved
from src to dest first. This is somewhat inefficient since normally
all data will be fully converted. But the translation functions have
no way to indicate only partial data was converted.
Reported-by: Alexander Cherepanov <cherepan(a)mccme.ru>
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/version_xlate.h | 12 +++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 2ca9509..adfccf1 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-03 Mark Wielaard <mjw(a)redhat.com>
+
+ * version_xlate.h (elf_cvt_Verdef): Use memmove to copy src to dest.
+ (elf_cvt_Verneed): Likewise.
+
2014-12-30 Mark Wielaard <mjw(a)redhat.com>
* elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function.
diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h
index 16eaa19..9fe01c6 100644
--- a/libelf/version_xlate.h
+++ b/libelf/version_xlate.h
@@ -1,5 +1,5 @@
/* Conversion functions for versioning information.
- Copyright (C) 1998, 1999, 2000, 2002, 2003 Red Hat, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 1998.
@@ -55,6 +55,11 @@ elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
if (len == 0)
return;
+ /* Below we rely on the next field offsets to be correct, start by
+ copying over all data as is in case some data isn't translated.
+ We don't want to leave (undefined) garbage in the dest buffer. */
+ memmove (dest, src, len);
+
do
{
size_t aux_offset;
@@ -149,6 +154,11 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
if (len == 0)
return;
+ /* Below we rely on the next field offsets to be correct, start by
+ copying over all data as is in case some data isn't translated.
+ We don't want to leave (undefined) garbage in the dest buffer. */
+ memmove (dest, src, len);
+
do
{
size_t aux_offset;
--
2.1.0
8 years, 7 months
Versioned symbols in elfutils and uClibc
by Max Filippov
Hello,
I've got a segfault in ltrace on uClibc-based system, caused by infinite
recursion in the dwfl_report_elf function [1]. This happens because there
is no symbol versioning support in uClibc and there are two versions of
that function, one of them calling the other. Does the below patch look
like a good solution to this?
[1] http://permalink.gmane.org/gmane.comp.lib.uclibc.buildroot/113856
---8<---
From: Max Filippov <jcmvbkbc(a)gmail.com>
Subject: [PATCH] Allow disabling symbol versioning at configure time
Due to missing symbol versioning support in uClibc calls to versioned
functions that internally call different version of themselves results
in infinite recursion.
Introduce macro SYMBOL_VERSIONING and use it instead of plain SHARED to
decide whether symbol versioning is needed. Control this macro
definition with new configure option --disable-symbol-versioning.
Signed-off-by: Max Filippov <jcmvbkbc(a)gmail.com>
---
config/eu.am | 10 ++++++++--
configure.ac | 5 +++++
lib/eu-config.h | 6 +++---
libdwfl/core-file.c | 2 +-
libdwfl/dwfl_module_build_id.c | 2 +-
libdwfl/dwfl_report_elf.c | 2 +-
6 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/config/eu.am b/config/eu.am
index faf8add..6103a3e 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -38,16 +38,22 @@ AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+DEFS.os = -DPIC -DSHARED
+if SYMBOL_VERSIONING
+DEFS.os += -DSYMBOL_VERSIONING
+else
+endif
+
%.os: %.c %.o
if AMDEP
- if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+ if $(COMPILE.os) -c -o $@ -fpic $(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
- $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $<
+ $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) $<
endif
CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index ed2c964..e3226f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -241,6 +241,11 @@ AS_HELP_STRING([--disable-textrelcheck],
[Disable textrelcheck being a fatal error]))
AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"])
+AC_ARG_ENABLE([symbol-versioning],
+AS_HELP_STRING([--disable-symbol-versioning],
+ [Disable symbol versioning in shared objects]))
+AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
+
dnl The directories with content.
dnl Documentation.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 3afff26..5bb21c1 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -163,7 +163,7 @@ asm (".section predict_data, \"aw\"; .previous\n"
#define ELFUTILS_HEADER(name) <lib##name.h>
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
# define OLD_VERSION(name, version) \
asm (".globl _compat." #version "." #name "\n" \
"_compat." #version "." #name " = " #name "\n" \
@@ -181,8 +181,8 @@ asm (".section predict_data, \"aw\"; .previous\n"
# define OLD_VERSION(name, version) /* Nothing for static linking. */
# define NEW_VERSION(name, version) /* Nothing for static linking. */
# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
- error "should use #ifdef SHARED"
-# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SHARED"
+ error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
#endif
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 324e9d2..bbe0899 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -588,7 +588,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
INTDEF (dwfl_core_file_report)
NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
without_executable)
diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c
index 350bbf8..c9a42ca 100644
--- a/libdwfl/dwfl_module_build_id.c
+++ b/libdwfl/dwfl_module_build_id.c
@@ -101,7 +101,7 @@ dwfl_module_build_id (Dwfl_Module *mod,
INTDEF (dwfl_module_build_id)
NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
int
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 3a4ae2e..624284c 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -321,7 +321,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
INTDEF (dwfl_report_elf)
NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
Dwfl_Module *
_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
const char *file_name, int fd,
--
1.8.1.4
8 years, 7 months
[COMMITTED] Update elf.h from glibc.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
backends/ChangeLog | 5 ++
backends/aarch64_reloc.def | 6 +-
libelf/ChangeLog | 4 +
libelf/elf.h | 190 ++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 192 insertions(+), 13 deletions(-)
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 8d9ecc1..fe61d9c 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-28 Mark Wielaard <mjw(a)redhat.com>
+
+ * aarch64_reloc.def: Drop "64" from TLS_DTPMOD64, TLS_DTPREL64 and
+ TLS_TPREL64.
+
2015-04-01 H.J. Lu <hjl.tools(a)gmail.com>
* Makefile.am (x86_64_SRCS): Add x32_corenote.c.
diff --git a/backends/aarch64_reloc.def b/backends/aarch64_reloc.def
index 2e16e98..f894687 100644
--- a/backends/aarch64_reloc.def
+++ b/backends/aarch64_reloc.def
@@ -34,9 +34,9 @@ RELOC_TYPE (COPY, EXEC|DYN)
RELOC_TYPE (GLOB_DAT, EXEC|DYN)
RELOC_TYPE (JUMP_SLOT, EXEC|DYN)
RELOC_TYPE (RELATIVE, EXEC|DYN)
-RELOC_TYPE (TLS_DTPMOD64, EXEC|DYN)
-RELOC_TYPE (TLS_DTPREL64, EXEC|DYN)
-RELOC_TYPE (TLS_TPREL64, EXEC|DYN)
+RELOC_TYPE (TLS_DTPMOD, EXEC|DYN)
+RELOC_TYPE (TLS_DTPREL, EXEC|DYN)
+RELOC_TYPE (TLS_TPREL, EXEC|DYN)
RELOC_TYPE (TLSDESC, EXEC|DYN)
/* R_AARCH64_NONE records that the section containing the place to be
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index dc9892f..a1b0ee4 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-28 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf.h: Update from glibc.
+
2015-03-23 Mark Wielaard <mjw(a)redhat.com>
* elf32_updatenull.c (updatenull_wrlock): Don't extend size with
diff --git a/libelf/elf.h b/libelf/elf.h
index 40e87b2..39bafc2 100644
--- a/libelf/elf.h
+++ b/libelf/elf.h
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Copyright (C) 1995-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -249,6 +249,7 @@ typedef struct
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_ALTERA_NIOS2 113 /* Altera Nios II */
#define EM_AARCH64 183 /* ARM AARCH64 */
#define EM_TILEPRO 188 /* Tilera TILEPro */
#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
@@ -370,7 +371,7 @@ typedef struct
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
#define SHF_ORDERED (1 << 30) /* Special ordering requirement
(Solaris). */
-#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless
referenced or allocated (Solaris).*/
/* Section group handling. */
@@ -1383,6 +1384,7 @@ typedef struct
#define EF_MIPS_64BIT_WHIRL 16
#define EF_MIPS_ABI2 32
#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */
#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */
@@ -1631,9 +1633,10 @@ typedef struct
/* Legal values for p_type field of Elf32_Phdr. */
-#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
-#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
-#define PT_MIPS_OPTIONS 0x70000002
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information. */
+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+#define PT_MIPS_ABIFLAGS 0x70000003 /* FP mode requirement. */
/* Special program header types. */
@@ -1755,6 +1758,101 @@ typedef struct
typedef Elf32_Addr Elf32_Conflict;
+typedef struct
+{
+ /* Version of flags structure. */
+ Elf32_Half version;
+ /* The level of the ISA: 1-5, 32, 64. */
+ unsigned char isa_level;
+ /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise. */
+ unsigned char isa_rev;
+ /* The size of general purpose registers. */
+ unsigned char gpr_size;
+ /* The size of co-processor 1 registers. */
+ unsigned char cpr1_size;
+ /* The size of co-processor 2 registers. */
+ unsigned char cpr2_size;
+ /* The floating-point ABI. */
+ unsigned char fp_abi;
+ /* Processor-specific extension. */
+ Elf32_Word isa_ext;
+ /* Mask of ASEs used. */
+ Elf32_Word ases;
+ /* Mask of general flags. */
+ Elf32_Word flags1;
+ Elf32_Word flags2;
+} Elf_MIPS_ABIFlags_v0;
+
+/* Values for the register size bytes of an abi flags structure. */
+
+#define MIPS_AFL_REG_NONE 0x00 /* No registers. */
+#define MIPS_AFL_REG_32 0x01 /* 32-bit registers. */
+#define MIPS_AFL_REG_64 0x02 /* 64-bit registers. */
+#define MIPS_AFL_REG_128 0x03 /* 128-bit registers. */
+
+/* Masks for the ases word of an ABI flags structure. */
+
+#define MIPS_AFL_ASE_DSP 0x00000001 /* DSP ASE. */
+#define MIPS_AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */
+#define MIPS_AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */
+#define MIPS_AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */
+#define MIPS_AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */
+#define MIPS_AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */
+#define MIPS_AFL_ASE_MT 0x00000040 /* MT ASE. */
+#define MIPS_AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */
+#define MIPS_AFL_ASE_VIRT 0x00000100 /* VZ ASE. */
+#define MIPS_AFL_ASE_MSA 0x00000200 /* MSA ASE. */
+#define MIPS_AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */
+#define MIPS_AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */
+#define MIPS_AFL_ASE_XPA 0x00001000 /* XPA ASE. */
+#define MIPS_AFL_ASE_MASK 0x00001fff /* All ASEs. */
+
+/* Values for the isa_ext word of an ABI flags structure. */
+
+#define MIPS_AFL_EXT_XLR 1 /* RMI Xlr instruction. */
+#define MIPS_AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */
+#define MIPS_AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */
+#define MIPS_AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */
+#define MIPS_AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */
+#define MIPS_AFL_EXT_5900 6 /* MIPS R5900 instruction. */
+#define MIPS_AFL_EXT_4650 7 /* MIPS R4650 instruction. */
+#define MIPS_AFL_EXT_4010 8 /* LSI R4010 instruction. */
+#define MIPS_AFL_EXT_4100 9 /* NEC VR4100 instruction. */
+#define MIPS_AFL_EXT_3900 10 /* Toshiba R3900 instruction. */
+#define MIPS_AFL_EXT_10000 11 /* MIPS R10000 instruction. */
+#define MIPS_AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */
+#define MIPS_AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */
+#define MIPS_AFL_EXT_4120 14 /* NEC VR4120 instruction. */
+#define MIPS_AFL_EXT_5400 15 /* NEC VR5400 instruction. */
+#define MIPS_AFL_EXT_5500 16 /* NEC VR5500 instruction. */
+#define MIPS_AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */
+#define MIPS_AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */
+
+/* Masks for the flags1 word of an ABI flags structure. */
+#define MIPS_AFL_FLAGS1_ODDSPREG 1 /* Uses odd single-precision registers. */
+
+/* Object attribute values. */
+enum
+{
+ /* Not tagged or not using any ABIs affected by the differences. */
+ Val_GNU_MIPS_ABI_FP_ANY = 0,
+ /* Using hard-float -mdouble-float. */
+ Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+ /* Using hard-float -msingle-float. */
+ Val_GNU_MIPS_ABI_FP_SINGLE = 2,
+ /* Using soft-float. */
+ Val_GNU_MIPS_ABI_FP_SOFT = 3,
+ /* Using -mips32r2 -mfp64. */
+ Val_GNU_MIPS_ABI_FP_OLD_64 = 4,
+ /* Using -mfpxx. */
+ Val_GNU_MIPS_ABI_FP_XX = 5,
+ /* Using -mips32r2 -mfp64. */
+ Val_GNU_MIPS_ABI_FP_64 = 6,
+ /* Using -mips32r2 -mfp64 -mno-odd-spreg. */
+ Val_GNU_MIPS_ABI_FP_64A = 7,
+ /* Maximum allocated FP ABI value. */
+ Val_GNU_MIPS_ABI_FP_MAX = 7
+};
/* HPPA specific definitions. */
@@ -2096,6 +2194,8 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */
+#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
@@ -2139,7 +2239,11 @@ typedef Elf32_Addr Elf32_Conflict;
/* PowerPC specific values for the Dyn d_tag field. */
#define DT_PPC_GOT (DT_LOPROC + 0)
-#define DT_PPC_NUM 1
+#define DT_PPC_OPT (DT_LOPROC + 1)
+#define DT_PPC_NUM 2
+
+/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */
+#define PPC_OPT_TLS 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
@@ -2283,7 +2387,7 @@ typedef Elf32_Addr Elf32_Conflict;
#define DT_PPC64_OPD (DT_LOPROC + 1)
#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
#define DT_PPC64_OPT (DT_LOPROC + 3)
-#define DT_PPC64_NUM 3
+#define DT_PPC64_NUM 4
/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
#define PPC64_OPT_TLS 1
@@ -2362,6 +2466,20 @@ typedef Elf32_Addr Elf32_Conflict;
/* AArch64 relocs. */
#define R_AARCH64_NONE 0 /* No relocation. */
+
+/* ILP32 AArch64 relocs. */
+#define R_AARCH64_P32_ABS32 1 /* Direct 32 bit. */
+#define R_AARCH64_P32_COPY 180 /* Copy symbol at runtime. */
+#define R_AARCH64_P32_GLOB_DAT 181 /* Create GOT entry. */
+#define R_AARCH64_P32_JUMP_SLOT 182 /* Create PLT entry. */
+#define R_AARCH64_P32_RELATIVE 183 /* Adjust by program base. */
+#define R_AARCH64_P32_TLS_DTPMOD 184 /* Module number, 32 bit. */
+#define R_AARCH64_P32_TLS_DTPREL 185 /* Module-relative offset, 32 bit. */
+#define R_AARCH64_P32_TLS_TPREL 186 /* TP-relative offset, 32 bit. */
+#define R_AARCH64_P32_TLSDESC 187 /* TLS Descriptor. */
+#define R_AARCH64_P32_IRELATIVE 188 /* STT_GNU_IFUNC relocation. */
+
+/* LP64 AArch64 relocs. */
#define R_AARCH64_ABS64 257 /* Direct 64 bit. */
#define R_AARCH64_ABS32 258 /* Direct 32 bit. */
#define R_AARCH64_ABS16 259 /* Direct 16-bit. */
@@ -2479,9 +2597,9 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
-#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */
-#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
-#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
+#define R_AARCH64_TLS_DTPMOD 1028 /* Module number, 64 bit. */
+#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset, 64 bit. */
+#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset, 64 bit. */
#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
@@ -3132,6 +3250,58 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */
#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */
+/* Legal values for d_tag (dynamic entry type). */
+#define DT_NIOS2_GP 0x70000002 /* Address of _gp. */
+
+/* Nios II relocations. */
+#define R_NIOS2_NONE 0 /* No reloc. */
+#define R_NIOS2_S16 1 /* Direct signed 16 bit. */
+#define R_NIOS2_U16 2 /* Direct unsigned 16 bit. */
+#define R_NIOS2_PCREL16 3 /* PC relative 16 bit. */
+#define R_NIOS2_CALL26 4 /* Direct call. */
+#define R_NIOS2_IMM5 5 /* 5 bit constant expression. */
+#define R_NIOS2_CACHE_OPX 6 /* 5 bit expression, shift 22. */
+#define R_NIOS2_IMM6 7 /* 6 bit constant expression. */
+#define R_NIOS2_IMM8 8 /* 8 bit constant expression. */
+#define R_NIOS2_HI16 9 /* High 16 bit. */
+#define R_NIOS2_LO16 10 /* Low 16 bit. */
+#define R_NIOS2_HIADJ16 11 /* High 16 bit, adjusted. */
+#define R_NIOS2_BFD_RELOC_32 12 /* 32 bit symbol value + addend. */
+#define R_NIOS2_BFD_RELOC_16 13 /* 16 bit symbol value + addend. */
+#define R_NIOS2_BFD_RELOC_8 14 /* 8 bit symbol value + addend. */
+#define R_NIOS2_GPREL 15 /* 16 bit GP pointer offset. */
+#define R_NIOS2_GNU_VTINHERIT 16 /* GNU C++ vtable hierarchy. */
+#define R_NIOS2_GNU_VTENTRY 17 /* GNU C++ vtable member usage. */
+#define R_NIOS2_UJMP 18 /* Unconditional branch. */
+#define R_NIOS2_CJMP 19 /* Conditional branch. */
+#define R_NIOS2_CALLR 20 /* Indirect call through register. */
+#define R_NIOS2_ALIGN 21 /* Alignment requirement for
+ linker relaxation. */
+#define R_NIOS2_GOT16 22 /* 16 bit GOT entry. */
+#define R_NIOS2_CALL16 23 /* 16 bit GOT entry for function. */
+#define R_NIOS2_GOTOFF_LO 24 /* %lo of offset to GOT pointer. */
+#define R_NIOS2_GOTOFF_HA 25 /* %hiadj of offset to GOT pointer. */
+#define R_NIOS2_PCREL_LO 26 /* %lo of PC relative offset. */
+#define R_NIOS2_PCREL_HA 27 /* %hiadj of PC relative offset. */
+#define R_NIOS2_TLS_GD16 28 /* 16 bit GOT offset for TLS GD. */
+#define R_NIOS2_TLS_LDM16 29 /* 16 bit GOT offset for TLS LDM. */
+#define R_NIOS2_TLS_LDO16 30 /* 16 bit module relative offset. */
+#define R_NIOS2_TLS_IE16 31 /* 16 bit GOT offset for TLS IE. */
+#define R_NIOS2_TLS_LE16 32 /* 16 bit LE TP-relative offset. */
+#define R_NIOS2_TLS_DTPMOD 33 /* Module number. */
+#define R_NIOS2_TLS_DTPREL 34 /* Module-relative offset. */
+#define R_NIOS2_TLS_TPREL 35 /* TP-relative offset. */
+#define R_NIOS2_COPY 36 /* Copy symbol at runtime. */
+#define R_NIOS2_GLOB_DAT 37 /* Create GOT entry. */
+#define R_NIOS2_JUMP_SLOT 38 /* Create PLT entry. */
+#define R_NIOS2_RELATIVE 39 /* Adjust by program base. */
+#define R_NIOS2_GOTOFF 40 /* 16 bit offset to GOT pointer. */
+#define R_NIOS2_CALL26_NOAT 41 /* Direct call in .noat section. */
+#define R_NIOS2_GOT_LO 42 /* %lo() of GOT entry. */
+#define R_NIOS2_GOT_HA 43 /* %hiadj() of GOT entry. */
+#define R_NIOS2_CALL_LO 44 /* %lo() of function GOT entry. */
+#define R_NIOS2_CALL_HA 45 /* %hiadj() of function GOT entry. */
+
/* TILEPro relocations. */
#define R_TILEPRO_NONE 0 /* No reloc */
#define R_TILEPRO_32 1 /* Direct 32 bit */
--
1.8.3.1
8 years, 7 months
[PATCH] readelf: Fix cie_offset calculation comparison on 32bit.
by Mark Wielaard
gcc -fsanitize=undefined pointed out that on 32bit systems the calculation
to match the cie_offset to the cie_id could be undefined because a cie_id
could be an unsigned 64bit value while ptrdiff_t is only 32bits. Correct
the calculation to use 64bit values.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 40a0e6f..6a1aa40 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
2015-03-22 Mark Wielaard <mjw(a)redhat.com>
+ * readelf.c (print_debug_frame_section): Cast start to Dwarf_Off
+ before subtracting cie_id.
+
+2015-03-22 Mark Wielaard <mjw(a)redhat.com>
+
* readelf.c (print_gdb_index_section): Check all offsets used
against section d_size.
diff --git a/src/readelf.c b/src/readelf.c
index 26c7eed..550b00d 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -5619,8 +5619,8 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
struct cieinfo *cie = cies;
while (cie != NULL)
if (is_eh_frame
- ? start - (ptrdiff_t) cie_id == cie->cie_offset
- : (ptrdiff_t) cie_id == cie->cie_offset)
+ ? ((Dwarf_Off) start - cie_id) == cie->cie_offset
+ : cie_id == cie->cie_offset)
break;
else
cie = cie->next;
--
2.1.0
8 years, 7 months
[PATCH] libdw: Undefined behavior in get_sleb128_step.
by Mark Wielaard
gcc -fsanitize=undefined pointed out that for too big sleb128 values we
could shift into the sign bit. So for sleb128 values that have to fit
in a (signed) int64_t variable reduce the max number of steps by one.
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c29
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 8 ++++++++
libdw/memory-access.h | 23 +++++++++++++++++++----
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 87c7d82..739e0f6 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2015-04-22 Mark Wielaard <mjw(a)redhat.com>
+
+ * memory-access.h (__libdw_max_len_leb128): Take type_len as argument.
+ (__libdw_max_len_uleb128): New function.
+ (__libdw_max_len_sleb128): Likewise.
+ (__libdw_get_uleb128): Use __libdw_max_len_uleb128.
+ (__libdw_get_sleb128): Use __libdw_max_len_sleb128.
+
2015-04-21 Mark Wielaard <mjw(a)redhat.com>
* dwarf_getmacros.c (read_macros): Allocate attributes dynamically
diff --git a/libdw/memory-access.h b/libdw/memory-access.h
index a53f791..a749b5a 100644
--- a/libdw/memory-access.h
+++ b/libdw/memory-access.h
@@ -40,13 +40,28 @@
#define len_leb128(var) ((8 * sizeof (var) + 6) / 7)
static inline size_t
-__libdw_max_len_leb128 (const unsigned char *addr, const unsigned char *end)
+__libdw_max_len_leb128 (const size_t type_len,
+ const unsigned char *addr, const unsigned char *end)
{
- const size_t type_len = len_leb128 (uint64_t);
const size_t pointer_len = likely (addr < end) ? end - addr : 0;
return likely (type_len <= pointer_len) ? type_len : pointer_len;
}
+static inline size_t
+__libdw_max_len_uleb128 (const unsigned char *addr, const unsigned char *end)
+{
+ const size_t type_len = len_leb128 (uint64_t);
+ return __libdw_max_len_leb128 (type_len, addr, end);
+}
+
+static inline size_t
+__libdw_max_len_sleb128 (const unsigned char *addr, const unsigned char *end)
+{
+ /* Subtract one step, so we don't shift into sign bit. */
+ const size_t type_len = len_leb128 (int64_t) - 1;
+ return __libdw_max_len_leb128 (type_len, addr, end);
+}
+
#define get_uleb128_step(var, addr, nth) \
do { \
unsigned char __b = *(addr)++; \
@@ -64,7 +79,7 @@ __libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end)
for the common single-byte case. */
get_uleb128_step (acc, *addrp, 0);
- const size_t max = __libdw_max_len_leb128 (*addrp - 1, end);
+ const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end);
for (size_t i = 1; i < max; ++i)
get_uleb128_step (acc, *addrp, i);
/* Other implementations set VALUE to UINT_MAX in this
@@ -98,7 +113,7 @@ __libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end)
for the common single-byte case. */
get_sleb128_step (acc, *addrp, 0);
- const size_t max = __libdw_max_len_leb128 (*addrp - 1, end);
+ const size_t max = __libdw_max_len_sleb128 (*addrp - 1, end);
for (size_t i = 1; i < max; ++i)
get_sleb128_step (acc, *addrp, i);
/* Other implementations set VALUE to INT_MAX in this
--
2.1.0
8 years, 7 months
[PATCH] readelf: Check all offsets used in print_gdb_index_section against d_size.
by Mark Wielaard
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c29
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/readelf.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/readelf.c b/src/readelf.c
index 7f84eda..26c7eed 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8015,11 +8015,12 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
< const_off))
goto invalid_data;
- const unsigned char *const_start = data->d_buf + const_off;
-
readp = data->d_buf + cu_off;
const unsigned char *nextp = data->d_buf + tu_off;
+ if (tu_off >= data->d_size)
+ goto invalid_data;
+
size_t cu_nr = (nextp - readp) / 16;
printf (gettext ("\n CU list at offset %#" PRIx32
@@ -8042,6 +8043,9 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + tu_off;
nextp = data->d_buf + addr_off;
+ if (addr_off >= data->d_size)
+ goto invalid_data;
+
size_t tu_nr = (nextp - readp) / 24;
printf (gettext ("\n TU list at offset %#" PRIx32
@@ -8068,6 +8072,9 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + addr_off;
nextp = data->d_buf + sym_off;
+ if (sym_off >= data->d_size)
+ goto invalid_data;
+
size_t addr_nr = (nextp - readp) / 20;
printf (gettext ("\n Address list at offset %#" PRIx32
@@ -8095,6 +8102,10 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
n++;
}
+ const unsigned char *const_start = data->d_buf + const_off;
+ if (const_off >= data->d_size)
+ goto invalid_data;
+
readp = data->d_buf + sym_off;
nextp = const_start;
size_t sym_nr = (nextp - readp) / 8;
--
2.1.0
8 years, 7 months
[PATCH] readelf: Always try to print some debug section information.
by Mark Wielaard
Even if we cannot create a proper Dwarf dbg we can still print the
information of various debug sections. All all debug print section
functions already check first they can access the appropriate data.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 4 ++++
src/readelf.c | 2 --
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 6985b58..e92f115 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
2015-03-17 Mark Wielaard <mjw(a)redhat.com>
+ * readelf.c (print_debug): Don't return, but always use dummy_dbg.
+
+2015-03-17 Mark Wielaard <mjw(a)redhat.com>
+
* readelf.c (print_gdb_index_section): Add overflow checking for
dataend checks.
diff --git a/src/readelf.c b/src/readelf.c
index b717757..7f84eda 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8188,8 +8188,6 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
if ((print_debug_sections & ~section_exception) != 0)
error (0, 0, gettext ("cannot get debug context descriptor: %s"),
dwfl_errmsg (-1));
- if ((print_debug_sections & section_exception) == 0)
- return;
dbg = &dummy_dbg;
}
--
2.1.0
8 years, 7 months
[PATCH] readelf: Add overflow checking to print_gdb_index_section dataend checks.
by Mark Wielaard
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c29
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 24 +++++++++++++++---------
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index c8ddff6..6985b58 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-17 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_gdb_index_section): Add overflow checking for
+ dataend checks.
+
2015-03-14 Mark Wielaard <mjw(a)redhat.com>
* nm.c (INTERNAL_ERROR): Remove __DATE__.
diff --git a/src/readelf.c b/src/readelf.c
index 23bd73f..b717757 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8011,6 +8011,12 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
+ if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
+ < const_off))
+ goto invalid_data;
+
+ const unsigned char *const_start = data->d_buf + const_off;
+
readp = data->d_buf + cu_off;
const unsigned char *nextp = data->d_buf + tu_off;
@@ -8021,7 +8027,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
cu_off, cu_nr);
size_t n = 0;
- while (readp + 16 <= dataend && n < cu_nr)
+ while (dataend - readp >= 16 && n < cu_nr)
{
uint64_t off = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -8043,7 +8049,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
tu_off, tu_nr);
n = 0;
- while (readp + 24 <= dataend && n < tu_nr)
+ while (dataend - readp >= 24 && n < tu_nr)
{
uint64_t off = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -8069,7 +8075,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
addr_off, addr_nr);
n = 0;
- while (readp + 20 <= dataend && n < addr_nr)
+ while (dataend - readp >= 20 && n < addr_nr)
{
uint64_t low = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -8090,7 +8096,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
}
readp = data->d_buf + sym_off;
- nextp = data->d_buf + const_off;
+ nextp = const_start;
size_t sym_nr = (nextp - readp) / 8;
printf (gettext ("\n Symbol table at offset %#" PRIx32
@@ -8098,7 +8104,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
addr_off, sym_nr);
n = 0;
- while (readp + 8 <= dataend && n < sym_nr)
+ while (dataend - readp >= 8 && n < sym_nr)
{
uint32_t name = read_4ubyte_unaligned (dbg, readp);
readp += 4;
@@ -8108,15 +8114,15 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
if (name != 0 || vector != 0)
{
- const unsigned char *sym = data->d_buf + const_off + name;
- if (unlikely (sym > dataend
+ const unsigned char *sym = const_start + name;
+ if (unlikely ((size_t) (dataend - const_start) < name
|| memchr (sym, '\0', dataend - sym) == NULL))
goto invalid_data;
printf (" [%4zu] symbol: %s, CUs: ", n, sym);
- const unsigned char *readcus = data->d_buf + const_off + vector;
- if (unlikely (readcus + 4 > dataend))
+ const unsigned char *readcus = const_start + vector;
+ if (unlikely ((size_t) (dataend - const_start) < vector))
goto invalid_data;
uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
while (cus--)
--
1.8.3.1
8 years, 7 months
[PATCH] libdw: Don't overflow stack with user defined macro attributes array.
by Mark Wielaard
In theory user defined debug macros can have an arbitrary number of
arguments. Don't allocate them all on stack. If there are more than
8 (arbitrary number, but no sane macro should have more arguments),
then dynamically allocate and free the attributes.
Found by gcc -fsanitize=undefined. Which pointed out the nforms could
be zero, creating an empty vla (which could cause undefined behavior).
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 5 +++++
libdw/dwarf_getmacros.c | 23 +++++++++++++++++++++--
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 3abb382..87c7d82 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getmacros.c (read_macros): Allocate attributes dynamically
+ when there are more than 8.
+
2015-04-01 Petr Machata <pmachata(a)redhat.com>
* libdwP.h (DWARF_E_NOT_CUDIE): New enumerator.
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index f9f2996..c5d47d6 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -361,7 +361,22 @@ read_macros (Dwarf *dbg, int sec_index,
.endp = (void *) endp,
};
- Dwarf_Attribute attributes[proto->nforms];
+ Dwarf_Attribute *attributes;
+ Dwarf_Attribute *attributesp = NULL;
+ Dwarf_Attribute nattributes[8];
+ if (unlikely (proto->nforms > 8))
+ {
+ attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms);
+ if (attributesp == NULL)
+ {
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return -1;
+ }
+ attributes = attributesp;
+ }
+ else
+ attributes = &nattributes[0];
+
for (Dwarf_Word i = 0; i < proto->nforms; ++i)
{
/* We pretend this is a DW_AT_GNU_macros attribute so that
@@ -385,7 +400,11 @@ read_macros (Dwarf *dbg, int sec_index,
.attributes = attributes,
};
- if (callback (¯o, arg) != DWARF_CB_OK)
+ int res = callback (¯o, arg);
+ if (unlikely (attributesp != NULL))
+ free (attributesp);
+
+ if (res != DWARF_CB_OK)
return readp - startp;
}
--
2.1.0
8 years, 7 months