mirror of
https://github.com/arachsys/libelf.git
synced 2026-01-26 15:39:09 +00:00
Merge from upstream libelf 0.192
This commit is contained in:
commit
f918d99c1e
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ LDFLAGS =
|
||||
LDLIBS = -lz -lzstd
|
||||
|
||||
MAJOR = 1
|
||||
MINOR = 0.191
|
||||
MINOR = 0.192
|
||||
|
||||
HEADERS = $(wildcard include/*.h src/*.h)
|
||||
SOURCES = $(wildcard src/*.c)
|
||||
|
||||
24
src/common.h
24
src/common.h
@ -89,30 +89,34 @@ allocate_elf (int fildes, void *map_address, int64_t offset, size_t maxsize,
|
||||
}
|
||||
|
||||
|
||||
/* Acquire lock for the descriptor and all children. */
|
||||
/* Caller must hold a lock for ELF. If there are children then a lock
|
||||
will be acquired for each of them (recursively). */
|
||||
static void
|
||||
__attribute__ ((unused))
|
||||
libelf_acquire_all (Elf *elf)
|
||||
libelf_acquire_all_children (Elf *elf)
|
||||
{
|
||||
rwlock_wrlock (elf->lock);
|
||||
|
||||
if (elf->kind == ELF_K_AR)
|
||||
{
|
||||
Elf *child = elf->state.ar.children;
|
||||
|
||||
while (child != NULL)
|
||||
{
|
||||
rwlock_wrlock (child->lock);
|
||||
|
||||
if (child->ref_count != 0)
|
||||
libelf_acquire_all (child);
|
||||
libelf_acquire_all_children (child);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Release own lock and those of the children. */
|
||||
|
||||
/* Caller must hold a lock for ELF. If there are children then a lock
|
||||
will be released for each of them (recursively). */
|
||||
static void
|
||||
__attribute__ ((unused))
|
||||
libelf_release_all (Elf *elf)
|
||||
libelf_release_all_children (Elf *elf)
|
||||
{
|
||||
if (elf->kind == ELF_K_AR)
|
||||
{
|
||||
@ -121,12 +125,12 @@ libelf_release_all (Elf *elf)
|
||||
while (child != NULL)
|
||||
{
|
||||
if (child->ref_count != 0)
|
||||
libelf_release_all (child);
|
||||
libelf_release_all_children (child);
|
||||
|
||||
rwlock_unlock (child->lock);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
rwlock_unlock (elf->lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -98,4 +98,136 @@
|
||||
#define GNU_BUILD_ATTRIBUTE_PIC 7
|
||||
#define GNU_BUILD_ATTRIBUTE_SHORT_ENUM 8
|
||||
|
||||
/* Hexagon specific declarations. */
|
||||
|
||||
/* Processor specific flags for the Ehdr e_flags field. */
|
||||
#define EF_HEXAGON_MACH_V2 0x00000001 /* Hexagon V2 */
|
||||
#define EF_HEXAGON_MACH_V3 0x00000002 /* Hexagon V3 */
|
||||
#define EF_HEXAGON_MACH_V4 0x00000003 /* Hexagon V4 */
|
||||
#define EF_HEXAGON_MACH_V5 0x00000004 /* Hexagon V5 */
|
||||
#define EF_HEXAGON_MACH_V55 0x00000005 /* Hexagon V55 */
|
||||
#define EF_HEXAGON_MACH_V60 0x00000060 /* Hexagon V60 */
|
||||
#define EF_HEXAGON_MACH_V61 0x00000061 /* Hexagon V61 */
|
||||
#define EF_HEXAGON_MACH_V62 0x00000062 /* Hexagon V62 */
|
||||
#define EF_HEXAGON_MACH_V65 0x00000065 /* Hexagon V65 */
|
||||
#define EF_HEXAGON_MACH_V66 0x00000066 /* Hexagon V66 */
|
||||
#define EF_HEXAGON_MACH_V67 0x00000067 /* Hexagon V67 */
|
||||
#define EF_HEXAGON_MACH_V67T 0x00008067 /* Hexagon V67T */
|
||||
#define EF_HEXAGON_MACH_V68 0x00000068 /* Hexagon V68 */
|
||||
#define EF_HEXAGON_MACH_V69 0x00000069 /* Hexagon V68 */
|
||||
#define EF_HEXAGON_MACH_V71 0x00000071 /* Hexagon V71 */
|
||||
#define EF_HEXAGON_MACH_V71T 0x00008071 /* Hexagon V71T */
|
||||
#define EF_HEXAGON_MACH_V73 0x00000073 /* Hexagon V73 */
|
||||
#define EF_HEXAGON_MACH 0x000003ff /* Hexagon V.. */
|
||||
#define EF_HEXAGON_TINY 0x00008000 /* Hexagon V..T */
|
||||
|
||||
/* Special section indices. */
|
||||
#define SHN_HEXAGON_SCOMMON 0xff00 /* Other access sizes */
|
||||
#define SHN_HEXAGON_SCOMMON_1 0xff01 /* Byte-sized access */
|
||||
#define SHN_HEXAGON_SCOMMON_2 0xff02 /* Half-word-sized access */
|
||||
#define SHN_HEXAGON_SCOMMON_4 0xff03 /* Word-sized access */
|
||||
#define SHN_HEXAGON_SCOMMON_8 0xff04 /* Double-word-size access */
|
||||
|
||||
/* Hexagon specific relocs. */
|
||||
#define R_HEX_NONE 0
|
||||
#define R_HEX_B22_PCREL 1
|
||||
#define R_HEX_B15_PCREL 2
|
||||
#define R_HEX_B7_PCREL 3
|
||||
#define R_HEX_LO16 4
|
||||
#define R_HEX_HI16 5
|
||||
#define R_HEX_32 6
|
||||
#define R_HEX_16 7
|
||||
#define R_HEX_8 8
|
||||
#define R_HEX_GPREL16_0 9
|
||||
#define R_HEX_GPREL16_1 10
|
||||
#define R_HEX_GPREL16_2 11
|
||||
#define R_HEX_GPREL16_3 12
|
||||
#define R_HEX_HL16 13
|
||||
#define R_HEX_B13_PCREL 14
|
||||
#define R_HEX_B9_PCREL 15
|
||||
#define R_HEX_B32_PCREL_X 16
|
||||
#define R_HEX_32_6_X 17
|
||||
#define R_HEX_B22_PCREL_X 18
|
||||
#define R_HEX_B15_PCREL_X 19
|
||||
#define R_HEX_B13_PCREL_X 20
|
||||
#define R_HEX_B9_PCREL_X 21
|
||||
#define R_HEX_B7_PCREL_X 22
|
||||
#define R_HEX_16_X 23
|
||||
#define R_HEX_12_X 24
|
||||
#define R_HEX_11_X 25
|
||||
#define R_HEX_10_X 26
|
||||
#define R_HEX_9_X 27
|
||||
#define R_HEX_8_X 28
|
||||
#define R_HEX_7_X 29
|
||||
#define R_HEX_6_X 30
|
||||
#define R_HEX_32_PCREL 31
|
||||
#define R_HEX_COPY 32
|
||||
#define R_HEX_GLOB_DAT 33
|
||||
#define R_HEX_JMP_SLOT 34
|
||||
#define R_HEX_RELATIVE 35
|
||||
#define R_HEX_PLT_B22_PCREL 36
|
||||
#define R_HEX_GOTREL_LO16 37
|
||||
#define R_HEX_GOTREL_HI16 38
|
||||
#define R_HEX_GOTREL_32 39
|
||||
#define R_HEX_GOT_LO16 40
|
||||
#define R_HEX_GOT_HI16 41
|
||||
#define R_HEX_GOT_32 42
|
||||
#define R_HEX_GOT_16 43
|
||||
#define R_HEX_DTPMOD_32 44
|
||||
#define R_HEX_DTPREL_LO16 45
|
||||
#define R_HEX_DTPREL_HI16 46
|
||||
#define R_HEX_DTPREL_32 47
|
||||
#define R_HEX_DTPREL_16 48
|
||||
#define R_HEX_GD_PLT_B22_PCREL 49
|
||||
#define R_HEX_GD_GOT_LO16 50
|
||||
#define R_HEX_GD_GOT_HI16 51
|
||||
#define R_HEX_GD_GOT_32 52
|
||||
#define R_HEX_GD_GOT_16 53
|
||||
#define R_HEX_IE_LO16 54
|
||||
#define R_HEX_IE_HI16 55
|
||||
#define R_HEX_IE_32 56
|
||||
#define R_HEX_IE_GOT_LO16 57
|
||||
#define R_HEX_IE_GOT_HI16 58
|
||||
#define R_HEX_IE_GOT_32 59
|
||||
#define R_HEX_IE_GOT_16 60
|
||||
#define R_HEX_TPREL_LO16 61
|
||||
#define R_HEX_TPREL_HI16 62
|
||||
#define R_HEX_TPREL_32 63
|
||||
#define R_HEX_TPREL_16 64
|
||||
#define R_HEX_6_PCREL_X 65
|
||||
#define R_HEX_GOTREL_32_6_X 66
|
||||
#define R_HEX_GOTREL_16_X 67
|
||||
#define R_HEX_GOTREL_11_X 68
|
||||
#define R_HEX_GOT_32_6_X 69
|
||||
#define R_HEX_GOT_16_X 70
|
||||
#define R_HEX_GOT_11_X 71
|
||||
#define R_HEX_DTPREL_32_6_X 72
|
||||
#define R_HEX_DTPREL_16_X 73
|
||||
#define R_HEX_DTPREL_11_X 74
|
||||
#define R_HEX_GD_GOT_32_6_X 75
|
||||
#define R_HEX_GD_GOT_16_X 76
|
||||
#define R_HEX_GD_GOT_11_X 77
|
||||
#define R_HEX_IE_32_6_X 78
|
||||
#define R_HEX_IE_16_X 79
|
||||
#define R_HEX_IE_GOT_32_6_X 80
|
||||
#define R_HEX_IE_GOT_16_X 81
|
||||
#define R_HEX_IE_GOT_11_X 82
|
||||
#define R_HEX_TPREL_32_6_X 83
|
||||
#define R_HEX_TPREL_16_X 84
|
||||
#define R_HEX_TPREL_11_X 85
|
||||
#define R_HEX_LD_PLT_B22_PCREL 86
|
||||
#define R_HEX_LD_GOT_LO16 87
|
||||
#define R_HEX_LD_GOT_HI16 88
|
||||
#define R_HEX_LD_GOT_32 89
|
||||
#define R_HEX_LD_GOT_16 90
|
||||
#define R_HEX_LD_GOT_32_6_X 91
|
||||
#define R_HEX_LD_GOT_16_X 92
|
||||
#define R_HEX_LD_GOT_11_X 93
|
||||
#define R_HEX_23_REG 94
|
||||
#define R_HEX_GD_PLT_B22_PCREL_X 95
|
||||
#define R_HEX_GD_PLT_B32_PCREL_X 96
|
||||
#define R_HEX_LD_PLT_B22_PCREL_X 97
|
||||
#define R_HEX_LD_PLT_B32_PCREL_X 98
|
||||
#define R_HEX_27_REG 99
|
||||
|
||||
#endif /* elf-knowledge.h */
|
||||
|
||||
16
src/elf.h
16
src/elf.h
@ -831,6 +831,10 @@ typedef struct
|
||||
control. */
|
||||
#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* AArch64 pointer authentication
|
||||
enabled keys. */
|
||||
#define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers. */
|
||||
#define NT_ARM_ZA 0x40c /* ARM SME ZA registers. */
|
||||
#define NT_ARM_ZT 0x40d /* ARM SME ZT registers. */
|
||||
#define NT_ARM_FPMR 0x40e /* ARM floating point mode register. */
|
||||
#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */
|
||||
#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */
|
||||
#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */
|
||||
@ -1234,6 +1238,10 @@ typedef struct
|
||||
#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */
|
||||
#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */
|
||||
|
||||
/* More machine-dependent hints about processor capabilities. */
|
||||
#define AT_HWCAP3 29 /* extension of AT_HWCAP. */
|
||||
#define AT_HWCAP4 30 /* extension of AT_HWCAP. */
|
||||
|
||||
#define AT_EXECFN 31 /* Filename of executable. */
|
||||
|
||||
/* Pointer to the global system page used for system calls and other
|
||||
@ -1333,9 +1341,13 @@ typedef struct
|
||||
#define NT_GNU_PROPERTY_TYPE_0 5
|
||||
|
||||
/* Packaging metadata as defined on
|
||||
https://systemd.io/COREDUMP_PACKAGE_METADATA/ */
|
||||
https://systemd.io/ELF_PACKAGE_METADATA/ */
|
||||
#define NT_FDO_PACKAGING_METADATA 0xcafe1a7e
|
||||
|
||||
/* dlopen metadata as defined on
|
||||
https://systemd.io/ELF_DLOPEN_METADATA/ */
|
||||
#define NT_FDO_DLOPEN_METADATA 0x407c0c0a
|
||||
|
||||
/* Note section name of program property. */
|
||||
#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property"
|
||||
|
||||
@ -4237,6 +4249,8 @@ enum
|
||||
#define R_LARCH_TLS_TPREL32 10
|
||||
#define R_LARCH_TLS_TPREL64 11
|
||||
#define R_LARCH_IRELATIVE 12
|
||||
#define R_LARCH_TLS_DESC32 13
|
||||
#define R_LARCH_TLS_DESC64 14
|
||||
|
||||
/* Reserved for future relocs that the dynamic linker must understand. */
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ load_shdr_wrlock (Elf_Scn *scn)
|
||||
if (unlikely (notcvt == NULL))
|
||||
{
|
||||
__libelf_seterrno (ELF_E_NOMEM);
|
||||
goto out;
|
||||
goto free_and_out;
|
||||
}
|
||||
memcpy (notcvt, ((char *) elf->map_address
|
||||
+ elf->start_offset + ehdr->e_shoff),
|
||||
|
||||
@ -45,13 +45,26 @@ Elf_Data *
|
||||
elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src,
|
||||
unsigned int encode)
|
||||
{
|
||||
if (src == NULL || dest == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->d_type >= ELF_T_NUM)
|
||||
{
|
||||
__libelf_seterrno (ELF_E_UNKNOWN_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* First test whether the input data is really suitable for this
|
||||
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. */
|
||||
size_t recsize = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
|
||||
|
||||
if (src->d_size % recsize != 0)
|
||||
/* We shouldn't require integer number of records when processing
|
||||
notes. Payload bytes follow the header immediately, it's not an
|
||||
array of records as is the case otherwise. */
|
||||
if (src->d_type != ELF_T_NHDR && src->d_type != ELF_T_NHDR8
|
||||
&& src->d_size % recsize != 0)
|
||||
{
|
||||
__libelf_seterrno (ELF_E_INVALID_DATA);
|
||||
return NULL;
|
||||
|
||||
@ -45,6 +45,15 @@ Elf_Data *
|
||||
elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src,
|
||||
unsigned int encode)
|
||||
{
|
||||
if (src == NULL || dest == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src->d_type >= ELF_T_NUM)
|
||||
{
|
||||
__libelf_seterrno (ELF_E_UNKNOWN_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* First test whether the input data is really suitable for this
|
||||
type. This means, whether there is an integer number of records.
|
||||
Note that for this implementation the memory and file size of the
|
||||
|
||||
@ -439,6 +439,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
|
||||
/* So far only one block with sections. */
|
||||
elf->state.elf32.scns_last = &elf->state.elf32.scns;
|
||||
eu_search_tree_init (&elf->state.elf32.rawchunk_tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -536,6 +537,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
|
||||
/* So far only one block with sections. */
|
||||
elf->state.elf64.scns_last = &elf->state.elf64.scns;
|
||||
eu_search_tree_init (&elf->state.elf64.rawchunk_tree);
|
||||
}
|
||||
|
||||
return elf;
|
||||
|
||||
@ -42,19 +42,11 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
|
||||
if (elf == NULL)
|
||||
return -1;
|
||||
|
||||
if (elf->fildes == -1)
|
||||
{
|
||||
__libelf_seterrno (ELF_E_INVALID_HANDLE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rwlock_wrlock (elf->lock);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case ELF_C_FDREAD:
|
||||
/* If not all of the file is in the memory read it now. */
|
||||
if (elf->map_address == NULL && __libelf_readall (elf) == NULL)
|
||||
if (__libelf_readall (elf) == NULL)
|
||||
{
|
||||
/* We were not able to read everything. */
|
||||
result = -1;
|
||||
@ -64,7 +56,9 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
|
||||
|
||||
case ELF_C_FDDONE:
|
||||
/* Mark the file descriptor as not usable. */
|
||||
rwlock_wrlock (elf->lock);
|
||||
elf->fildes = -1;
|
||||
rwlock_unlock (elf->lock);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -73,7 +67,5 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
rwlock_unlock (elf->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -519,7 +519,17 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
|
||||
scn->rawdata.d.d_align = align;
|
||||
scn->rawdata.d.d_type = type;
|
||||
|
||||
/* Remove the old data. */
|
||||
Elf_Data_List *runp = scn->data_list.next;
|
||||
while (runp != NULL)
|
||||
{
|
||||
Elf_Data_List *oldp = runp;
|
||||
runp = runp->next;
|
||||
if ((oldp->flags & ELF_F_MALLOCED) != 0)
|
||||
free (oldp);
|
||||
}
|
||||
/* Existing existing data is no longer valid. */
|
||||
scn->data_list.next = NULL;
|
||||
scn->data_list_rear = NULL;
|
||||
if (scn->data_base != scn->rawdata_base)
|
||||
free (scn->data_base);
|
||||
|
||||
@ -126,13 +126,14 @@ elf_end (Elf *elf)
|
||||
|
||||
case ELF_K_ELF:
|
||||
{
|
||||
void *rawchunks
|
||||
search_tree *rawchunk_tree
|
||||
= (elf->class == ELFCLASS32
|
||||
|| (offsetof (struct Elf, state.elf32.rawchunks)
|
||||
== offsetof (struct Elf, state.elf64.rawchunks))
|
||||
? elf->state.elf32.rawchunks
|
||||
: elf->state.elf64.rawchunks);
|
||||
tdestroy (rawchunks, free_chunk);
|
||||
|| (offsetof (struct Elf, state.elf32.rawchunk_tree)
|
||||
== offsetof (struct Elf, state.elf64.rawchunk_tree))
|
||||
? &elf->state.elf32.rawchunk_tree
|
||||
: &elf->state.elf64.rawchunk_tree);
|
||||
|
||||
eu_search_tree_fini (rawchunk_tree, free_chunk);
|
||||
|
||||
Elf_ScnList *list = (elf->class == ELFCLASS32
|
||||
|| (offsetof (struct Elf, state.elf32.scns)
|
||||
|
||||
@ -33,12 +33,11 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <search.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libelfP.h"
|
||||
#include "common.h"
|
||||
#include "eu-search.h"
|
||||
|
||||
static int
|
||||
chunk_compare (const void *a, const void *b)
|
||||
@ -95,8 +94,9 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
|
||||
key.offset = offset;
|
||||
key.data.d.d_size = size;
|
||||
key.data.d.d_type = type;
|
||||
Elf_Data_Chunk **found = tsearch (&key, &elf->state.elf.rawchunks,
|
||||
&chunk_compare);
|
||||
Elf_Data_Chunk **found
|
||||
= eu_tsearch (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
|
||||
|
||||
if (found == NULL)
|
||||
goto nomem;
|
||||
|
||||
@ -136,7 +136,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
|
||||
if (rawchunk == NULL)
|
||||
{
|
||||
nomem:
|
||||
tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare);
|
||||
eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
|
||||
__libelf_seterrno (ELF_E_NOMEM);
|
||||
goto out;
|
||||
}
|
||||
@ -147,7 +147,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
|
||||
!= size))
|
||||
{
|
||||
/* Something went wrong. */
|
||||
tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare);
|
||||
eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare);
|
||||
free (rawchunk);
|
||||
__libelf_seterrno (ELF_E_READ_ERROR);
|
||||
goto out;
|
||||
|
||||
@ -46,5 +46,6 @@ elf_memory (char *image, size_t size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ_MMAP, NULL);
|
||||
return __libelf_read_mmaped_file (-1, image, 0, size,
|
||||
ELF_C_READ_MMAP_PRIVATE, NULL);
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ __libelf_readall (Elf *elf)
|
||||
|
||||
/* If this is an archive and we have derived descriptors get the
|
||||
locks for all of them. */
|
||||
libelf_acquire_all (elf);
|
||||
libelf_acquire_all_children (elf);
|
||||
|
||||
if (elf->maximum_size == ~((size_t) 0))
|
||||
{
|
||||
@ -141,7 +141,7 @@ __libelf_readall (Elf *elf)
|
||||
__libelf_seterrno (ELF_E_NOMEM);
|
||||
|
||||
/* Free the locks on the children. */
|
||||
libelf_release_all (elf);
|
||||
libelf_release_all_children (elf);
|
||||
}
|
||||
|
||||
rwlock_unlock (elf->lock);
|
||||
|
||||
@ -29,35 +29,7 @@
|
||||
#ifndef EU_CONFIG_H
|
||||
#define EU_CONFIG_H 1
|
||||
|
||||
#ifdef USE_LOCKS
|
||||
# include <pthread.h>
|
||||
# include <assert.h>
|
||||
# define rwlock_define(class,name) class pthread_rwlock_t name
|
||||
# define once_define(class,name) class pthread_once_t name = PTHREAD_ONCE_INIT
|
||||
# define RWLOCK_CALL(call) \
|
||||
({ int _err = pthread_rwlock_ ## call; assert_perror (_err); })
|
||||
# define ONCE_CALL(call) \
|
||||
({ int _err = pthread_ ## call; assert_perror (_err); })
|
||||
# define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL))
|
||||
# define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock))
|
||||
# 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 once(once_control, init_routine) \
|
||||
ONCE_CALL (once (&once_control, init_routine))
|
||||
#else
|
||||
/* Eventually we will allow multi-threaded applications to use the
|
||||
libraries. Therefore we will add the necessary locking although
|
||||
the macros used expand to nothing for now. */
|
||||
# define rwlock_define(class,name) class int name
|
||||
# define rwlock_init(lock) ((void) (lock))
|
||||
# define rwlock_fini(lock) ((void) (lock))
|
||||
# define rwlock_rdlock(lock) ((void) (lock))
|
||||
# define rwlock_wrlock(lock) ((void) (lock))
|
||||
# define rwlock_unlock(lock) ((void) (lock))
|
||||
# define once_define(class,name)
|
||||
# define once(once_control, init_routine) init_routine()
|
||||
#endif /* USE_LOCKS */
|
||||
#include "locks.h"
|
||||
|
||||
#include <libintl.h>
|
||||
/* gettext helper macros. */
|
||||
|
||||
64
src/eu-search.h
Normal file
64
src/eu-search.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* Calls for thread-safe tsearch/tfind
|
||||
Copyright (C) 2023 Rice University
|
||||
This file is part of elfutils.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
it under the terms of either
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at
|
||||
your option) any later version
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at
|
||||
your option) any later version
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
elfutils is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and
|
||||
the GNU Lesser General Public License along with this program. If
|
||||
not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef EU_SEARCH_H
|
||||
#define EU_SEARCH_H 1
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <search.h>
|
||||
#include <locks.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *root;
|
||||
rwlock_define (, lock);
|
||||
} search_tree;
|
||||
|
||||
/* Search TREE for KEY and add KEY if not found. Synchronized using
|
||||
TREE's lock. */
|
||||
extern void *eu_tsearch (const void *key, search_tree *tree,
|
||||
int (*compare)(const void *, const void *));
|
||||
|
||||
/* Search TREE for KEY. Synchronized with TREE's lock. */
|
||||
extern void *eu_tfind (const void *key, search_tree *tree,
|
||||
int (*compare)(const void *, const void *));
|
||||
|
||||
/* Delete key from TREE. Synchronized with TREE's lock. */
|
||||
extern void *eu_tdelete (const void *key, search_tree *tree,
|
||||
int (*compare)(const void *, const void *));
|
||||
|
||||
/* Free all nodes from TREE. */
|
||||
void eu_tdestroy (search_tree *tree, void (*free_node)(void *));
|
||||
|
||||
/* Initialize TREE's root and lock. */
|
||||
void eu_search_tree_init (search_tree *tree);
|
||||
|
||||
/* Free all nodes from TREE as well as TREE's lock. */
|
||||
void eu_search_tree_fini (search_tree *tree, void (*free_node)(void *));
|
||||
|
||||
#endif
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
#include <ar.h>
|
||||
#include <gelf.h>
|
||||
#include "eu-search.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
@ -323,7 +324,8 @@ struct Elf
|
||||
Elf_ScnList *scns_last; /* Last element in the section list.
|
||||
If NULL the data has not yet been
|
||||
read from the file. */
|
||||
void *rawchunks; /* Tree of elf_getdata_rawchunk results. */
|
||||
search_tree rawchunk_tree; /* Tree and lock for elf_getdata_rawchunk
|
||||
results. */
|
||||
unsigned int scnincr; /* Number of sections allocate the last
|
||||
time. */
|
||||
int ehdr_flags; /* Flags (dirty) for ELF header. */
|
||||
@ -342,7 +344,8 @@ struct Elf
|
||||
Elf_ScnList *scns_last; /* Last element in the section list.
|
||||
If NULL the data has not yet been
|
||||
read from the file. */
|
||||
void *rawchunks; /* Tree of elf_getdata_rawchunk results. */
|
||||
search_tree rawchunk_tree; /* Tree and lock for
|
||||
elf_getdata_rawchunk results. */
|
||||
unsigned int scnincr; /* Number of sections allocate the last
|
||||
time. */
|
||||
int ehdr_flags; /* Flags (dirty) for ELF header. */
|
||||
@ -367,7 +370,8 @@ struct Elf
|
||||
Elf_ScnList *scns_last; /* Last element in the section list.
|
||||
If NULL the data has not yet been
|
||||
read from the file. */
|
||||
void *rawchunks; /* Tree of elf_getdata_rawchunk results. */
|
||||
search_tree rawchunk_tree; /* Tree and lock for
|
||||
elf_getdata_rawchunk results. */
|
||||
unsigned int scnincr; /* Number of sections allocate the last
|
||||
time. */
|
||||
int ehdr_flags; /* Flags (dirty) for ELF header. */
|
||||
@ -617,4 +621,7 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
|
||||
#define INVALID_NDX(ndx, type, data) \
|
||||
unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
|
||||
|
||||
#define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff)
|
||||
#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff)
|
||||
#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff)
|
||||
#endif /* libelfP.h */
|
||||
|
||||
62
src/locks.h
Normal file
62
src/locks.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* Configuration definitions.
|
||||
Copyright (C) 2024 Red Hat, Inc.
|
||||
This file is part of elfutils.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
it under the terms of either
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at
|
||||
your option) any later version
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at
|
||||
your option) any later version
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
elfutils is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and
|
||||
the GNU Lesser General Public License along with this program. If
|
||||
not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOCKS_H
|
||||
#define LOCKS_H 1
|
||||
|
||||
#ifdef USE_LOCKS
|
||||
# include <pthread.h>
|
||||
# include <assert.h>
|
||||
# define rwlock_define(class,name) class pthread_rwlock_t name
|
||||
# define once_define(class,name) class pthread_once_t name = PTHREAD_ONCE_INIT
|
||||
# define RWLOCK_CALL(call) \
|
||||
({ int _err = pthread_rwlock_ ## call; assert_perror (_err); })
|
||||
# define ONCE_CALL(call) \
|
||||
({ int _err = pthread_ ## call; assert_perror (_err); })
|
||||
# define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL))
|
||||
# define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock))
|
||||
# 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 once(once_control, init_routine) \
|
||||
ONCE_CALL (once (&once_control, init_routine))
|
||||
#else
|
||||
/* Eventually we will allow multi-threaded applications to use the
|
||||
libraries. Therefore we will add the necessary locking although
|
||||
the macros used expand to nothing for now. */
|
||||
# define rwlock_define(class,name) class int name
|
||||
# define rwlock_init(lock) ((void) (lock))
|
||||
# define rwlock_fini(lock) ((void) (lock))
|
||||
# define rwlock_rdlock(lock) ((void) (lock))
|
||||
# define rwlock_wrlock(lock) ((void) (lock))
|
||||
# define rwlock_unlock(lock) ((void) (lock))
|
||||
# define once_define(class,name)
|
||||
# define once(once_control, init_routine) init_routine()
|
||||
#endif /* USE_LOCKS */
|
||||
|
||||
#endif /* locks.h */
|
||||
@ -27,6 +27,10 @@
|
||||
the GNU Lesser General Public License along with this program. If
|
||||
not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user