mirror of
https://github.com/arachsys/libelf.git
synced 2026-01-26 07:37:55 +00:00
Update upstream files from elfutils 0.193
This commit is contained in:
parent
4015076fe6
commit
e12821ffb2
@ -315,7 +315,14 @@ extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn);
|
||||
extern Elf_Scn *elf_newscn (Elf *__elf);
|
||||
|
||||
/* Get the section index of the extended section index table for the
|
||||
given symbol table. */
|
||||
given symbol table. Returns -1 when the given Elf_Scn is NULL or
|
||||
if an error occurred during lookup, elf_errno will be set. Returns
|
||||
0 if the given Elf_Scn isn't a symbol table (sh_type is not
|
||||
SHT_SYMTAB) or no extended section index table could be
|
||||
found. Otherwise the section index of the extended section index
|
||||
table for the given Elf_Scn is returned. An extended index table
|
||||
has a sh_type of SHT_SYMTAB_SHNDX and a sh_link equal to the given
|
||||
symbol table section index. */
|
||||
extern int elf_scnshndx (Elf_Scn *__scn);
|
||||
|
||||
/* Get the number of sections in the ELF file. If the file uses more
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
the GNU Lesser General Public License along with this program. If
|
||||
not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
@ -146,20 +146,6 @@ load_shdr_wrlock (Elf_Scn *scn)
|
||||
CONVERT_TO (shdr[cnt].sh_addralign,
|
||||
notcvt[cnt].sh_addralign);
|
||||
CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& shdr[cnt].sh_link < shnum)
|
||||
elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
|
||||
elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
|
||||
= -1;
|
||||
}
|
||||
|
||||
if (copy)
|
||||
|
||||
@ -412,19 +412,6 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
((char *) map_address + offset
|
||||
+ elf->state.elf32.shdr[cnt].sh_offset);
|
||||
elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& elf->state.elf32.shdr[cnt].sh_link < scncnt)
|
||||
elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
|
||||
elf->state.elf32.scns.data[cnt].shndx_index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -510,19 +497,6 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
((char *) map_address + offset
|
||||
+ elf->state.elf64.shdr[cnt].sh_offset);
|
||||
elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& elf->state.elf64.shdr[cnt].sh_link < scncnt)
|
||||
elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
|
||||
elf->state.elf64.scns.data[cnt].shndx_index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@ -584,25 +584,30 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags)
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_addralign;
|
||||
union shdr
|
||||
{
|
||||
Elf32_Shdr *s32;
|
||||
Elf64_Shdr *s64;
|
||||
} shdr;
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
if (shdr == NULL)
|
||||
shdr.s32 = elf32_getshdr (scn);
|
||||
if (shdr.s32 == NULL)
|
||||
return -1;
|
||||
|
||||
sh_flags = shdr->sh_flags;
|
||||
sh_type = shdr->sh_type;
|
||||
sh_addralign = shdr->sh_addralign;
|
||||
sh_flags = shdr.s32->sh_flags;
|
||||
sh_type = shdr.s32->sh_type;
|
||||
sh_addralign = shdr.s32->sh_addralign;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
if (shdr == NULL)
|
||||
shdr.s64 = elf64_getshdr (scn);
|
||||
if (shdr.s64 == NULL)
|
||||
return -1;
|
||||
|
||||
sh_flags = shdr->sh_flags;
|
||||
sh_type = shdr->sh_type;
|
||||
sh_addralign = shdr->sh_addralign;
|
||||
sh_flags = shdr.s64->sh_flags;
|
||||
sh_type = shdr.s64->sh_type;
|
||||
sh_addralign = shdr.s64->sh_addralign;
|
||||
}
|
||||
|
||||
if ((sh_flags & SHF_ALLOC) != 0)
|
||||
@ -679,17 +684,17 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags)
|
||||
correctly and ignored when SHF_COMPRESSED is set. */
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
shdr->sh_size = new_size;
|
||||
shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR);
|
||||
shdr->sh_flags |= SHF_COMPRESSED;
|
||||
shdr.s32->sh_size = new_size;
|
||||
shdr.s32->sh_addralign = __libelf_type_align (ELFCLASS32,
|
||||
ELF_T_CHDR);
|
||||
shdr.s32->sh_flags |= SHF_COMPRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
shdr->sh_size = new_size;
|
||||
shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR);
|
||||
shdr->sh_flags |= SHF_COMPRESSED;
|
||||
shdr.s64->sh_size = new_size;
|
||||
shdr.s64->sh_addralign = __libelf_type_align (ELFCLASS64,
|
||||
ELF_T_CHDR);
|
||||
shdr.s64->sh_flags |= SHF_COMPRESSED;
|
||||
}
|
||||
|
||||
__libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR);
|
||||
@ -731,17 +736,15 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags)
|
||||
correctly and ignored when SHF_COMPRESSED is set. */
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
shdr->sh_size = scn->zdata_size;
|
||||
shdr->sh_addralign = scn->zdata_align;
|
||||
shdr->sh_flags &= ~SHF_COMPRESSED;
|
||||
shdr.s32->sh_size = scn->zdata_size;
|
||||
shdr.s32->sh_addralign = scn->zdata_align;
|
||||
shdr.s32->sh_flags &= ~SHF_COMPRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
shdr->sh_size = scn->zdata_size;
|
||||
shdr->sh_addralign = scn->zdata_align;
|
||||
shdr->sh_flags &= ~SHF_COMPRESSED;
|
||||
shdr.s64->sh_size = scn->zdata_size;
|
||||
shdr.s64->sh_addralign = scn->zdata_align;
|
||||
shdr.s64->sh_flags &= ~SHF_COMPRESSED;
|
||||
}
|
||||
|
||||
__libelf_reset_rawdata (scn, scn->zdata_base,
|
||||
|
||||
@ -59,25 +59,30 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_addralign;
|
||||
union shdr
|
||||
{
|
||||
Elf32_Shdr *s32;
|
||||
Elf64_Shdr *s64;
|
||||
} shdr;
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
if (shdr == NULL)
|
||||
shdr.s32 = elf32_getshdr (scn);
|
||||
if (shdr.s32 == NULL)
|
||||
return -1;
|
||||
|
||||
sh_flags = shdr->sh_flags;
|
||||
sh_type = shdr->sh_type;
|
||||
sh_addralign = shdr->sh_addralign;
|
||||
sh_flags = shdr.s32->sh_flags;
|
||||
sh_type = shdr.s32->sh_type;
|
||||
sh_addralign = shdr.s32->sh_addralign;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
if (shdr == NULL)
|
||||
shdr.s64 = elf64_getshdr (scn);
|
||||
if (shdr.s64 == NULL)
|
||||
return -1;
|
||||
|
||||
sh_flags = shdr->sh_flags;
|
||||
sh_type = shdr->sh_type;
|
||||
sh_addralign = shdr->sh_addralign;
|
||||
sh_flags = shdr.s64->sh_flags;
|
||||
sh_type = shdr.s64->sh_type;
|
||||
sh_addralign = shdr.s64->sh_addralign;
|
||||
}
|
||||
|
||||
/* Allocated sections, or sections that are already are compressed
|
||||
@ -122,15 +127,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
|
||||
sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
|
||||
Just adjust the sh_size. */
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
shdr->sh_size = new_size;
|
||||
}
|
||||
shdr.s32->sh_size = new_size;
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
shdr->sh_size = new_size;
|
||||
}
|
||||
shdr.s64->sh_size = new_size;
|
||||
|
||||
__libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE);
|
||||
|
||||
@ -187,15 +186,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
|
||||
sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
|
||||
Just adjust the sh_size. */
|
||||
if (elfclass == ELFCLASS32)
|
||||
{
|
||||
Elf32_Shdr *shdr = elf32_getshdr (scn);
|
||||
shdr->sh_size = size;
|
||||
}
|
||||
shdr.s32->sh_size = size;
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *shdr = elf64_getshdr (scn);
|
||||
shdr->sh_size = size;
|
||||
}
|
||||
shdr.s64->sh_size = size;
|
||||
|
||||
__libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
|
||||
__libelf_data_type (&ehdr, sh_type,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* Get the section index of the extended section index table.
|
||||
Copyright (C) 2007 Red Hat, Inc.
|
||||
Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
|
||||
This file is part of elfutils.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
|
||||
|
||||
@ -37,14 +38,53 @@
|
||||
int
|
||||
elf_scnshndx (Elf_Scn *scn)
|
||||
{
|
||||
if (unlikely (scn->shndx_index == 0))
|
||||
size_t scnndx;
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr;
|
||||
Elf *elf;
|
||||
Elf_Scn *nscn;
|
||||
|
||||
if (scn == NULL)
|
||||
return -1;
|
||||
|
||||
scnndx = scn->index;
|
||||
elf = scn->elf;
|
||||
|
||||
shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
if (shdr == NULL)
|
||||
return -1;
|
||||
|
||||
/* Only SYMTAB sections can have a SHNDX section. */
|
||||
if (shdr->sh_type != SHT_SYMTAB)
|
||||
return 0;
|
||||
|
||||
/* By convention the SHT_SYMTAB_SHNDX section is right after the the
|
||||
SHT_SYMTAB section, so start there. */
|
||||
nscn = scn;
|
||||
while ((nscn = elf_nextscn (elf, nscn)) != NULL)
|
||||
{
|
||||
/* We do not have the value yet. We get it as a side effect of
|
||||
getting a section header. */
|
||||
GElf_Shdr shdr_mem;
|
||||
(void) INTUSE(gelf_getshdr) (scn, &shdr_mem);
|
||||
shdr = gelf_getshdr (nscn, &shdr_mem);
|
||||
if (shdr == NULL)
|
||||
return -1;
|
||||
|
||||
if (shdr->sh_type == SHT_SYMTAB_SHNDX && shdr->sh_link == scnndx)
|
||||
return nscn->index;
|
||||
}
|
||||
|
||||
return scn->shndx_index;
|
||||
/* OK, not found, start from the top. */
|
||||
nscn = NULL;
|
||||
while ((nscn = elf_nextscn (elf, nscn)) != NULL
|
||||
&& nscn->index != scnndx)
|
||||
{
|
||||
shdr = gelf_getshdr (nscn, &shdr_mem);
|
||||
if (shdr == NULL)
|
||||
return -1;
|
||||
|
||||
if (shdr->sh_type == SHT_SYMTAB_SHNDX && shdr->sh_link == scnndx)
|
||||
return nscn->index;
|
||||
}
|
||||
|
||||
/* No shndx found, but no errors. */
|
||||
return 0;
|
||||
}
|
||||
INTDEF(elf_scnshndx)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* Return string pointer from string section.
|
||||
Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc.
|
||||
Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
|
||||
This file is part of elfutils.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
|
||||
|
||||
@ -53,24 +54,6 @@ get_zdata (Elf_Scn *strscn)
|
||||
return zdata;
|
||||
}
|
||||
|
||||
static bool validate_str (const char *str, size_t from, size_t to)
|
||||
{
|
||||
#if HAVE_DECL_MEMRCHR
|
||||
// Check end first, which is likely a zero terminator, to prevent function call
|
||||
return ((to > 0 && str[to - 1] == '\0')
|
||||
|| (to - from > 0 && memrchr (&str[from], '\0', to - from - 1) != 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)
|
||||
{
|
||||
@ -201,9 +184,12 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
|
||||
// initialized yet (when data_read is zero). So we cannot just
|
||||
// look at the rawdata.d.d_size.
|
||||
|
||||
/* Make sure the string is NUL terminated. Start from the end,
|
||||
which very likely is a NUL char. */
|
||||
if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
|
||||
/* First check there actually is any data. This could be a new
|
||||
section which hasn't had any data set yet. Then make sure
|
||||
the string is at a valid offset and NUL terminated. */
|
||||
if (unlikely (strscn->rawdata_base == NULL))
|
||||
__libelf_seterrno (ELF_E_INVALID_SECTION);
|
||||
else if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
|
||||
result = &strscn->rawdata_base[offset];
|
||||
else
|
||||
__libelf_seterrno (ELF_E_INVALID_INDEX);
|
||||
|
||||
@ -218,9 +218,6 @@ struct Elf_Scn
|
||||
int data_read; /* Nonzero if the section was created by the
|
||||
user or if the data from the file/memory
|
||||
is read. */
|
||||
int shndx_index; /* Index of the extended section index
|
||||
table for this symbol table (if this
|
||||
section is a symbol table). */
|
||||
|
||||
size_t index; /* Index of this section. */
|
||||
struct Elf *elf; /* The underlying ELF file. */
|
||||
@ -524,7 +521,6 @@ extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
|
||||
attribute_hidden;
|
||||
extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
|
||||
attribute_hidden;
|
||||
extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden;
|
||||
extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
|
||||
attribute_hidden;
|
||||
extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data)
|
||||
|
||||
16
src/locks.h
16
src/locks.h
@ -43,6 +43,17 @@
|
||||
# define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock))
|
||||
# define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock))
|
||||
# define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock))
|
||||
# define mutex_define(class,name) class pthread_mutex_t name
|
||||
# define MUTEX_CALL(call) \
|
||||
({ int _err = pthread_mutex_ ## call; assert_perror (_err); })
|
||||
# define mutex_init(lock) \
|
||||
({ pthread_mutexattr_t _attr; \
|
||||
pthread_mutexattr_init (&_attr); \
|
||||
pthread_mutexattr_settype (&_attr, PTHREAD_MUTEX_RECURSIVE); \
|
||||
MUTEX_CALL (init (&lock, &_attr)); })
|
||||
# define mutex_lock(_lock) MUTEX_CALL (lock (&_lock))
|
||||
# define mutex_unlock(lock) MUTEX_CALL (unlock (&lock))
|
||||
# define mutex_fini(lock) MUTEX_CALL (destroy (&lock))
|
||||
# define once(once_control, init_routine) \
|
||||
ONCE_CALL (once (&once_control, init_routine))
|
||||
#else
|
||||
@ -55,6 +66,11 @@
|
||||
# define rwlock_rdlock(lock) ((void) (lock))
|
||||
# define rwlock_wrlock(lock) ((void) (lock))
|
||||
# define rwlock_unlock(lock) ((void) (lock))
|
||||
# define mutex_define(class,name) class int name
|
||||
# define mutex_init(lock) ((void) (lock))
|
||||
# define mutex_lock(lock) ((void) (lock))
|
||||
# define mutex_unlock(lock) ((void) (lock))
|
||||
# define mutex_fini(lock) ((void) (lock))
|
||||
# define once_define(class,name)
|
||||
# define once(once_control, init_routine) init_routine()
|
||||
#endif /* USE_LOCKS */
|
||||
|
||||
34
src/system.h
34
src/system.h
@ -31,9 +31,15 @@
|
||||
#ifndef LIB_SYSTEM_H
|
||||
#define LIB_SYSTEM_H 1
|
||||
|
||||
#include <config.h>
|
||||
/* Prevent double inclusion of config.h, config.h includes eu-config.h. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#ifndef EU_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -117,6 +123,32 @@ startswith (const char *str, const char *prefix)
|
||||
return strncmp (str, prefix, strlen (prefix)) == 0;
|
||||
}
|
||||
|
||||
/* Return TRUE if STR[FROM] is a valid string with a zero terminator
|
||||
at or before STR[TO - 1]. Note FROM is an index into the STR
|
||||
array, while TO is the maximum size of the STR array. This
|
||||
function returns FALSE when TO is zero or FROM >= TO. */
|
||||
static inline bool
|
||||
validate_str (const char *str, size_t from, size_t to)
|
||||
{
|
||||
#if HAVE_DECL_MEMRCHR
|
||||
// Check end first, which is likely a zero terminator,
|
||||
// to prevent function call
|
||||
return (to > 0
|
||||
&& (str[to - 1] == '\0'
|
||||
|| (to > from
|
||||
&& memrchr (&str[from], '\0', to - from - 1) != NULL)));
|
||||
#else
|
||||
do {
|
||||
if (to <= from)
|
||||
return false;
|
||||
|
||||
to--;
|
||||
} while (str[to]);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* A special gettext function we use if the strings are too short. */
|
||||
#define sgettext(Str) \
|
||||
({ const char *__res = strrchr (_(Str), '|'); \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user