[PATCH] libelf: Do not cast pointer to integer in gelf_newphdr
by Akihiko Odaki
unsigned long int is not always capable to have pointer in some cases
(LLP64, for example).
Signed-off-by: Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
---
libelf/gelf.h | 4 ++--
libelf/gelf_newehdr.c | 6 +++---
libelf/gelf_newphdr.c | 6 +++---
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libelf/gelf.h b/libelf/gelf.h
index 1bc7ee7..0c31c27 100644
--- a/libelf/gelf.h
+++ b/libelf/gelf.h
@@ -166,7 +166,7 @@ extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest);
extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src);
/* Create new ELF header if none exists. */
-extern unsigned long int gelf_newehdr (Elf *__elf, int __class);
+extern void *gelf_newehdr (Elf *__elf, int __class);
/* Get section at OFFSET. */
extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset);
@@ -184,7 +184,7 @@ extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst);
extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src);
/* Create new program header with PHNUM entries. */
-extern unsigned long int gelf_newphdr (Elf *__elf, size_t __phnum);
+extern void *gelf_newphdr (Elf *__elf, size_t __phnum);
/* Get compression header of section if any. Returns NULL and sets
elf_errno if the section isn't compressed or an error occurred. */
diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c
index cfa80e1..2788906 100644
--- a/libelf/gelf_newehdr.c
+++ b/libelf/gelf_newehdr.c
@@ -37,10 +37,10 @@
#include "libelfP.h"
-unsigned long int
+void *
gelf_newehdr (Elf *elf, int class)
{
return (class == ELFCLASS32
- ? (unsigned long int) INTUSE(elf32_newehdr) (elf)
- : (unsigned long int) INTUSE(elf64_newehdr) (elf));
+ ? (void *) INTUSE(elf32_newehdr) (elf)
+ : (void *) INTUSE(elf64_newehdr) (elf));
}
diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c
index 4e95474..84aad78 100644
--- a/libelf/gelf_newphdr.c
+++ b/libelf/gelf_newphdr.c
@@ -37,10 +37,10 @@
#include "libelfP.h"
-unsigned long int
+void *
gelf_newphdr ( Elf *elf, size_t phnum)
{
return (elf->class == ELFCLASS32
- ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum)
- : (unsigned long int) INTUSE(elf64_newphdr) (elf, phnum));
+ ? (void *) INTUSE(elf32_newphdr) (elf, phnum)
+ : (void *) INTUSE(elf64_newphdr) (elf, phnum));
}
--
2.10.0
6 years, 11 months
[PATCH] libelf: Always set ELF maxsize when reading an ELF file for sanity checks.
by Mark Wielaard
There are various sanity checks that depend on knowing the file size
of the underlying ELF file which we only used when mmapping the ELF file.
Although we probably won't crash if we use pread to try to read from
the file, we still might return completely bogus data structures. This
could cause us to malloc insane amounts of memory.
Always try to get the maxsize when unknown in elf_begin.c (read_file).
https://bugzilla.redhat.com/show_bug.cgi?id=1388057
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 8 ++++++--
libelf/elf_begin.c | 37 +++++++++++++++++++++----------------
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 35af786..39fbccf 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,4 +1,8 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-26 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_begin.c (read_file): Always set maxsize when parent == NULL.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
available.
@@ -6,7 +10,7 @@
(validate_str): New function.
(elf_strptr): Use validate_str instead of memrchr.
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf32_updatefile.c: Remove sys/param.h include.
* elf32_updatenull.c: Likewise. Add system.h include.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 8fdb376..5e9099c 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -1,5 +1,5 @@
/* Create descriptor for processing file.
- Copyright (C) 1998-2010, 2012, 2014, 2015 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 1998.
@@ -605,22 +605,30 @@ read_file (int fildes, off_t offset, size_t maxsize,
|| cmd == ELF_C_WRITE_MMAP
|| cmd == ELF_C_READ_MMAP_PRIVATE);
+ if (parent == NULL)
+ {
+ if (maxsize == ~((size_t) 0))
+ {
+ /* We don't know in the moment how large the file is.
+ Determine it now. */
+ struct stat st;
+
+ if (fstat (fildes, &st) == 0
+ && (sizeof (size_t) >= sizeof (st.st_size)
+ || st.st_size <= ~((size_t) 0)))
+ maxsize = (size_t) st.st_size;
+ }
+ }
+ else
+ {
+ /* The parent is already loaded. Use it. */
+ assert (maxsize != ~((size_t) 0));
+ }
+
if (use_mmap)
{
if (parent == NULL)
{
- if (maxsize == ~((size_t) 0))
- {
- /* We don't know in the moment how large the file is.
- Determine it now. */
- struct stat st;
-
- if (fstat (fildes, &st) == 0
- && (sizeof (size_t) >= sizeof (st.st_size)
- || st.st_size <= ~((size_t) 0)))
- maxsize = (size_t) st.st_size;
- }
-
/* We try to map the file ourself. */
map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
? PROT_READ
@@ -635,9 +643,6 @@ read_file (int fildes, off_t offset, size_t maxsize,
}
else
{
- /* The parent is already loaded. Use it. */
- assert (maxsize != ~((size_t) 0));
-
map_address = parent->map_address;
}
}
--
1.8.3.1
7 years
[PATCH] libelf: Sanity check offset and size before trying to malloc and read data.
by Mark Wielaard
Bad sh_off or sh_size could trigger a bad malloc or read. Sanity check
the header values first before trying to malloc a huge buffer or reading
any data that will certainly fail.
https://bugzilla.redhat.com/show_bug.cgi?id=1387584
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/elf_getdata.c | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 35af786..89546ab 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-21 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_getdata.c (__libelf_set_rawdata_wrlock): Sanity check
+ offset and size before trying to malloc and read data.
+
2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index d1fafbf..97c503b 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -312,6 +312,17 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
}
else if (likely (elf->fildes != -1))
{
+ /* First see whether the information in the section header is
+ valid and it does not ask for too much. Check for unsigned
+ overflow. */
+ if (unlikely (offset > elf->maximum_size
+ || elf->maximum_size - offset < size))
+ {
+ /* Something is wrong. */
+ __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+ return 1;
+ }
+
/* We have to read the data from the file. Allocate the needed
memory. */
scn->rawdata_base = scn->rawdata.d.d_buf
--
1.8.3.1
7 years
[PATCH] libdw: Correct spelling of DW_LANG_PLI in dwarf.h.
by Mark Wielaard
The name used in the standard and other DWARF implementations for
Programming Language One, PL/I, is DW_LANG_PLI (not DW_LANG_PL1).
Fix usage in dwarf_aggregate_size.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
NEWS | 5 +++++
libdw/ChangeLog | 6 ++++++
libdw/dwarf.h | 4 ++--
libdw/dwarf_aggregate_size.c | 4 ++--
4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index 599970b..6adb76f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Version 0.168
+
+libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1).
+ Any existing sources using the old name will have to be updated.
+
Version 0.167
libasm: Add eBPF disassembler for EM_BPF files.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c2f25ea..01213c5 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2016-10-22 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf.h: Correct spelling of DW_LANG_PLI.
+ * dwarf_aggregate_size.c (array_size): Use correct spelling of
+ DW_LANG_PLI.
+
2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* dwarf_getpubnames.c: Remove sys/param.h include, add system.h.
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index b5c58d7..6354c39 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -1,5 +1,5 @@
/* This file defines standard DWARF types, structures, and macros.
- Copyright (C) 2000-2011, 2014 Red Hat, Inc.
+ Copyright (C) 2000-2011, 2014, 2016 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -582,7 +582,7 @@ enum
DW_LANG_C99 = 0x000c, /* ISO C:1999 */
DW_LANG_Ada95 = 0x000d, /* ISO Ada:1995 */
DW_LANG_Fortran95 = 0x000e, /* ISO Fortran 95 */
- DW_LANG_PL1 = 0x000f, /* ISO PL/1:1976 */
+ DW_LANG_PLI = 0x000f, /* ISO PL/1:1976 */
DW_LANG_ObjC = 0x0010, /* Objective-C */
DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */
DW_LANG_UPC = 0x0012, /* Unified Parallel C */
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index aaeb7ed..52ef006 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -1,5 +1,5 @@
/* Compute size of an aggregate type from DWARF.
- Copyright (C) 2010, 2014 Red Hat, Inc.
+ Copyright (C) 2010, 2014, 2016 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -127,7 +127,7 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
case DW_LANG_Fortran08:
case DW_LANG_Pascal83:
case DW_LANG_Modula2:
- case DW_LANG_PL1:
+ case DW_LANG_PLI:
lower = 1;
break;
--
1.8.3.1
7 years
Some DWARF5 work
by Mark Wielaard
Hi,
You might have seen that there is a draft of DWARF5 out now.
Summary of changes: http://dwarfstd.org/Dwarf5Std.php
DWARF5 public review pdf: http://dwarfstd.org/doc/DWARF5_Public_Review.pdf
Feedback needs to be given by end of next month. So I started looking
at it and pushed some patches to the mjw/DWARF5 branch. I don't have
a real plan yet. But I like to implement various things before end of
November to see whether the proposals make sense and are supportable.
Given that DWARF5 isn't final yet I probably won't push this to master
yet. Except for cleanups or stuff like dwarf_default_lower_bound that
can be supported without needing the prelimenary DWARF5 additions. We
could do a release next month/December. And add the new DWARF5 stuff
after that release.
Cheers,
Mark
7 years, 1 month
[PATCH 1/2] unstrip: Don't try to use unstripped .symtab with stripped .strtab
by Kevin Cernekee
Prematurely matching up the stripped and unstripped .strtab sections
in the "Match each debuginfo" loop can lead to a case where sec->outscn
gets populated for the stripped .strtab, which we normally want to
ignore. This causes the .strtab override in the "Make sure each main
file section" loop to be skipped, so the code winds up using indices
from the unstripped .symtab to look up strings in the stripped .strtab.
This returns incorrect strings for a little while, and then fails
catastrophically when it tries to read past the end of the (smaller)
stripped file's .strtab section:
eu-unstrip: invalid string offset in symbol [1589]
Fix this by adding logic to the "Match each debuginfo" loop to
treat the unstripped .strtab, .shstrtab, and .symtab sections
essentially the same way.
The new logic will break if the .strtab section shows up earlier than
the .symtab section. We will assume this never happens in practice.
Signed-off-by: Kevin Cernekee <cernekee(a)chromium.org>
---
src/ChangeLog | 7 ++++++-
src/unstrip.c | 12 ++++++------
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 68baa2e7f6bf..ee67cffcdadd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,9 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-22 Kevin Cernekee <cernekee(a)chromium.org>
+
+ * unstrip.c: Fix "invalid string offset" error caused by using the
+ unstripped .symtab with the stripped .strtab.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* arlib.c: Remove system.h include, add libeu.h include.
* arlib2.c: Remove sys/param.h include.
diff --git a/src/unstrip.c b/src/unstrip.c
index 3bf4b192b5db..cc3dcb26611a 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1363,6 +1363,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* Match each debuginfo section with its corresponding stripped section. */
bool check_prelink = false;
Elf_Scn *unstripped_symtab = NULL;
+ size_t unstripped_strndx = 0;
size_t alloc_avail = 0;
scn = NULL;
while ((scn = elf_nextscn (unstripped, scn)) != NULL)
@@ -1374,11 +1375,12 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (shdr->sh_type == SHT_SYMTAB)
{
unstripped_symtab = scn;
+ unstripped_strndx = shdr->sh_link;
continue;
}
const size_t ndx = elf_ndxscn (scn);
- if (ndx == unstripped_shstrndx)
+ if (ndx == unstripped_shstrndx || ndx == unstripped_strndx)
continue;
const char *name = get_section_name (ndx, shdr, shstrtab);
@@ -1485,13 +1487,11 @@ more sections in stripped file than debug file -- arguments reversed?"));
}
if (unstripped_symtab != NULL && stripped_symtab != NULL
- && secndx == stripped_symtab->shdr.sh_link)
+ && secndx == stripped_symtab->shdr.sh_link
+ && unstripped_strndx != 0)
{
/* ... nor its string table. */
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
- ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
- ndx_section[secndx - 1] = shdr->sh_link;
+ ndx_section[secndx - 1] = unstripped_strndx;
continue;
}
--
2.8.3
7 years, 1 month
[PATCH 1/2] unstrip: Don't try to use unstripped .symtab with stripped .strtab
by Kevin Cernekee
Prematurely matching up the stripped and unstripped .strtab sections
in the "Match each debuginfo" loop can lead to a case where sec->outscn
gets populated for the stripped .strtab, which we normally want to
ignore. This causes the .strtab override in the "Make sure each main
file section" loop to be skipped, so the code winds up using indices
from the unstripped .symtab to look up strings in the stripped .strtab.
This returns incorrect strings for a little while, and then fails
catastrophically when it tries to read past the end of the (smaller)
stripped file's .strtab section:
eu-unstrip: invalid string offset in symbol [1589]
Fix this by adding logic to the "Match each debuginfo" loop to
treat the unstripped .strtab, .shstrtab, and .symtab sections
essentially the same way.
The new logic will break if the .strtab section shows up earlier than
the .symtab section. We will assume this never happens in practice.
Signed-off-by: Kevin Cernekee <cernekee(a)chromium.org>
---
src/ChangeLog | 7 ++++++-
src/unstrip.c | 12 ++++++------
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 68baa2e7f6bf..ee67cffcdadd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,9 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
+2016-10-22 Kevin Cernekee <cernekee(a)chromium.org>
+
+ * unstrip.c: Fix "invalid string offset" error caused by using the
+ unstripped .symtab with the stripped .strtab.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
* arlib.c: Remove system.h include, add libeu.h include.
* arlib2.c: Remove sys/param.h include.
diff --git a/src/unstrip.c b/src/unstrip.c
index 3bf4b192b5db..cc3dcb26611a 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1363,6 +1363,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* Match each debuginfo section with its corresponding stripped section. */
bool check_prelink = false;
Elf_Scn *unstripped_symtab = NULL;
+ size_t unstripped_strndx = 0;
size_t alloc_avail = 0;
scn = NULL;
while ((scn = elf_nextscn (unstripped, scn)) != NULL)
@@ -1374,11 +1375,12 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (shdr->sh_type == SHT_SYMTAB)
{
unstripped_symtab = scn;
+ unstripped_strndx = shdr->sh_link;
continue;
}
const size_t ndx = elf_ndxscn (scn);
- if (ndx == unstripped_shstrndx)
+ if (ndx == unstripped_shstrndx || ndx == unstripped_strndx)
continue;
const char *name = get_section_name (ndx, shdr, shstrtab);
@@ -1485,13 +1487,11 @@ more sections in stripped file than debug file -- arguments reversed?"));
}
if (unstripped_symtab != NULL && stripped_symtab != NULL
- && secndx == stripped_symtab->shdr.sh_link)
+ && secndx == stripped_symtab->shdr.sh_link
+ && unstripped_strndx != 0)
{
/* ... nor its string table. */
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
- ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
- ndx_section[secndx - 1] = shdr->sh_link;
+ ndx_section[secndx - 1] = unstripped_strndx;
continue;
}
--
2.8.3
7 years, 1 month
[PATCH] Allow to disable components
by Akihiko Odaki
Signed-off-by: Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
---
Makefile.am | 27 +++++++++++++--
configure.ac | 107 ++++++++++++++++++++++++++++++++++++++++++-----------------
lib/system.h | 9 ++++-
3 files changed, 110 insertions(+), 33 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2ff444e..7abd95f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,8 +27,31 @@ AM_MAKEFLAGS = --no-print-directory
pkginclude_HEADERS = version.h
# Add doc back when we have some real content.
-SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libcpu libasm \
- backends src po tests
+SUBDIRS = config m4 libelf po tests
+
+if ENABLE_LIBEU
+SUBDIRS += lib
+endif
+
+if ENABLE_LIBEBL
+SUBDIRS += libebl
+endif
+
+if ENABLE_LIBDW
+SUBDIRS += libdwelf libdwfl libdw
+endif
+
+if ENABLE_LIBEBL
+SUBDIRS += libcpu backends
+endif
+
+if ENABLE_LIBASM
+SUBDIRS += libasm
+endif
+
+if ENABLE_TOOLS
+SUBDIRS += src
+endif
EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
COPYING COPYING-GPLV2 COPYING-LGPLV3
diff --git a/configure.ac b/configure.ac
index e5503f1..cf6a59c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -214,6 +214,28 @@ AS_HELP_STRING([--enable-tests-rpath],[build $ORIGIN-using rpath into tests]),
[tests_use_rpath=$enableval], [tests_use_rpath=no])
AM_CONDITIONAL(TESTS_RPATH, test "$tests_use_rpath" = yes)
+AC_ARG_ENABLE([tools],
+AS_HELP_STRING([--disable-tools], [do not build tools]),
+ [tools=$enableval], [tools=yes])
+AM_CONDITIONAL(ENABLE_TOOLS, test "$tools" = yes)
+
+AC_ARG_ENABLE([libasm],
+AS_HELP_STRING([--disable-libasm], [do not build libasm]),
+ [libasm=$enableval], [libasm=yes])
+AM_CONDITIONAL(ENABLE_LIBASM, test "$libasm" = yes)
+
+AC_ARG_ENABLE([libdw],
+AS_HELP_STRING([--disable-libdw], [do not build libdw]),
+ [libdw=$enableval], [libdw=yes])
+AM_CONDITIONAL(ENABLE_LIBDW, test "$libdw" = yes)
+
+AC_ARG_ENABLE([libebl],
+AS_HELP_STRING([--disable-libebl], [do not build libebl]),
+ [libebl=$enableval], [libebl=yes])
+AM_CONDITIONAL(ENABLE_LIBEBL, test "$libebl" = yes)
+
+AM_CONDITIONAL(ENABLE_LIBEU, test "$libdw" = yes -o "$libebl" = yes)
+
LIBEBL_SUBDIR="$PACKAGE"
AC_ARG_ENABLE([libebl-subdir],
AS_HELP_STRING([--enable-libebl-subdir=DIR],
@@ -306,30 +328,32 @@ CFLAGS="$old_CFLAGS"])
AM_CONDITIONAL(HAVE_NULL_DEREFERENCE_WARNING,
[test "x$ac_cv_null_dereference" != "xno"])
-dnl Check if we have argp available from our libc
-AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#include <argp.h>],
- [int argc=1; char *argv[]={"test"}; argp_parse(0,argc,&argv,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")
+if test "$tools" = yes ; then
+ dnl Check if we have argp available from our libc
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <argp.h>],
+ [int argc=1; char *argv[]={"test"}; argp_parse(0,argc,&argv,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="-largp"
+ argp_LDADD=""
fi
-else
- argp_LDADD=""
+ AC_SUBST([argp_LDADD])
fi
-AC_SUBST([argp_LDADD])
dnl Check if we have <linux/bpf.h> for EM_BPF disassembly.
AC_CHECK_HEADERS(linux/bpf.h)
@@ -348,29 +372,47 @@ dnl ELF library.
AC_CONFIG_FILES([libelf/Makefile])
dnl Higher-level ELF support library.
-AC_CONFIG_FILES([libebl/Makefile])
+if test "$libebl" = yes ; then
+ AC_CONFIG_FILES([libebl/Makefile])
+fi
dnl DWARF-ELF Lower-level Functions support library.
-AC_CONFIG_FILES([libdwelf/Makefile])
+if test "$libdw" = yes; then
+ AC_CONFIG_FILES([libdwelf/Makefile])
+fi
dnl DWARF library.
-AC_CONFIG_FILES([libdw/Makefile])
+if test "$libdw" = yes; then
+ AC_CONFIG_FILES([libdw/Makefile])
+fi
dnl Higher-level DWARF support library.
-AC_CONFIG_FILES([libdwfl/Makefile])
+if test "$libdw" = yes; then
+ AC_CONFIG_FILES([libdwfl/Makefile])
+fi
dnl CPU handling library.
-AC_CONFIG_FILES([libcpu/Makefile])
+if test "$libebl" = yes; then
+ AC_CONFIG_FILES([libcpu/Makefile])
+fi
dnl Assembler library.
-AM_CONDITIONAL(HAVE_LIBASM, true)dnl Used in tests/Makefile.am, which see.
-AC_CONFIG_FILES([libasm/Makefile])
+AM_CONDITIONAL(HAVE_LIBASM, test "$libasm" = yes)dnl Used in tests/Makefile.am, which see.
+if test "$libasm" = yes; then
+ AC_CONFIG_FILES([libasm/Makefile])
+fi
dnl CPU-specific backend libraries.
-AC_CONFIG_FILES([backends/Makefile])
+if test "$libebl" = yes; then
+ AC_CONFIG_FILES([backends/Makefile])
+fi
dnl Tools.
-AC_CONFIG_FILES([src/Makefile po/Makefile.in])
+if test "$tools" = yes ; then
+ AC_CONFIG_FILES([src/Makefile])
+fi
+
+AC_CONFIG_FILES([po/Makefile.in])
dnl Test suite.
AM_CONDITIONAL(STANDALONE, false)dnl Used in tests/Makefile.am, which see.
@@ -384,6 +426,11 @@ AC_CONFIG_FILES([config/libelf.pc config/libdw.pc])
AC_SUBST(USE_NLS, yes)
AM_PO_SUBDIRS
+AH_TEMPLATE([ENABLE_TOOLS], [Defined if the tools will be built.])
+if test "$tools" = yes ; then
+ AC_DEFINE([ENABLE_TOOLS])
+fi
+
dnl Appended to the config.h file.
dnl We hide all kinds of configuration magic in lib/eu-config.h.
AH_BOTTOM([#include <eu-config.h>])
diff --git a/lib/system.h b/lib/system.h
index f31cfd0..6391dec 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -29,7 +29,12 @@
#ifndef LIB_SYSTEM_H
#define LIB_SYSTEM_H 1
-#include <argp.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#ifdef ENABLE_TOOLS
+# include <argp.h>
+#endif
#include <stddef.h>
#include <stdint.h>
#include <endian.h>
@@ -126,6 +131,7 @@ pread_retry (int fd, void *buf, size_t len, off_t off)
}
+#ifdef ENABLE_TOOLS
/* 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
@@ -136,6 +142,7 @@ pread_retry (int fd, void *buf, size_t len, off_t off)
__asm ("argp_program_version_hook")
#define ARGP_PROGRAM_BUG_ADDRESS_DEF \
const char *const apba__ __asm ("argp_program_bug_address")
+#endif
/* The demangler from libstdc++. */
--
2.10.0
7 years, 1 month
[PATCH] Do not depend on non-POSIX features
by Akihiko Odaki
Signed-off-by: Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
---
configure.ac | 3 +++
lib/fixedsizehash.h | 6 ++++++
lib/system.h | 9 +++++++++
libelf/elf_getarsym.c | 8 ++++++++
libelf/elf_strptr.c | 30 ++++++++++++++++++++++--------
libelf/libelfP.h | 4 ++++
6 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index e5503f1..feb2ed5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -245,6 +245,9 @@ zip_LIBS="$LIBS"
LIBS="$save_LIBS"
AC_SUBST([zip_LIBS])
+AC_CHECK_DECLS([memrchr rawmemchr])
+AC_CHECK_DECLS(powerof2, , , [#include <sys/param.h>])
+
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/lib/fixedsizehash.h b/lib/fixedsizehash.h
index 06ce6a2..762ebaa 100644
--- a/lib/fixedsizehash.h
+++ b/lib/fixedsizehash.h
@@ -35,7 +35,13 @@
#include <system.h>
+#ifdef __CONCAT
#define CONCAT(t1,t2) __CONCAT (t1,t2)
+#else
+#define STROF(t2) t2
+#define CONCAT_EXPANDED(t1,t2) t1 ## t2
+#define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
+#endif
/* Before including this file the following macros must be defined:
diff --git a/lib/system.h b/lib/system.h
index f31cfd0..72005d4 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -30,6 +30,7 @@
#define LIB_SYSTEM_H 1
#include <argp.h>
+#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <endian.h>
@@ -68,6 +69,14 @@ extern int crc32_file (int fd, uint32_t *resp);
#define gettext_noop(Str) Str
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(expression) \
+ ({ ssize_t __res; \
+ do \
+ __res = expression; \
+ while (__res == -1 && errno == EINTR); \
+ __res; });
+#endif
static inline ssize_t __attribute__ ((unused))
pwrite_retry (int fd, const void *buf, size_t len, off_t off)
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
index 65c67cc..d5f0ba4 100644
--- a/libelf/elf_getarsym.c
+++ b/libelf/elf_getarsym.c
@@ -297,7 +297,15 @@ elf_getarsym (Elf *elf, size_t *ptr)
arsym[cnt].as_off = (*u32)[cnt];
arsym[cnt].as_hash = _dl_elf_hash (str_data);
+#if HAVE_DECL_RAWMEMCHR
str_data = rawmemchr (str_data, '\0') + 1;
+#else
+ char c;
+ do {
+ c = *str_data;
+ str_data++;
+ } while (c);
+#endif
}
/* At the end a special entry. */
diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c
index ea21045..e72a3a3 100644
--- a/libelf/elf_strptr.c
+++ b/libelf/elf_strptr.c
@@ -32,6 +32,7 @@
#endif
#include <libelf.h>
+#include <stdbool.h>
#include <stddef.h>
#include "libelfP.h"
@@ -52,6 +53,22 @@ get_zdata (Elf_Scn *strscn)
return zdata;
}
+static bool validate_str (const char *str, size_t from, size_t to)
+{
+#if HAVE_DECL_MEMRCHR
+ return memrchr (&str[from], '\0', to - from) != NULL;
+#else
+ do {
+ if (to <= from)
+ return false;
+
+ to--;
+ } while (str[to]);
+
+ return true;
+#endif
+}
+
char *
elf_strptr (Elf *elf, size_t idx, size_t offset)
{
@@ -166,8 +183,7 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
{
/* Make sure the string is NUL terminated. Start from the end,
which very likely is a NUL char. */
- if (likely (memrchr (&strscn->zdata_base[offset],
- '\0', sh_size - offset) != NULL))
+ if (likely (validate_str (strscn->zdata_base, offset, sh_size)))
result = &strscn->zdata_base[offset];
else
__libelf_seterrno (ELF_E_INVALID_INDEX);
@@ -185,8 +201,7 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
/* Make sure the string is NUL terminated. Start from the end,
which very likely is a NUL char. */
- if (likely (memrchr (&strscn->rawdata_base[offset],
- '\0', sh_size - offset) != NULL))
+ if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
result = &strscn->rawdata_base[offset];
else
__libelf_seterrno (ELF_E_INVALID_INDEX);
@@ -203,10 +218,9 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
{
/* Make sure the string is NUL terminated. Start from
the end, which very likely is a NUL char. */
- if (likely (memrchr ((char *) dl->data.d.d_buf
- + (offset - dl->data.d.d_off), '\0',
- (dl->data.d.d_size
- - (offset - dl->data.d.d_off))) != NULL))
+ if (likely (validate_str ((char *) dl->data.d.d_buf,
+ offset - dl->data.d.d_off,
+ dl->data.d.d_size)))
result = ((char *) dl->data.d.d_buf
+ (offset - dl->data.d.d_off));
else
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 4459982..88e5c13 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -46,6 +46,10 @@
/* gettext helper macros. */
#define _(Str) dgettext ("elfutils", Str)
+#if !HAVE_DECL_POWEROF2
+#define powerof2(x) (((x) & ((x) - 1)) == 0)
+#endif
+
/* Helper Macros to write 32 bit and 64 bit functions. */
#define __elfw2_(Bits, Name) __elf##Bits##_##Name
--
2.10.0
7 years, 1 month
[PATCH] Allow to build for non-ELF target
by Akihiko Odaki
Signed-off-by: Akihiko Odaki <akihiko.odaki.4i(a)stu.hosei.ac.jp>
---
backends/Makefile.am | 5 ++++-
configure.ac | 13 ++++++++++++-
lib/eu-config.h | 4 ++++
libdw/Makefile.am | 5 ++++-
libelf/Makefile.am | 5 ++++-
5 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/backends/Makefile.am b/backends/Makefile.am
index b553ec3..eed46d7 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -31,6 +31,9 @@ include $(top_srcdir)/config/eu.am
AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
-I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
+if ELF
+AM_LDFLAGS = -Wl,-z,defs
+endif
modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
tilegx m68k bpf
@@ -136,7 +139,7 @@ libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw)
$(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \
-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
-Wl,--version-script,$(@:.so=.map) \
- -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
+ -Wl,--as-needed $(libelf) $(libdw)
@$(textrel_check)
libebl_i386.so: $(cpu_i386)
diff --git a/configure.ac b/configure.ac
index e5503f1..fa731c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,13 +121,24 @@ CFLAGS="$old_CFLAGS"])
AS_IF([test "x$ac_cv_c99" != xyes],
AC_MSG_ERROR([gcc with GNU99 support required]))
+AC_CACHE_CHECK([the output format of the linker is ELF], ac_cv_elf,[dnl
+case `$CC -Wl,-print-output-format -nodefaultlibs -nostartfiles` in
+ elf*) ac_cv_elf=yes ;;
+ *) ac_cv_elf=no ;;
+esac])
+AM_CONDITIONAL(ELF, test "$ac_cv_elf" = yes)
+AS_IF(test "$ac_cv_elf" = yes, elf_val=0, elf_val=1)
+AC_SUBST(ELF, $elf_val)
+AH_TEMPLATE([ELF], [whether the output format of the linker is ELF])
+
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.
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
CFLAGS="-fPIC $CFLAGS"
-LDFLAGS="-shared -Wl,-z,defs,-z,relro $LDFLAGS"
+LDFLAGS="-shared $LDFLAGS"
+AS_IF([test "$ac_cv_elf" = yes], [LDFLAGS="-Wl,-z,defs,-z,relro $LDFLAGS"])
AC_LINK_IFELSE([dnl
AC_LANG_PROGRAM([[#include <stdlib.h>
#undef __thread
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 400cdc6..5f1dda3 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 ELF
#define attribute_hidden \
__attribute__ ((visibility ("hidden")))
+#else
+#define attribute_hidden
+#endif
/* Define ALLOW_UNALIGNED if the architecture allows operations on
unaligned memory locations. */
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 082d96c..a637e18 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -102,13 +102,16 @@ endif
libdw_pic_a_SOURCES =
am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
+if ELF
+libdw_so_LDFLAGS = -Wl,-z,defs
+endif
libdw_so_SOURCES =
libdw.so$(EXEEXT): $(srcdir)/libdw.map libdw_pic.a ../libdwelf/libdwelf_pic.a \
../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
../libelf/libelf.so
# The rpath is necessary for libebl because its $ORIGIN use will
# not fly in a setuid executable that links in libdw.
- $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+ $(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION) \
-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 167a832..41302c3 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -100,11 +100,14 @@ if USE_LOCKS
libelf_so_LDLIBS += -lpthread
endif
+if ELF
+libelf_so_LDFLAGS = -Wl,-z,defs,-z,relro
+endif
libelf_so_SOURCES =
libelf.so$(EXEEXT): libelf_pic.a libelf.map
$(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \
- -Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS)
+ -Wl,--soname,$@.$(VERSION) $(libelf_so_LDLIBS)
@$(textrel_check)
$(AM_V_at)ln -fs $@ $@.$(VERSION)
--
2.10.0
7 years, 1 month