aboutsummaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog72
-rw-r--r--libelf/common.h2
-rw-r--r--libelf/elf32_fsize.c12
-rw-r--r--libelf/elf32_updatefile.c70
-rw-r--r--libelf/elf32_updatenull.c5
-rw-r--r--libelf/elf32_xlatetof.c16
-rw-r--r--libelf/elf32_xlatetom.c16
-rw-r--r--libelf/elf_begin.c24
-rw-r--r--libelf/elf_compress.c33
-rw-r--r--libelf/elf_getdata.c26
-rw-r--r--libelf/elf_getdata_rawchunk.c5
-rw-r--r--libelf/elf_newdata.c2
-rw-r--r--libelf/elf_version.c23
-rw-r--r--libelf/gelf_fsize.c13
-rw-r--r--libelf/gelf_xlate.c10
-rw-r--r--libelf/libelfP.h47
-rw-r--r--libelf/nlist.c5
17 files changed, 172 insertions, 209 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index b89e93fe..a2e4ee90 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,75 @@
+2019-02-24 Mark Wielaard <mark@klomp.org>
+
+ * gelf_xlate.c (__elf_xfctstof): Remove alias.
+ * libelfP.h (__elf_xfctstof): Remove definition.
+
+2019-02-24 Mark Wielaard <mark@klomp.org>
+
+ * elf32_fsize.c (local_strong_alias): Remove definition.
+ (msize): Remove alias.
+ * libelfP.h (__elf32_msize): Remove definition.
+ (__elf64_msize): Likewise.
+
+2019-02-21 Mark Wielaard <mark@klomp.org>
+
+ * common.h (determine_kind): Only accept EV_CURRENT.
+ * elf32_fsize.c (fsize): Just check version is EV_CURRENT.
+ Use __libelf_type_size without version dimension.
+ * elf32_updatefile.c (updatemmap): Define fctp from __elf_xfctstom
+ without version dimension.
+ (updatefile): Likewise.
+ * elf32_updatenull.c (default_ehdr): Check e_version is EV_CURRENT.
+ (updatenull_wrlock): Check d_version is EV_CURRENT.
+ (elf32_xlatetof): Likewise. And get recsize without version
+ dimension from __elf_xfctstom.
+ (elf32_xlatetom): Likewise.
+ * elf_begin.c (elf_begin): Check __libelf_version is EV_CURRENT.
+ * elf_compress.c (__libelf_reset_rawdata): Set d_version to
+ EV_CURRENT.
+ * elf_getdata.c (shtype_map): Remove version dimension.
+ (__libelf_type_aligns): Likewise.
+ (__libelf_data_type): Use shtype_map without version dimension.
+ (convert_data): Remove unused version argument. Get fp from
+ __elf_xfctstom without version dimensions.
+ (__libelf_set_data_list_rdlock): Call convert_data without version.
+ * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Call __elfcfctstom
+ conversion function without version dimensions. Set d_version to
+ EV_CURRENT.
+ * elf_newdata.c (elf_newdata): Set d_version to EV_CURRENT.
+ * elf_version.c (__libelf_version_initialized): Removed.
+ (__libelf_version): Initialized to EV_NONE.
+ (elf_version): Always return EV_CURRENT for EV_NONE version.
+ Only accept (and return) EV_CURRENT as version.
+ * gelf_fsize.c (__libelf_type_sizes): Remove version dimension.
+ (gelf_fsize): Only accept EV_CURRENT as version.
+ Use __libelf_type_sizes without version dimension.
+ * gelf_xlate.c (__elf_xftstom): Remove version dimensions.
+ * libelfP.h (__elf_xfctstom): Defined without version dimensions.
+ (__elf_xfctstof): Likewise.
+ (__libelf_type_sizes): Define without version dimension.
+ (elf_typesize): Define using __libelf_type_sizes without version
+ dimension.
+ (__libelf_version_initialized): Remove definition.
+ (__libelf_version): Add definition.
+ (LIBELF_EV_IDX): Removed define.
+ (__libelf_type_aligns): Remove version dimension.
+ * nlist.c (nlist): Call elf_version unconditionally.
+
+2019-02-19 Mark Wielaard <mark@klomp.org>
+
+ * elf_compress.c (do_deflate_cleanup): Remove ei_data argument,
+ check cdatap is not NULL before calling free.
+ (deflate_cleanup): Add cdata as argument.
+ (__libelf_compress): Also check whether the d_size is not zero
+ before converting data. Call deflate_cleanup with an extra
+ argument depending on whether there is converted data to free.
+ Always allocate allocate at least one byte for buf_out.
+
+2019-02-14 Mark Wielaard <mark@klomp.org>
+
+ * elf_begin.c (read_long_names): Make sure ar_size is properly
+ terminated. Sanity check len early if we can.
+
2019-01-18 Mark Wielaard <mark@klomp.org>
* Makefile.am (INSTALL_ELFH): Add elf.h to include_HEADERS when
diff --git a/libelf/common.h b/libelf/common.h
index 744f1bb8..62486903 100644
--- a/libelf/common.h
+++ b/libelf/common.h
@@ -56,7 +56,7 @@ determine_kind (void *buf, size_t len)
if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM
&& data > ELFDATANONE && data < ELFDATANUM
- && version > EV_NONE && version < EV_NUM)
+ && version == EV_CURRENT)
return ELF_K_ELF;
}
diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c
index fddae91e..139f4a91 100644
--- a/libelf/elf32_fsize.c
+++ b/libelf/elf32_fsize.c
@@ -44,7 +44,7 @@ elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count, unsigned int version)
{
/* We do not have differences between file and memory sizes. Better
not since otherwise `mmap' would not work. */
- if (unlikely (version == EV_NONE) || unlikely (version >= EV_NUM))
+ if (unlikely (version != EV_CURRENT))
{
__libelf_seterrno (ELF_E_UNKNOWN_VERSION);
return 0;
@@ -56,13 +56,5 @@ elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count, unsigned int version)
return 0;
}
-#if EV_NUM != 2
- return (count
- * __libelf_type_sizes[version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
-#else
- return (count
- * __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
-#endif
+ return (count * __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
}
-#define local_strong_alias(n1, n2) strong_alias (n1, n2)
-local_strong_alias (elfw2(LIBELFBITS, fsize), __elfw2(LIBELFBITS, msize))
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index 284bacc9..2899c6fb 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -143,13 +143,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
if (unlikely (change_bo))
{
/* Today there is only one version of the ELF header. */
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
/* Do the real work. */
(*fctp) ((char *) elf->map_address + elf->start_offset, ehdr,
@@ -189,13 +184,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
if (unlikely (change_bo))
{
/* Today there is only one version of the ELF header. */
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
/* Do the real work. */
(*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff,
@@ -238,12 +228,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
+ ehdr->e_shoff);
char *const shdr_end = shdr_start + shnum * ehdr->e_shentsize;
-#if EV_NUM != 2
- xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
-#else
-# undef shdr_fctp
-# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
-#endif
+#undef shdr_fctp
+#define shdr_fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
#define shdr_dest ((ElfW2(LIBELFBITS,Shdr) *) shdr_start)
/* Get all sections into the array and sort them. */
@@ -358,13 +344,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
&& dl->data.d.d_size != 0
&& dl->data.d.d_type != ELF_T_BYTE))
{
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
size_t align;
align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS),
@@ -559,13 +540,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (unlikely (change_bo))
{
/* Today there is only one version of the ELF header. */
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
/* Write the converted ELF header in a temporary buffer. */
(*fctp) (&tmp_ehdr, ehdr, sizeof (ElfW2(LIBELFBITS,Ehdr)), 1);
@@ -618,13 +594,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (unlikely (change_bo))
{
/* Today there is only one version of the ELF header. */
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
/* Allocate sufficient memory. */
tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *)
@@ -679,12 +650,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
return 1;
off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
-#if EV_NUM != 2
- xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
-#else
-# undef shdr_fctp
-# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
-#endif
+#undef shdr_fctp
+#define shdr_fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
ElfW2(LIBELFBITS,Shdr) *shdr_data;
ElfW2(LIBELFBITS,Shdr) *shdr_data_mem = NULL;
@@ -769,13 +736,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (unlikely (change_bo))
{
-#if EV_NUM != 2
- xfct_t fctp;
- fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
-#else
-# undef fctp
-# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
-#endif
+#undef fctp
+#define fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
buf = tmpbuf;
if (dl->data.d.d_size > MAX_TMPBUF)
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index 3e9ef61b..2ce6a597 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -89,7 +89,7 @@ ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
ehdr->e_version = EV_CURRENT;
elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
}
- else if (unlikely (ehdr->e_version >= EV_NUM))
+ else if (unlikely (ehdr->e_version != EV_CURRENT))
{
__libelf_seterrno (ELF_E_UNKNOWN_VERSION);
return 1;
@@ -280,8 +280,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
&& scn->rawdata.d.d_buf != NULL)
data = &scn->rawdata.d;
- if (unlikely (data->d_version == EV_NONE)
- || unlikely (data->d_version >= EV_NUM))
+ if (unlikely (data->d_version != EV_CURRENT))
{
__libelf_seterrno (ELF_E_UNKNOWN_VERSION);
return -1;
diff --git a/libelf/elf32_xlatetof.c b/libelf/elf32_xlatetof.c
index ac4eaf40..082d833f 100644
--- a/libelf/elf32_xlatetof.c
+++ b/libelf/elf32_xlatetof.c
@@ -50,11 +50,7 @@ elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src,
type. This means, whether there is an integer number of records.
Note that for this implementation the memory and file size of the
data types are identical. */
-#if EV_NUM != 2
- size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
-#else
- size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
-#endif
+ size_t recsize = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
if (src->d_size % recsize != 0)
{
@@ -97,15 +93,7 @@ elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src,
else
{
xfct_t fctp;
-
- /* Get a pointer to the transformation functions. The `#ifdef' is
- a small optimization since we don't anticipate another ELF
- version and so would waste "precious" code. */
-#if EV_NUM != 2
- fctp = __elf_xfctstom[dest->d_version - 1][src->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
-#else
- fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
-#endif
+ fctp = __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
/* Do the real work. */
(*fctp) (dest->d_buf, src->d_buf, src->d_size, 1);
diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c
index 3b94cac7..cb0bb8d5 100644
--- a/libelf/elf32_xlatetom.c
+++ b/libelf/elf32_xlatetom.c
@@ -50,11 +50,7 @@ elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src,
type. This means, whether there is an integer number of records.
Note that for this implementation the memory and file size of the
data types are identical. */
-#if EV_NUM != 2
- size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
-#else
- size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
-#endif
+ size_t recsize = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
/* We shouldn't require integer number of records when processing
@@ -102,15 +98,7 @@ elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src,
else
{
xfct_t fctp;
-
- /* Get a pointer to the transformation functions. The `#ifdef' is
- a small optimization since we don't anticipate another ELF
- version and so would waste "precious" code. */
-#if EV_NUM != 2
- fctp = __elf_xfctstom[src->d_version - 1][dest->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
-#else
- fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
-#endif
+ fctp = __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
/* Do the real work. */
(*fctp) (dest->d_buf, src->d_buf, src->d_size, 0);
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index b20ab4f3..5d095ff0 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -736,7 +736,17 @@ read_long_names (Elf *elf)
hdr = &hdrm;
}
- len = atol (hdr->ar_size);
+ /* The ar_size is given as a fixed size decimal string, right
+ padded with spaces. Make sure we read it properly even if
+ there is no terminating space. */
+ char buf[sizeof (hdr->ar_size) + 1];
+ const char *string = hdr->ar_size;
+ if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
+ {
+ *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
+ string = buf;
+ }
+ len = atol (string);
if (memcmp (hdr->ar_name, "// ", 16) == 0)
break;
@@ -744,6 +754,13 @@ read_long_names (Elf *elf)
offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
}
+ /* Sanity check len early if we can. */
+ if (elf->map_address != NULL)
+ {
+ if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
+ return NULL;
+ }
+
/* Due to the stupid format of the long name table entry (which are not
NUL terminted) we have to provide an appropriate representation anyhow.
Therefore we always make a copy which has the appropriate form. */
@@ -754,8 +771,6 @@ read_long_names (Elf *elf)
if (elf->map_address != NULL)
{
- if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
- goto too_much;
/* Simply copy it over. */
elf->state.ar.long_names = (char *) memcpy (newp,
elf->map_address + offset
@@ -769,7 +784,6 @@ read_long_names (Elf *elf)
+ sizeof (struct ar_hdr))
!= len))
{
- too_much:
/* We were not able to read all data. */
free (newp);
elf->state.ar.long_names = NULL;
@@ -1094,7 +1108,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
{
Elf *retval;
- if (unlikely (! __libelf_version_initialized))
+ if (unlikely (__libelf_version != EV_CURRENT))
{
/* Version wasn't set so far. */
__libelf_seterrno (ELF_E_NO_VERSION);
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index be9eeaba..244467b5 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -44,17 +44,17 @@
/* Cleanup and return result. Don't leak memory. */
static void *
do_deflate_cleanup (void *result, z_stream *z, void *out_buf,
- int ei_data, Elf_Data *cdatap)
+ Elf_Data *cdatap)
{
deflateEnd (z);
free (out_buf);
- if (ei_data != MY_ELFDATA)
+ if (cdatap != NULL)
free (cdatap->d_buf);
return result;
}
-#define deflate_cleanup(result) \
- do_deflate_cleanup(result, &z, out_buf, ei_data, &cdata)
+#define deflate_cleanup(result, cdata) \
+ do_deflate_cleanup(result, &z, out_buf, cdata)
/* Given a section, uses the (in-memory) Elf_Data to extract the
original data size (including the given header size) and data
@@ -127,7 +127,8 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
{
/* Convert to raw if different endianess. */
cdata = *data;
- if (ei_data != MY_ELFDATA)
+ bool convert = ei_data != MY_ELFDATA && data->d_size > 0;
+ if (convert)
{
/* Don't do this conversion in place, we might want to keep
the original data around, caller decides. */
@@ -135,10 +136,10 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
if (cdata.d_buf == NULL)
{
__libelf_seterrno (ELF_E_NOMEM);
- return deflate_cleanup (NULL);
+ return deflate_cleanup (NULL, NULL);
}
if (gelf_xlatetof (scn->elf, &cdata, data, ei_data) == NULL)
- return deflate_cleanup (NULL);
+ return deflate_cleanup (NULL, &cdata);
}
z.avail_in = cdata.d_size;
@@ -164,7 +165,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
if (zrc == Z_STREAM_ERROR)
{
__libelf_seterrno (ELF_E_COMPRESS_ERROR);
- return deflate_cleanup (NULL);
+ return deflate_cleanup (NULL, convert ? &cdata : NULL);
}
used += (out_size - used) - z.avail_out;
@@ -172,7 +173,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
compression forced and we are using more compressed data
than original data. */
if (!force && flush == Z_FINISH && used >= *orig_size)
- return deflate_cleanup ((void *) -1);
+ return deflate_cleanup ((void *) -1, convert ? &cdata : NULL);
if (z.avail_out == 0)
{
@@ -180,7 +181,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
if (bigger == NULL)
{
__libelf_seterrno (ELF_E_NOMEM);
- return deflate_cleanup (NULL);
+ return deflate_cleanup (NULL, convert ? &cdata : NULL);
}
out_buf = bigger;
out_size += block;
@@ -188,7 +189,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
}
while (z.avail_out == 0); /* Need more output buffer. */
- if (ei_data != MY_ELFDATA)
+ if (convert)
{
free (cdata.d_buf);
cdata.d_buf = NULL;
@@ -200,7 +201,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
if (zrc != Z_OK)
{
__libelf_seterrno (ELF_E_COMPRESS_ERROR);
- return deflate_cleanup (NULL);
+ return deflate_cleanup (NULL, NULL);
}
*new_size = used;
@@ -220,7 +221,11 @@ __libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
return NULL;
}
- void *buf_out = malloc (size_out);
+ /* Malloc might return NULL when requestion zero size. This is highly
+ unlikely, it would only happen when the compression was forced.
+ But we do need a non-NULL buffer to return and set as result.
+ Just make sure to always allocate at least 1 byte. */
+ void *buf_out = malloc (size_out ?: 1);
if (unlikely (buf_out == NULL))
{
__libelf_seterrno (ELF_E_NOMEM);
@@ -308,7 +313,7 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
{
/* This is the new raw data, replace and possibly free old data. */
scn->rawdata.d.d_off = 0;
- scn->rawdata.d.d_version = __libelf_version;
+ scn->rawdata.d.d_version = EV_CURRENT;
scn->rawdata.d.d_buf = buf;
scn->rawdata.d.d_size = size;
scn->rawdata.d.d_align = align;
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 639a798e..40fe1694 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -50,10 +50,8 @@
: 0))
/* Associate section types with libelf types. */
-static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
+static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] =
{
- [EV_CURRENT - 1] =
- {
[SHT_SYMTAB] = ELF_T_SYM,
[SHT_RELA] = ELF_T_RELA,
[SHT_HASH] = ELF_T_WORD,
@@ -73,11 +71,10 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
[TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
[TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
[TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
- }
};
/* Associate libelf types with their internal alignment requirements. */
-const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
{
# define TYPE_ALIGNS(Bits) \
{ \
@@ -108,11 +105,8 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
[ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)), \
[ELF_T_NHDR8] = 8 /* Special case for GNU Property note. */ \
}
- [EV_CURRENT - 1] =
- {
[ELFCLASS32 - 1] = TYPE_ALIGNS (32),
[ELFCLASS64 - 1] = TYPE_ALIGNS (64),
- }
# undef TYPE_ALIGNS
};
@@ -131,7 +125,7 @@ __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
}
else
{
- Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)];
+ Elf_Type t = shtype_map[TYPEIDX (sh_type)];
/* Special case for GNU Property notes. */
if (t == ELF_T_NHDR && align == 8)
t = ELF_T_NHDR8;
@@ -141,7 +135,7 @@ __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
/* Convert the data in the current section. */
static void
-convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
+convert_data (Elf_Scn *scn, int eclass,
int data, size_t size, Elf_Type type)
{
const size_t align = __libelf_type_align (eclass, type);
@@ -195,11 +189,7 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
}
/* Get the conversion function. */
-#if EV_NUM != 2
- fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
-#else
- fp = __elf_xfctstom[0][0][eclass - 1][type];
-#endif
+ fp = __elf_xfctstom[eclass - 1][type];
fp (scn->data_base, rawdata_source, size, 0);
@@ -285,14 +275,14 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
}
else
{
- Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+ Elf_Type t = shtype_map[TYPEIDX (type)];
if (t == ELF_T_NHDR && align == 8)
t = ELF_T_NHDR8;
if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
|| (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
entsize = 1;
else
- entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
+ entsize = __libelf_type_sizes[elf->class - 1][t];
}
/* We assume it is an array of bytes if it is none of the structured
@@ -444,7 +434,7 @@ __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
}
/* Convert according to the version and the type. */
- convert_data (scn, __libelf_version, elf->class,
+ convert_data (scn, elf->class,
(elf->class == ELFCLASS32
|| (offsetof (struct Elf, state.elf32.ehdr)
== offsetof (struct Elf, state.elf64.ehdr))
diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
index d0c0b75f..6a130737 100644
--- a/libelf/elf_getdata_rawchunk.c
+++ b/libelf/elf_getdata_rawchunk.c
@@ -151,8 +151,7 @@ elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
}
/* Call the conversion function. */
- (*__elf_xfctstom[LIBELF_EV_IDX][LIBELF_EV_IDX][elf->class - 1][type])
- (buffer, rawchunk, size, 0);
+ (*__elf_xfctstom[elf->class - 1][type])(buffer, rawchunk, size, 0);
}
/* Allocate the dummy container to point at this buffer. */
@@ -171,7 +170,7 @@ elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
chunk->data.d.d_size = size;
chunk->data.d.d_type = type;
chunk->data.d.d_align = align;
- chunk->data.d.d_version = __libelf_version;
+ chunk->data.d.d_version = EV_CURRENT;
rwlock_unlock (elf->lock);
rwlock_wrlock (elf->lock);
diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c
index f6609a80..896f22cd 100644
--- a/libelf/elf_newdata.c
+++ b/libelf/elf_newdata.c
@@ -117,7 +117,7 @@ elf_newdata (Elf_Scn *scn)
}
/* Set the predefined values. */
- result->data.d.d_version = __libelf_version;
+ result->data.d.d_version = EV_CURRENT;
result->data.s = scn;
diff --git a/libelf/elf_version.c b/libelf/elf_version.c
index 7c336ff9..6ec534ab 100644
--- a/libelf/elf_version.c
+++ b/libelf/elf_version.c
@@ -34,32 +34,25 @@
#include <libelfP.h>
-/* Is the version initialized? */
-int __libelf_version_initialized;
-
-/* Currently selected version. */
-unsigned int __libelf_version = EV_CURRENT;
-
+/* Currently selected version. Should be EV_CURRENT.
+ Will be EV_NONE if elf_version () has not been called yet. */
+unsigned int __libelf_version = EV_NONE;
unsigned int
elf_version (unsigned int version)
{
if (version == EV_NONE)
- return __libelf_version;
+ return EV_CURRENT;
- if (likely (version < EV_NUM))
+ if (likely (version == EV_CURRENT))
{
/* Phew, we know this version. */
- unsigned int last_version = __libelf_version;
-
- /* Store the new version. */
- __libelf_version = version;
/* Signal that the version is now initialized. */
- __libelf_version_initialized = 1;
+ __libelf_version = EV_CURRENT;
- /* And return the last version. */
- return last_version;
+ /* And return the last (or initial) version. */
+ return EV_CURRENT;
}
/* We cannot handle this version. */
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index d04ec5d5..493d7916 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -38,10 +38,8 @@
/* These are the sizes for all the known types. */
-const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] =
{
- /* We have no entry for EV_NONE since we have to set an error. */
- [EV_CURRENT - 1] = {
[ELFCLASS32 - 1] = {
#define TYPE_SIZES(LIBELFBITS) \
[ELF_T_ADDR] = ELFW2(LIBELFBITS, FSZ_ADDR), \
@@ -77,7 +75,6 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
[ELFCLASS64 - 1] = {
TYPE_SIZES (64)
}
- }
};
@@ -89,7 +86,7 @@ gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
if (elf == NULL)
return 0;
- if (version == EV_NONE || version >= EV_NUM)
+ if (version != EV_CURRENT)
{
__libelf_seterrno (ELF_E_UNKNOWN_VERSION);
return 0;
@@ -101,10 +98,6 @@ gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
return 0;
}
-#if EV_NUM != 2
- return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
-#else
- return count * __libelf_type_sizes[0][elf->class - 1][type];
-#endif
+ return count * __libelf_type_sizes[elf->class - 1][type];
}
INTDEF(gelf_fsize)
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
index b5d6ef3d..b9e7fd65 100644
--- a/libelf/gelf_xlate.c
+++ b/libelf/gelf_xlate.c
@@ -170,10 +170,8 @@ union unaligned
/* Now the externally visible table with the function pointers. */
-const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] =
{
- [EV_CURRENT - 1] = {
- [EV_CURRENT - 1] = {
[ELFCLASS32 - 1] = {
#define define_xfcts(Bits) \
[ELF_T_BYTE] = elf_cvt_Byte, \
@@ -209,10 +207,4 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
define_xfcts (64),
[ELF_T_GNUHASH] = elf_cvt_gnuhash
}
- }
- }
};
-/* For now we only handle the case where the memory representation is the
- same as the file representation. Should this change we have to define
- separate functions. For now reuse them. */
-strong_alias (__elf_xfctstom, __elf_xfctstof)
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 9f3e8e9d..51344142 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -411,43 +411,30 @@ struct Elf
typedef void (*xfct_t) (void *, const void *, size_t, int);
/* The table with the function pointers. */
-extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
-extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+extern const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM]
+ attribute_hidden;
/* Array with sizes of the external types indexed by ELF version, binary
class, and type. */
-extern const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+extern const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM]
+ attribute_hidden;
/* We often have to access the size for a type in the current version. */
-#if EV_NUM != 2
# define elf_typesize(class,type,n) \
- elfw2(class,fsize) (type, n, __libelf_version)
-#else
-# define elf_typesize(class,type,n) \
- (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n)
-#endif
-
-/* Currently selected version of the ELF specification. */
-extern unsigned int __libelf_version attribute_hidden;
+ (__libelf_type_sizes[ELFW(ELFCLASS,class) - 1][type] * n)
/* The byte value used for filling gaps. */
extern int __libelf_fill_byte attribute_hidden;
-/* Nonzero if the version was set. */
-extern int __libelf_version_initialized attribute_hidden;
-
-/* Index for __libelf_type_sizes et al. */
-#if EV_NUM == 2
-# define LIBELF_EV_IDX 0
-#else
-# define LIBELF_EV_IDX (__libelf_version - 1)
-#endif
+/* EV_CURRENT if the version was set, EV_NONE otherwise. */
+extern unsigned int __libelf_version attribute_hidden;
-/* Array with alignment requirements of the internal types indexed by ELF
- version, binary class, and type. */
-extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+/* Array with alignment requirements of the internal types indexed by
+ binary class, and type. */
+extern const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM]
+ attribute_hidden;
# define __libelf_type_align(class, type) \
- (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1)
+ (__libelf_type_aligns[class - 1][type] ?: 1)
/* Given an Elf handle and a section type returns the Elf_Data d_type.
Should not be called when SHF_COMPRESSED is set, the d_type should
@@ -455,16 +442,6 @@ extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_
extern Elf_Type __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
internal_function;
-/* The libelf API does not have such a function but it is still useful.
- Get the memory size for the given type.
-
- These functions cannot be marked internal since they are aliases
- of the export elfXX_fsize functions.*/
-extern size_t __elf32_msize (Elf_Type __type, size_t __count,
- unsigned int __version) __const_attribute__;
-extern size_t __elf64_msize (Elf_Type __type, size_t __count,
- unsigned int __version) __const_attribute__;
-
/* Create Elf descriptor from memory image. */
extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
diff --git a/libelf/nlist.c b/libelf/nlist.c
index c7b32fdb..8593c1de 100644
--- a/libelf/nlist.c
+++ b/libelf/nlist.c
@@ -80,9 +80,8 @@ nlist (const char *filename, struct nlist *nl)
/* For compatibility reasons (`nlist' existed before ELF and libelf)
we don't expect the caller to set the ELF version. Do this here
- if it hasn't happened yet. */
- if (__libelf_version_initialized == 0)
- INTUSE(elf_version) (EV_CURRENT);
+ as if it hasn't happened yet. */
+ INTUSE(elf_version) (EV_CURRENT);
/* Now get an ELF descriptor. */
elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL);