summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog32
-rw-r--r--libelf/common.h2
-rw-r--r--libelf/elf32_newphdr.c3
-rw-r--r--libelf/elf32_updatefile.c8
-rw-r--r--libelf/elf32_updatenull.c34
-rw-r--r--libelf/elf_begin.c15
-rw-r--r--libelf/elf_getaroff.c2
-rw-r--r--libelf/elf_getbase.c4
-rw-r--r--libelf/elf_getdata_rawchunk.c2
-rw-r--r--libelf/elf_update.c8
-rw-r--r--libelf/libelfP.h18
11 files changed, 85 insertions, 43 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 82e18ebc..dde6c81d 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,35 @@
+2019-06-18 Mark Wielaard <mark@klomp.org>
+
+ * common.h (allocate_elf): Use int64_t instead of off_t for offset.
+ * elf32_newphdr.c (newphdr): Document why Elf32/64_Word is correct.
+ * elf32_updatefile.c (fill): Use int64_t instead of off_t for pos.
+ (updatefile): Define last_offset, shdr_offset and scn_start as
+ int64_t instead of off_t.
+ * elf32_updatenull.c: Define Elf32_SizeWord and Elf64_SizeWord.
+ (updatenull_wrlock): Return int64_t instead of off_t. Define size,
+ sh_entsize, sh_align and sh_size as SizeWords. Define offset as
+ int64_t. Cast data->d_off to SizeWord instead of GElf_Word. Drop
+ size GElf_Word cast. Cast offset to SizeWord instead of GElf_Word
+ when comparing with sh_size.
+ * elf_begin.c (get_shnum): Define offset as int64_t instead of
+ off_t. Document why use GElf_Word is correct.
+ (file_read_elf): Define offset as int64_t instead of off_t.
+ (__libelf_read_mmaped_file): Likewise.
+ (read_unmmaped_file): Likewise.
+ (read_file): Likewise.
+ * elf_getaroff.c (elf_getaroff): Return int64_t.
+ * elf_getbase.c (elf_getbase): Likewise.
+ * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Define offset as
+ int64_t instead of off_t.
+ * elf_update.c (write_file): Return int64_t instead of off_t,
+ define size as int64_t instead of off_t.
+ (elf_update): Likewise.
+ * libelfP.h (struct Elf): Define start_offset, sizestr_offset and
+ offset as int64_t.
+ (__libelf_read_mmaped_file): Define offset as int64_t.
+ (__elf32_updatenull_wrlock): Return int64_t.
+ (__elf64_updatenull_wrlock): Return int64_t.
+
2019-05-12 Mark Wielaard <mark@klomp.org>
* elf32_updatenull.c (updatenull_wrlock): Mark shdr_flags dirty if
diff --git a/libelf/common.h b/libelf/common.h
index 62486903..b0175f60 100644
--- a/libelf/common.h
+++ b/libelf/common.h
@@ -68,7 +68,7 @@ determine_kind (void *buf, size_t len)
/* Allocate an Elf descriptor and fill in the generic information. */
static inline Elf *
__attribute__ ((unused))
-allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
+allocate_elf (int fildes, void *map_address, int64_t offset, size_t maxsize,
Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra)
{
Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra);
diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c
index 4aa72137..7dd78ca9 100644
--- a/libelf/elf32_newphdr.c
+++ b/libelf/elf32_newphdr.c
@@ -56,6 +56,9 @@ elfw2(LIBELFBITS,newphdr) (Elf *elf, size_t count)
return NULL;
}
+ /* This check is correct, it is for sh_info, which is either
+ Elf32_Word or Elf64_Word, both being 32 bits. But count is size_t
+ so might not fit on 32bit ELF files. */
if (unlikely ((ElfW2(LIBELFBITS,Word)) count != count))
{
__libelf_seterrno (ELF_E_INVALID_OPERAND);
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index eea51a7f..f67e6261 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -498,7 +498,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
/* Helper function to write out fill bytes. */
static int
-fill (int fd, off_t pos, size_t len, char *fillbuf, size_t *filledp)
+fill (int fd, int64_t pos, size_t len, char *fillbuf, size_t *filledp)
{
size_t filled = *filledp;
size_t fill_len = MIN (len, FILLBUFSIZE);
@@ -651,7 +651,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
/* From now on we have to keep track of the last position to eventually
fill the gaps with the prescribed fill byte. */
- off_t last_offset;
+ int64_t last_offset;
if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
else
@@ -664,7 +664,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
+ sizeof (ElfW2(LIBELFBITS,Shdr)))))
return 1;
- off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
+ int64_t shdr_offset = elf->start_offset + ehdr->e_shoff;
#undef shdr_fctp
#define shdr_fctp __elf_xfctstom[ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
@@ -712,7 +712,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (shdr->sh_type == SHT_NOBITS)
goto next;
- off_t scn_start = elf->start_offset + shdr->sh_offset;
+ int64_t scn_start = elf->start_offset + shdr->sh_offset;
Elf_Data_List *dl = &scn->data_list;
bool scn_changed = false;
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index 303055a0..5f3cdbf6 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -45,6 +45,10 @@
# define LIBELFBITS 32
#endif
+/* Some fields contain 32/64 sizes. We cannot use Elf32/64_Word for those,
+ since those are both 32bits. Elf32/64_Xword is always 64bits. */
+#define Elf32_SizeWord Elf32_Word
+#define Elf64_SizeWord Elf64_Xword
static int
@@ -122,7 +126,7 @@ ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
}
-off_t
+int64_t
internal_function
__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
{
@@ -137,7 +141,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
return -1;
/* At least the ELF header is there. */
- off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+ ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
/* Set the program header position. */
if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
@@ -152,7 +156,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
{
/* The user is supposed to fill out e_phoff. Use it and
e_phnum to determine the maximum extend. */
- size = MAX ((size_t) size,
+ size = MAX (size,
ehdr->e_phoff
+ elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
}
@@ -205,11 +209,11 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
{
Elf_Scn *scn = &list->data[cnt];
ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
- off_t offset = 0;
+ int64_t offset = 0;
assert (shdr != NULL);
- ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
- ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
+ ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize;
+ ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1;
if (unlikely (! powerof2 (sh_align)))
{
__libelf_seterrno (ELF_E_INVALID_ALIGN);
@@ -299,8 +303,8 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
/* The user specified the offset and the size.
All we have to do is check whether this block
fits in the size specified for the section. */
- if (unlikely ((GElf_Word) (data->d_off
- + data->d_size)
+ if (unlikely ((ElfW2(LIBELFBITS,SizeWord))
+ (data->d_off + data->d_size)
> shdr->sh_size))
{
__libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
@@ -329,7 +333,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
if (elf->flags & ELF_F_LAYOUT)
{
- size = MAX ((GElf_Word) size,
+ size = MAX (size,
(shdr->sh_type != SHT_NOBITS
? shdr->sh_offset + shdr->sh_size : 0));
@@ -353,8 +357,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
size = (size + sh_align - 1) & ~(sh_align - 1);
int offset_changed = 0;
- update_if_changed (shdr->sh_offset, (GElf_Word) size,
- offset_changed);
+ update_if_changed (shdr->sh_offset, size, offset_changed);
changed |= offset_changed;
if (offset_changed && scn->data_list_rear == NULL)
@@ -367,7 +370,8 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
/* See whether the section size is correct. */
int size_changed = 0;
- update_if_changed (shdr->sh_size, (GElf_Word) offset,
+ update_if_changed (shdr->sh_size,
+ (ElfW2(LIBELFBITS,SizeWord)) offset,
size_changed);
changed |= size_changed;
@@ -384,7 +388,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
&& (elf->flags & ELF_F_PERMISSIVE) == 0)
{
/* For compressed sections check the uncompressed size. */
- ElfW2(LIBELFBITS,Word) sh_size;
+ ElfW2(LIBELFBITS,SizeWord) sh_size;
if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
sh_size = shdr->sh_size;
else
@@ -418,7 +422,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
/* The user is supposed to fill out e_shoff. Use it and
e_shnum (or sh_size of the dummy, first section header)
to determine the maximum extend. */
- size = MAX ((GElf_Word) size,
+ size = MAX (size,
(ehdr->e_shoff
+ (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
}
@@ -432,7 +436,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
- update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
+ update_if_changed (ehdr->e_shoff, size, elf->flags);
/* Account for the section header size. */
size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 5d095ff0..8107a103 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -71,8 +71,8 @@ file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
static size_t
-get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
- size_t maxsize)
+get_shnum (void *map_address, unsigned char *e_ident, int fildes,
+ int64_t offset, size_t maxsize)
{
size_t result;
union
@@ -243,6 +243,9 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
CONVERT (size);
}
+ /* Although sh_size is an Elf64_Xword and can contain a 64bit
+ value, we only expect an 32bit value max. GElf_Word is
+ 32bit unsigned. */
if (size > ~((GElf_Word) 0))
{
/* Invalid value, it is too large. */
@@ -266,7 +269,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
/* Create descriptor for ELF file in memory. */
static Elf *
file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
- off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
+ int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
{
/* Verify the binary is of the class we can handle. */
if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
@@ -531,7 +534,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
Elf *
internal_function
-__libelf_read_mmaped_file (int fildes, void *map_address, off_t offset,
+__libelf_read_mmaped_file (int fildes, void *map_address, int64_t offset,
size_t maxsize, Elf_Cmd cmd, Elf *parent)
{
/* We have to find out what kind of file this is. We handle ELF
@@ -564,7 +567,7 @@ __libelf_read_mmaped_file (int fildes, void *map_address, off_t offset,
static Elf *
-read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
+read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
Elf *parent)
{
/* We have to find out what kind of file this is. We handle ELF
@@ -626,7 +629,7 @@ read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
/* Open a file for reading. If possible we will try to mmap() the file. */
static struct Elf *
-read_file (int fildes, off_t offset, size_t maxsize,
+read_file (int fildes, int64_t offset, size_t maxsize,
Elf_Cmd cmd, Elf *parent)
{
void *map_address = NULL;
diff --git a/libelf/elf_getaroff.c b/libelf/elf_getaroff.c
index 5b59203f..5c102ad6 100644
--- a/libelf/elf_getaroff.c
+++ b/libelf/elf_getaroff.c
@@ -38,7 +38,7 @@
#include "libelfP.h"
-off_t
+int64_t
elf_getaroff (Elf *elf)
{
/* Be gratious, the specs demand it. */
diff --git a/libelf/elf_getbase.c b/libelf/elf_getbase.c
index 8ec5f87e..4890d336 100644
--- a/libelf/elf_getbase.c
+++ b/libelf/elf_getbase.c
@@ -37,8 +37,8 @@
#include "libelfP.h"
-off_t
+int64_t
elf_getbase (Elf *elf)
{
- return elf == NULL ? (off_t) -1 : elf->start_offset;
+ return elf == NULL ? (int64_t) -1 : elf->start_offset;
}
diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
index 6a130737..1072f7de 100644
--- a/libelf/elf_getdata_rawchunk.c
+++ b/libelf/elf_getdata_rawchunk.c
@@ -41,7 +41,7 @@
#include "common.h"
Elf_Data *
-elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
+elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
{
if (unlikely (elf == NULL))
return NULL;
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 36997c2b..9b8867ce 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -40,8 +40,8 @@
#include "libelfP.h"
-static off_t
-write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
+static int64_t
+write_file (Elf *elf, int64_t size, int change_bo, size_t shnum)
{
int class = elf->class;
@@ -164,11 +164,11 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
}
-off_t
+int64_t
elf_update (Elf *elf, Elf_Cmd cmd)
{
size_t shnum;
- off_t size;
+ int64_t size;
int change_bo = 0;
if (cmd != ELF_C_NULL
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 51344142..b55d5c48 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -296,7 +296,7 @@ struct Elf
int fildes;
/* Offset in the archive this file starts or zero. */
- off_t start_offset;
+ int64_t start_offset;
/* Size of the file in the archive or the entire file size, or ~0
for an (yet) unknown size. */
@@ -350,7 +350,7 @@ struct Elf
int ehdr_flags; /* Flags (dirty) for ELF header. */
int phdr_flags; /* Flags (dirty|malloc) for program header. */
int shdr_malloced; /* Nonzero if shdr array was allocated. */
- off_t sizestr_offset; /* Offset of the size string in the parent
+ int64_t sizestr_offset; /* Offset of the size string in the parent
if this is an archive member. */
Elf32_Ehdr ehdr_mem; /* Memory used for ELF header when not
mmaped. */
@@ -375,7 +375,7 @@ struct Elf
int ehdr_flags; /* Flags (dirty) for ELF header. */
int phdr_flags; /* Flags (dirty|malloc) for program header. */
int shdr_malloced; /* Nonzero if shdr array was allocated. */
- off_t sizestr_offset; /* Offset of the size string in the parent
+ int64_t sizestr_offset; /* Offset of the size string in the parent
if this is an archive member. */
Elf64_Ehdr ehdr_mem; /* Memory used for ELF header when not
mmaped. */
@@ -392,7 +392,7 @@ struct Elf
char *long_names; /* If no index is available but long names
are used this elements points to the data.*/
size_t long_names_len; /* Length of the long name table. */
- off_t offset; /* Offset in file we are currently at.
+ int64_t offset; /* Offset in file we are currently at.
elf_next() advances this to the next
member of the archive. */
Elf_Arhdr elf_ar_hdr; /* Structure returned by 'elf_getarhdr'. */
@@ -445,7 +445,7 @@ extern Elf_Type __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
/* Create Elf descriptor from memory image. */
extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
- off_t offset, size_t maxsize,
+ int64_t offset, size_t maxsize,
Elf_Cmd cmd, Elf *parent)
internal_function;
@@ -467,10 +467,10 @@ extern int __libelf_set_rawdata_wrlock (Elf_Scn *scn) internal_function;
/* Helper functions for elf_update. */
-extern off_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop,
- size_t shnum) internal_function;
-extern off_t __elf64_updatenull_wrlock (Elf *elf, int *change_bop,
- size_t shnum) internal_function;
+extern int64_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop,
+ size_t shnum) internal_function;
+extern int64_t __elf64_updatenull_wrlock (Elf *elf, int *change_bop,
+ size_t shnum) internal_function;
extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum)
internal_function;