libelf: enable full elfutils package (#7431)

This commit is contained in:
Aditya Alok 2021-09-03 23:37:15 +05:30 committed by GitHub
parent 05ae16c447
commit 8ab480dda7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 1411 additions and 1319 deletions

View File

@ -0,0 +1,34 @@
similar to https://www.gnu.org/software/gnutls/clang/report-NwyD8A.html
--- argp-standalone-1.3/argp-help.c 2003-12-11 14:07:05.000000000 +0530
+++ argp-standalone-1.3-patch/argp-help.c 2021-08-30 20:06:23.807999907 +0530
@@ -726,15 +726,20 @@
canon_doc_option (const char **name)
{
int non_opt;
- /* Skip initial whitespace. */
- while (isspace ( (unsigned char) **name))
- (*name)++;
- /* Decide whether this looks like an option (leading `-') or not. */
- non_opt = (**name != '-');
- /* Skip until part of name used for sorting. */
- while (**name && !isalnum ( (unsigned char) **name))
- (*name)++;
- return non_opt;
+
+ if(!*name)
+ non_opt = 1;
+ else {
+ /* Skip initial whitespace. */
+ while (isspace ( (unsigned char) **name))
+ (*name)++;
+ /* Decide whether this looks like an option (leading `-') or not. */
+ non_opt = (**name != '-');
+ /* Skip until part of name used for sorting. */
+ while (**name && !isalnum ( (unsigned char) **name))
+ (*name)++;
+ return non_opt;
+ }
}
/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help

View File

@ -1,108 +0,0 @@
From 05d21996ba7b8cb7c8708ad8f7a6678d406e0936 Mon Sep 17 00:00:00 2001
From: Chih-Hung Hsieh <chh@google.com>
Date: Sun, 31 May 2020 14:03:51 +0100
Subject: [PATCH 2/3] Replace libdwfl nested functions with macros, part 1.
Prepare to compile with clang.
---
libdwfl/elf-from-memory.c | 77 +++++++++++++++++++++------------------
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index c54c1b9..143e124 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -229,29 +229,33 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
segments_end, segments_end_mem and loadbase (if not
found_base yet). Returns true if sanity checking failed,
false otherwise. */
- inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz, GElf_Xword memsz)
- {
- /* Sanity check the segment load aligns with the pagesize. */
- if (((vaddr - offset) & (pagesize - 1)) != 0)
- return true;
-
- GElf_Off segment_end = ((offset + filesz + pagesize - 1)
- & -pagesize);
-
- if (segment_end > (GElf_Off) contents_size)
- contents_size = segment_end;
-
- if (!found_base && (offset & -pagesize) == 0)
- {
- loadbase = ehdr_vma - (vaddr & -pagesize);
- found_base = true;
- }
-
- segments_end = offset + filesz;
- segments_end_mem = offset + memsz;
- return false;
- }
+ #define handle_segment(_vaddr, _offset, _filesz, _memsz) \
+ ( { \
+ bool result; \
+ GElf_Addr vaddr = _vaddr; \
+ GElf_Off offset = _offset; \
+ GElf_Xword filesz = _filesz; \
+ GElf_Xword memsz = _memsz; \
+ /* Sanity check the segment load aligns with the pagesize. */ \
+ if (((vaddr - offset) & (pagesize - 1)) != 0) \
+ result = true; \
+ else \
+ { \
+ result = false; \
+ GElf_Off segment_end = ((offset + filesz + pagesize - 1) \
+ & -pagesize); \
+ if (segment_end > (GElf_Off) contents_size) \
+ contents_size = segment_end; \
+ if (!found_base && (offset & -pagesize) == 0) \
+ { \
+ loadbase = ehdr_vma - (vaddr & -pagesize); \
+ found_base = true; \
+ } \
+ segments_end = offset + filesz; \
+ segments_end_mem = offset + memsz; \
+ } \
+ result; \
+ } )
case ELFCLASS32:
if (elf32_xlatetom (&xlateto, &xlatefrom,
@@ -309,18 +313,21 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
{
/* Reads the given segment. Returns true if reading fails,
false otherwise. */
- inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz)
- {
- GElf_Off start = offset & -pagesize;
- GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
- if (end > (GElf_Off) contents_size)
- end = contents_size;
- nread = (*read_memory) (arg, buffer + start,
- (loadbase + vaddr) & -pagesize,
- end - start, end - start);
- return nread <= 0;
- }
+ #undef handle_segment
+ #define handle_segment(_vaddr, _offset, _filesz) \
+ ( { \
+ GElf_Addr vaddr = _vaddr; \
+ GElf_Off offset = _offset; \
+ GElf_Xword filesz = _filesz; \
+ GElf_Off start = offset & -pagesize; \
+ GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize; \
+ if (end > (GElf_Off) contents_size) \
+ end = contents_size; \
+ nread = (*read_memory) (arg, buffer + start, \
+ (loadbase + vaddr) & -pagesize, \
+ end - start, end - start); \
+ (nread <= 0); \
+ } )
case ELFCLASS32:
for (uint_fast16_t i = 0; i < phnum; ++i)
--
2.26.2

View File

@ -1,484 +0,0 @@
From e0785056a91f893ef4235aefb2a26bed3b17537f Mon Sep 17 00:00:00 2001
From: Chih-Hung Hsieh <chh@google.com>
Date: Sun, 31 May 2020 14:06:12 +0100
Subject: [PATCH 3/3] For clang use Blocks instead of nested functions.
* Clang has Blocks like closures that can serve similar
purpose as the nested functions in gnu99.
Syntax of Blocks is similar to nested functions that
*NESTED_FUNC macro can be used for the function/block
declarations.
See spec in http://clang.llvm.org/docs/BlockLanguageSpec.html
* Local variables used in a closure should have __BLOCK
attribute unless they are constants.
* Formal parameters used in a closure should be copied
to local variable and declared as __BLOCK.
* Cannot goto and jump over __BLOCK variables, so these
variables have been moved to be declared before goto.
* Clang Blocks cannot copy an array to a closure,
and gcc complains about unbounded stack usage from alloca.
---
lib/nested_func.h | 85 +++++++++++++++++++
libdwfl/dwfl_segment_report_module.c | 117 ++++++++++++++++-----------
libdwfl/link_map.c | 31 ++++---
3 files changed, 174 insertions(+), 59 deletions(-)
create mode 100644 lib/nested_func.h
diff --git a/lib/nested_func.h b/lib/nested_func.h
new file mode 100644
index 0000000..be44a31
--- /dev/null
+++ b/lib/nested_func.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+ This file is part of elfutils.
+ Written by Chih-Hung Hsieh <chh@google.com>, 2015.
+
+ 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 _NESTED_FUNC_H
+#define _NESTED_FUNC_H 1
+
+#if __clang__
+
+ #define __BLOCK __block
+
+ #define NESTED_FUNC(return_type, function_name, \
+ arg_types, arg_types_and_names) \
+ return_type (^function_name) arg_types = \
+ ^ return_type arg_types_and_names
+
+ /* Clang does not like inline keyword before a block variable. */
+ #define INLINE_NESTED_FUNC(r, f, t, a) \
+ NESTED_FUNC (r, f, t, a)
+
+ #define INLINE_INTUSE_NESTED_FUNC(r, f, t, a) \
+ NESTED_FUNC (r, INTUSE(f), t, a)
+
+ /* Recrusive blocks need to be declared before used. */
+ #define RECURSIVE_NESTED_FUNC(return_type, function_name, \
+ arg_types, arg_types_and_names) \
+ __BLOCK return_type (^function_name) arg_types; \
+ function_name = ^ return_type arg_types_and_names
+
+ #define INLINE_RECURSIVE_NESTED_FUNC(r, f, t, a) \
+ RECURSIVE_NESTED_FUNC (r, f, t, a)
+
+ #define INLINE_INTUSE_RECURSIVE_NESTED_FUNC(r, f, t, a) \
+ RECURSIVE_NESTED_FUNC (r, INTUSE(f), t, a)
+
+#else /* gcc nested function */
+
+ #define __BLOCK
+
+ #define NESTED_FUNC(return_type, function_name, \
+ arg_types, arg_types_and_names) \
+ return_type function_name arg_types_and_names
+
+ #define INLINE_NESTED_FUNC(r, f, t, a) \
+ inline NESTED_FUNC (r, f, t, a)
+
+ #define INLINE_INTUSE_NESTED_FUNC(r, f, t, a) \
+ inline NESTED_FUNC (r, INTUSE(f), t, a)
+
+ #define RECURSIVE_NESTED_FUNC(r, f, t, a) \
+ NESTED_FUNC (r, f, t, a)
+
+ #define INLINE_RECURSIVE_NESTED_FUNC(r, f, t, a) \
+ inline RECURSIVE_NESTED_FUNC (r, f, t, a)
+
+ #define INLINE_INTUSE_RECURSIVE_NESTED_FUNC(r, f, t, a) \
+ INLINE_RECURSIVE_NESTED_FUNC (r, INTUSE(f), t, a)
+
+#endif
+
+#endif /* _NESTED_FUNC_H */
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index 430e13d..b7c6733 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -31,6 +31,7 @@
#undef _
#include "libdwflP.h"
#include "common.h"
+#include "nested_func.h"
#include <elf.h>
#include <gelf.h>
@@ -257,19 +258,23 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
GElf_Addr start = dwfl->lookup_addr[segment];
- inline bool segment_read (int segndx,
- void **buffer, size_t *buffer_available,
- GElf_Addr addr, size_t minread)
+ INLINE_NESTED_FUNC (bool, segment_read,
+ (int , void **, size_t *, GElf_Addr, size_t),
+ (int segndx,
+ void **buffer, size_t *buffer_available,
+ GElf_Addr addr, size_t minread))
{
return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
addr, minread, memory_callback_arg);
- }
+ };
- inline void release_buffer (void **buffer, size_t *buffer_available)
+ INLINE_NESTED_FUNC (void, release_buffer,
+ (void **, size_t *),
+ (void **buffer, size_t *buffer_available))
{
if (*buffer != NULL)
(void) segment_read (-1, buffer, buffer_available, 0, 0);
- }
+ };
/* First read in the file header and check its sanity. */
@@ -282,7 +287,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
here so we can always safely free it. */
void *phdrsp = NULL;
- inline int finish (void)
+ INLINE_NESTED_FUNC (int, finish, (void), (void))
{
free (phdrsp);
release_buffer (&buffer, &buffer_available);
@@ -291,15 +296,17 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
if (fd != -1)
close (fd);
return ndx;
- }
+ };
if (segment_read (ndx, &buffer, &buffer_available,
start, sizeof (Elf64_Ehdr))
|| memcmp (buffer, ELFMAG, SELFMAG) != 0)
return finish ();
- inline bool read_portion (void **data, size_t *data_size,
- GElf_Addr vaddr, size_t filesz)
+ INLINE_NESTED_FUNC (bool, read_portion,
+ (void **, size_t *, GElf_Addr, size_t),
+ (void **data, size_t *data_size,
+ GElf_Addr vaddr, size_t filesz))
{
/* Check whether we will have to read the segment data, or if it
can be returned from the existing buffer. */
@@ -320,13 +327,15 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
*data = vaddr - start + buffer;
*data_size = 0;
return false;
- }
+ };
- inline void finish_portion (void **data, size_t *data_size)
+ INLINE_NESTED_FUNC (void, finish_portion,
+ (void **, size_t *),
+ (void **data, size_t *data_size))
{
if (*data_size != 0)
release_buffer (data, data_size);
- }
+ };
/* Extract the information we need from the file header. */
const unsigned char *e_ident;
@@ -342,13 +351,13 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
uint_fast16_t phnum;
uint_fast16_t phentsize;
GElf_Off shdrs_end;
- Elf_Data xlatefrom =
+ __BLOCK Elf_Data xlatefrom =
{
.d_type = ELF_T_EHDR,
.d_buf = (void *) buffer,
.d_version = EV_CURRENT,
};
- Elf_Data xlateto =
+ __BLOCK Elf_Data xlateto =
{
.d_type = ELF_T_EHDR,
.d_buf = &ehdr,
@@ -433,32 +442,33 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
xlateto.d_size = phdrsp_bytes;
/* Track the bounds of the file visible in memory. */
- GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
- GElf_Off file_end = 0; /* Rounded up to effective page size. */
- GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
- GElf_Off total_filesz = 0; /* Total size of data to read. */
+ __BLOCK GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
+ __BLOCK GElf_Off file_end = 0; /* Rounded up to effective page size. */
+ __BLOCK GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
+ __BLOCK GElf_Off total_filesz = 0; /* Total size of data to read. */
/* Collect the bias between START and the containing PT_LOAD's p_vaddr. */
- GElf_Addr bias = 0;
- bool found_bias = false;
+ __BLOCK GElf_Addr bias = 0;
+ __BLOCK bool found_bias = false;
/* Collect the unbiased bounds of the module here. */
- GElf_Addr module_start = -1l;
- GElf_Addr module_end = 0;
- GElf_Addr module_address_sync = 0;
+ __BLOCK GElf_Addr module_start = -1l;
+ __BLOCK GElf_Addr module_end = 0;
+ __BLOCK GElf_Addr module_address_sync = 0;
/* If we see PT_DYNAMIC, record it here. */
- GElf_Addr dyn_vaddr = 0;
- GElf_Xword dyn_filesz = 0;
+ __BLOCK GElf_Addr dyn_vaddr = 0;
+ __BLOCK GElf_Xword dyn_filesz = 0;
/* Collect the build ID bits here. */
- void *build_id = NULL;
- size_t build_id_len = 0;
- GElf_Addr build_id_vaddr = 0;
+ __BLOCK void *build_id = NULL;
+ __BLOCK size_t build_id_len = 0;
+ __BLOCK GElf_Addr build_id_vaddr = 0;
/* Consider a PT_NOTE we've found in the image. */
- inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz,
- GElf_Xword align)
+ INLINE_NESTED_FUNC (void, consider_notes,
+ (GElf_Addr, GElf_Xword, GElf_Xword),
+ (GElf_Addr vaddr, GElf_Xword filesz, GElf_Xword align))
{
/* If we have already seen a build ID, we don't care any more. */
if (build_id != NULL || filesz == 0)
@@ -535,13 +545,18 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
if (notes != data)
free (notes);
finish_portion (&data, &data_size);
- }
+ };
/* Consider each of the program headers we've read from the image. */
- inline void consider_phdr (GElf_Word type,
- GElf_Addr vaddr, GElf_Xword memsz,
- GElf_Off offset, GElf_Xword filesz,
- GElf_Xword align)
+ INLINE_NESTED_FUNC (void, consider_phdr,
+ (GElf_Word,
+ GElf_Addr, GElf_Xword,
+ GElf_Off, GElf_Xword,
+ GElf_Xword),
+ (GElf_Word type,
+ GElf_Addr vaddr, GElf_Xword memsz,
+ GElf_Off offset, GElf_Xword filesz,
+ GElf_Xword align))
{
switch (type)
{
@@ -604,7 +619,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
module_end = vaddr_end;
break;
}
- }
+ };
Elf32_Phdr (*p32)[phnum] = phdrsp;
Elf64_Phdr (*p64)[phnum] = phdrsp;
@@ -751,11 +766,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
and they also tell us the essential portion of the file
for fetching symbols. */
- GElf_Addr soname_stroff = 0;
- GElf_Addr dynstr_vaddr = 0;
- GElf_Xword dynstrsz = 0;
- bool execlike = false;
- inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
+ __BLOCK GElf_Addr soname_stroff = 0;
+ __BLOCK GElf_Addr dynstr_vaddr = 0;
+ __BLOCK GElf_Xword dynstrsz = 0;
+ __BLOCK bool execlike = false;
+ INLINE_NESTED_FUNC (bool, consider_dyn, (GElf_Sxword, GElf_Xword),
+ (GElf_Sxword tag, GElf_Xword val))
{
switch (tag)
{
@@ -780,7 +796,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
}
return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
- }
+ };
const size_t dyn_entsize = (ei_class == ELFCLASS32
? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
@@ -915,25 +931,30 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
if (unlikely (contents == NULL))
return finish ();
- inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
+ INLINE_NESTED_FUNC (void, final_read,
+ (size_t, GElf_Addr, size_t),
+ (size_t offset, GElf_Addr vaddr, size_t size))
{
void *into = contents + offset;
size_t read_size = size;
(void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
&into, &read_size, vaddr, size);
- }
+ };
if (contiguous < file_trimmed_end)
{
/* We can't use the memory image verbatim as the file image.
So we'll be reading into a local image of the virtual file. */
- inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
- GElf_Off offset, GElf_Xword filesz)
+ INLINE_NESTED_FUNC (void, read_phdr,
+ (GElf_Word, GElf_Addr,
+ GElf_Off, GElf_Xword),
+ (GElf_Word type, GElf_Addr vaddr,
+ GElf_Off offset, GElf_Xword filesz))
{
if (type == PT_LOAD)
final_read (offset, vaddr + bias, filesz);
- }
+ };
if (ei_class == ELFCLASS32)
for (uint_fast16_t i = 0; i < phnum; ++i)
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 29307c7..05f4da2 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -30,6 +30,7 @@
#include "libdwflP.h"
#include "../libdw/memory-access.h"
#include "system.h"
+#include "nested_func.h"
#include <byteswap.h>
#include <endian.h>
@@ -245,20 +246,27 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
struct r_debug_info *r_debug_info)
{
/* Skip r_version, to aligned r_map field. */
- GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);
+ __BLOCK GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);
void *buffer = NULL;
size_t buffer_available = 0;
- inline int release_buffer (int result)
+ INLINE_NESTED_FUNC (int, release_buffer, (int), (int result))
{
if (buffer != NULL)
(void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
memory_callback_arg);
return result;
- }
+ };
+#if __clang__
+ /* Clang Blocks cannot copy an array to a closure. */
+ __BLOCK GElf_Addr *addrs = alloca(4 * sizeof (GElf_Addr));
+#else
+ /* gcc complains about unbounded stack usage from alloca. */
GElf_Addr addrs[4];
- inline bool read_addrs (GElf_Addr vaddr, size_t n)
+#endif
+ INLINE_NESTED_FUNC (bool, read_addrs,
+ (GElf_Addr, size_t), (GElf_Addr vaddr, size_t n))
{
size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */
@@ -301,7 +309,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
}
return false;
- }
+ };
if (unlikely (read_addrs (read_vaddr, 1)))
return release_buffer (-1);
@@ -754,12 +762,13 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
}
/* If we found the phdr dimensions, search phdrs for PT_DYNAMIC. */
- GElf_Addr dyn_vaddr = 0;
- GElf_Xword dyn_filesz = 0;
- GElf_Addr dyn_bias = (GElf_Addr) -1;
+ __BLOCK GElf_Addr dyn_vaddr = 0;
+ __BLOCK GElf_Xword dyn_filesz = 0;
+ __BLOCK GElf_Addr dyn_bias = (GElf_Addr) -1;
- inline bool consider_phdr (GElf_Word type,
- GElf_Addr vaddr, GElf_Xword filesz)
+ INLINE_NESTED_FUNC (bool, consider_phdr,
+ (GElf_Word, GElf_Addr, GElf_Xword),
+ (GElf_Word type, GElf_Addr vaddr, GElf_Xword filesz))
{
switch (type)
{
@@ -781,7 +790,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
}
return false;
- }
+ };
if (phdr != 0 && phnum != 0)
{
--- a/libdw/Makefile.am 2020-05-31 15:31:02.096994754 +0100
+++ b/libdw/Makefile.am 2020-05-31 15:31:38.456994741 +0100
@@ -109,7 +109,7 @@
../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \
../libdwfl/libdwfl_pic.a
libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
-libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(zip_LIBS) -pthread
+libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(zip_LIBS) -pthread -lBlocksRuntime
libdw_so_SOURCES =
libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index 47bd62a..cba562f 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -40,6 +40,7 @@ noinst_LIBRARIES += libdwfl_pic.a
pkginclude_HEADERS = libdwfl.h
+AM_CFLAGS += -fblocks
libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
dwfl_module.c dwfl_report_elf.c relocate.c \
dwfl_module_build_id.c dwfl_module_report_build_id.c \
--- a/config/libdw.pc.in 2020-05-31 15:57:15.036994154 +0100
+++ b/config/libdw.pc.in 2020-05-31 15:57:46.646994142 +0100
@@ -19,4 +19,4 @@
# data structures or functions. zlib (gz) is always required, bzip2 (bz2)
# lzma (xz) and zstd () are optional. But bzip2 doesn't have a pkg-config file.
Requires.private: zlib @LIBLZMA@ @LIBZSTD@
-Libs.private: @BZ2_LIB@
+Libs.private: @BZ2_LIB@ BlocksRuntime
--
2.26.2

View File

@ -19,49 +19,46 @@
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#if !defined (HAVE_POSIX_MEMALIGN)
# include <malloc.h>
#include <stdlib.h>
#if !defined(HAVE_POSIX_MEMALIGN)
#include <malloc.h>
#endif
void *aligned_alloc(size_t align, size_t size)
{
/* align must be a power of 2 */
/* size must be a multiple of align */
if ((align & (align - 1)) || (size & (align - 1)))
{
errno = EINVAL;
return NULL;
}
void *aligned_alloc(size_t align, size_t size) {
/* align must be a power of 2 */
/* size must be a multiple of align */
if ((align & (align - 1)) || (size & (align - 1))) {
errno = EINVAL;
return NULL;
}
#ifdef __ANDROID__
if (align < sizeof (void *)) /* POSIX does not allow small alignment */
align = sizeof (void *);
if (align < sizeof(void *)) /* POSIX does not allow small alignment */
align = sizeof(void *);
void *ptr;
int err = posix_memalign(&ptr, align, size);
if (err)
{
errno = err;
ptr = NULL;
}
return ptr;
void *ptr;
int err = posix_memalign(&ptr, align, size);
if (err) {
errno = err;
ptr = NULL;
}
return ptr;
#elif defined(HAVE_MEMALIGN)
return memalign(align, size);
#elif defined (_WIN32) && defined(__MINGW32__)
return __mingw_aligned_malloc(size, align);
#elif defined (_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, align);
return memalign(align, size);
#elif defined(_WIN32) && defined(__MINGW32__)
return __mingw_aligned_malloc(size, align);
#elif defined(_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, align);
#else
#warning unsupported aligned allocation!
if (size > 0)
errno = ENOMEM;
return NULL;
if (size > 0)
errno = ENOMEM;
return NULL;
#endif
}

View File

@ -2,22 +2,22 @@ TERMUX_PKG_HOMEPAGE=https://sourceware.org/elfutils/
TERMUX_PKG_DESCRIPTION="ELF object file access library"
TERMUX_PKG_LICENSE="GPL-2.0"
TERMUX_PKG_MAINTAINER="@termux"
# NOTE: We only build the libelf part of elfutils for now,
# as other parts are not clang compatible.
TERMUX_PKG_VERSION=0.182
TERMUX_PKG_SRCURL=ftp://sourceware.org/pub/elfutils/${TERMUX_PKG_VERSION}/elfutils-${TERMUX_PKG_VERSION}.tar.bz2
TERMUX_PKG_SHA256=ecc406914edf335f0b7fc084ebe6c460c4d6d5175bfdd6688c1c78d9146b8858
TERMUX_PKG_VERSION=0.185
TERMUX_PKG_SRCURL="https://sourceware.org/elfutils/ftp/${TERMUX_PKG_VERSION}/elfutils-${TERMUX_PKG_VERSION}.tar.bz2"
TERMUX_PKG_SHA256=dc8d3e74ab209465e7f568e1b3bb9a5a142f8656e2b57d10049a73da2ae6b5a6
# libandroid-support for langinfo.
TERMUX_PKG_DEPENDS="libandroid-support, zlib, libcurl"
TERMUX_PKG_BUILD_DEPENDS="argp"
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="ac_cv_c99=yes --disable-symbol-versioning --disable-debuginfod"
TERMUX_PKG_CONFLICTS="elfutils, libelf-dev"
TERMUX_PKG_REPLACES="elfutils, libelf-dev"
TERMUX_PKG_DEPENDS="libandroid-support, zlib, libcurl, libmicrohttpd, libsqlite, libarchive"
TERMUX_PKG_BUILD_DEPENDS="argp, libbz2, liblzma, zstd"
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="ac_cv_c99=yes --disable-symbol-versioning"
TERMUX_PKG_CONFLICTS="libelf-dev"
TERMUX_PKG_REPLACES="libelf-dev"
TERMUX_PKG_BUILD_IN_SRC=true
termux_step_pre_configure() {
CXXFLAGS+=" -Wno-unused-const-variable"
CFLAGS+=" -Wno-error=unused-value -Wno-error=format-nonliteral -Wno-error"
# Exposes ACCESSPERMS in <sys/stat.h> which elfutils uses:
# Exposes ACCESSPERMS in <sys/stat.h> which elfutils uses
CFLAGS+=" -D__USE_BSD"
CFLAGS+=" -DFNM_EXTMATCH=0"
@ -26,30 +26,11 @@ termux_step_pre_configure() {
CFLAGS="${CFLAGS/-Oz/-O1}"
fi
cp $TERMUX_PKG_BUILDER_DIR/error.h .
cp $TERMUX_PKG_BUILDER_DIR/stdio_ext.h .
cp $TERMUX_PKG_BUILDER_DIR/obstack.h .
cp $TERMUX_PKG_BUILDER_DIR/qsort_r.h .
cp $TERMUX_PKG_BUILDER_DIR/aligned_alloc.c libelf
autoreconf -if
}
cp -r $TERMUX_PKG_BUILDER_DIR/search src/
termux_step_make() {
make -j $TERMUX_MAKE_PROCESSES -C lib
make -j $TERMUX_MAKE_PROCESSES -C libelf
make -j $TERMUX_MAKE_PROCESSES -C libdwfl
make -j $TERMUX_MAKE_PROCESSES -C libebl
make -j $TERMUX_MAKE_PROCESSES -C backends
make -j $TERMUX_MAKE_PROCESSES -C libcpu
make -j $TERMUX_MAKE_PROCESSES -C libdwelf
make -j $TERMUX_MAKE_PROCESSES -C libdw
}
termux_step_make_install() {
make -j $TERMUX_MAKE_PROCESSES -C libelf install
make -j $TERMUX_MAKE_PROCESSES -C libdwfl install
make -j $TERMUX_MAKE_PROCESSES -C libdw install
make -j $TERMUX_MAKE_PROCESSES -C libasm install
make install-pkgincludeHEADERS
make -C config install
autoreconf -ivf
}

View File

@ -0,0 +1,29 @@
--- elfutils-0.185/configure.ac 2021-08-29 20:49:11.091999844 +0530
+++ elfutils-0.185-patch/configure.ac 2021-08-30 15:42:30.083999825 +0530
@@ -575,16 +575,6 @@
esac
AC_SUBST([fts_LIBS])
-saved_LIBS="$LIBS"
-AC_SEARCH_LIBS([_obstack_free], [obstack])
-LIBS="$saved_LIBS"
-case "$ac_cv_search__obstack_free" in
- no) AC_MSG_FAILURE([failed to find _obstack_free]) ;;
- -l*) obstack_LIBS="$ac_cv_search__obstack_free" ;;
- *) obstack_LIBS= ;;
-esac
-AC_SUBST([obstack_LIBS])
-
dnl The directories with content.
dnl Documentation.
@@ -747,8 +737,7 @@
fi
])
-AC_CHECK_LIB(pthread, pthread_setname_np, [
- AC_DEFINE([HAVE_PTHREAD_SETNAME_NP],[1],[Enable pthread_setname_np])])
+ AC_DEFINE([HAVE_PTHREAD_SETNAME_NP],[1],[Enable pthread_setname_np])
AS_IF([test "x$enable_libdebuginfod" = "xyes" || test "x$enable_libdebuginfod" = "xdummy"],
[AC_DEFINE([ENABLE_LIBDEBUGINFOD], [1], [Enable libdebuginfod])])

View File

@ -0,0 +1,23 @@
--- elfutils-0.185/debuginfod/debuginfod-client.c 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/debuginfod/debuginfod-client.c 2021-08-28 22:14:21.559999738 +0530
@@ -85,6 +85,20 @@
#include <sys/utsname.h>
#include <curl/curl.h>
+static int futimes(int fd, const struct timeval tv[2]) {
+ if (tv == NULL)
+ return syscall(__NR_utimensat, fd, NULL, NULL, 0);
+ if (tv[0].tv_usec < 0 || tv[0].tv_usec >= 1000000 || tv[1].tv_usec < 0 ||
+ tv[1].tv_usec >= 1000000) {
+ return -1;
+ }
+ // Convert timeval to timespec.
+ struct timespec ts[2];
+ TIMEVAL_TO_TIMESPEC(tv, ts);
+
+ return syscall(__NR_utimensat, fd, NULL, ts, 0);
+}
+
/* If fts.h is included before config.h, its indirect inclusions may not
give us the right LFS aliases of these functions, so map them manually. */
#ifdef BAD_FTS

View File

@ -0,0 +1,20 @@
--- elfutils-0.185/debuginfod/Makefile.am 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/debuginfod/Makefile.am 2021-08-29 00:51:31.449999941 +0530
@@ -42,7 +42,7 @@
if BUILD_STATIC
libasm = ../libasm/libasm.a
-libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
+libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl
libelf = ../libelf/libelf.a -lz
if DUMMY_LIBDEBUGINFOD
libdebuginfod = ./libdebuginfod.a
@@ -70,7 +70,7 @@
endif
debuginfod_SOURCES = debuginfod.cxx
-debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
+debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -ldl
debuginfod_find_SOURCES = debuginfod-find.c
debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS)

View File

@ -0,0 +1,38 @@
--- elfutils-0.185/debuginfod/debuginfod.cxx 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/debuginfod/debuginfod.cxx 2021-08-28 23:44:30.087999769 +0530
@@ -58,7 +58,6 @@
#include <fcntl.h>
#include <netdb.h>
-
/* If fts.h is included before config.h, its indirect inclusions may not
give us the right LFS aliases of these functions, so map them manually. */
#ifdef BAD_FTS
@@ -93,6 +92,7 @@
#include <libdwelf.h>
#include <microhttpd.h>
+#include <netinet/in.h>
#if MHD_VERSION >= 0x00097002
// libmicrohttpd 0.9.71 broke API
@@ -116,6 +116,19 @@
#define tid() pthread_self()
#endif
+static int futimes(int fd, const struct timeval tv[2]) {
+ if (tv == NULL)
+ return syscall(__NR_utimensat, fd, NULL, NULL, 0);
+ if (tv[0].tv_usec < 0 || tv[0].tv_usec >= 1000000 || tv[1].tv_usec < 0 ||
+ tv[1].tv_usec >= 1000000) {
+ return -1;
+ }
+ // Convert timeval to timespec.
+ struct timespec ts[2];
+ TIMEVAL_TO_TIMESPEC(tv, ts);
+
+ return syscall(__NR_utimensat, fd, NULL, ts, 0);
+}
inline bool
string_endswith(const string& haystack, const string& needle)

View File

@ -1,22 +0,0 @@
diff -u -r ../elfutils-0.166/libdwfl/dwfl_error.c ./libdwfl/dwfl_error.c
--- ../elfutils-0.166/libdwfl/dwfl_error.c 2015-11-27 08:36:29.000000000 -0500
+++ ./libdwfl/dwfl_error.c 2016-05-04 13:15:42.522820139 -0400
@@ -140,6 +140,7 @@
const char *
dwfl_errmsg (int error)
{
+ char* error_msg;
if (error == 0 || error == -1)
{
int last_error = global_error;
@@ -154,7 +155,9 @@
switch (error &~ 0xffff)
{
case OTHER_ERROR (ERRNO):
- return strerror_r (error & 0xffff, "bad", 0);
+ error_msg = malloc(256);
+ strerror_r (error & 0xffff, error_msg, 256);
+ return error_msg;
case OTHER_ERROR (LIBELF):
return elf_errmsg (error & 0xffff);
case OTHER_ERROR (LIBDW):

View File

@ -1,11 +0,0 @@
diff -u -r ../elfutils-0.166/libelf/elf_update.c ./libelf/elf_update.c
--- ../elfutils-0.166/libelf/elf_update.c 2015-11-27 08:36:29.000000000 -0500
+++ ./libelf/elf_update.c 2016-05-04 13:06:15.836140729 -0400
@@ -39,6 +39,7 @@
#include "libelfP.h"
+#define off_t loff_t
static off_t
write_file (Elf *elf, off_t size, int change_bo, size_t shnum)

View File

@ -0,0 +1,3 @@
TERMUX_SUBPKG_DESCRIPTION="A collection of utilities to read, create and modify ELF binary files"
TERMUX_SUBPKG_INCLUDE="bin/eu-* bin/debuginfod* etc/profile.d/debuginfod.* share/man/man8/* share/man/man1/*"
TERMUX_SUBPKG_DEPENDS="libasm, libdw, libdebuginfod"

View File

@ -1,25 +0,0 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/* program_invocation_short_name GNU extension - http://linux.die.net/man/3/program_invocation_short_name */
extern char* __progname;
#define program_invocation_short_name __progname
/* error(3) GNU extension - http://man7.org/linux/man-pages/man3/error.3.html */
unsigned int error_message_count;
static inline void error(int status, int errnum, const char* format, ...) {
error_message_count++;
va_list myargs;
va_start(myargs, format);
vfprintf(stderr, format, myargs);
va_end(myargs);
exit(status);
}
/* strchrnul(3) GNU extension - http://man7.org/linux/man-pages/man3/strchr.3.html */
static inline char* strchrnul(char const* s, int c)
{
char* result = strchr(s, c);
return (result == NULL) ? (char*)(s + strlen(s)) : result;
}

View File

@ -0,0 +1,2 @@
TERMUX_SUBPKG_DESCRIPTION="Library for debuginfod"
TERMUX_SUBPKG_INCLUDE="lib/libdebuginfod*.so* include/elfutils/debuginfod.h lib/pkgconfig/libdebuginfod.pc share/man/man3/debuginfod_*"

View File

@ -1,14 +0,0 @@
diff -u -r ../elfutils-0.166/libdwfl/libdwflP.h ./libdwfl/libdwflP.h
--- ../elfutils-0.166/libdwfl/libdwflP.h 2016-01-12 07:49:19.000000000 -0500
+++ ./libdwfl/libdwflP.h 2016-05-04 13:21:07.997599838 -0400
@@ -771,5 +771,10 @@
/* The default used by dwfl_standard_find_debuginfo. */
#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
+ /* canonicalize_file_name GNU extension - http://man7.org/linux/man-pages/man3/canonicalize_file_name.3.html */
+inline static char* canonicalize_file_name(const char *path)
+{
+ return realpath(path, NULL);
+}
#endif /* libdwflP.h */

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,8 @@
/* https://raw.githubusercontent.com/android/platform_bionic/master/libc/upstream-freebsd/lib/libc/stdlib/qsort.c */
#define I_AM_QSORT_R
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -31,56 +29,41 @@
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
// __FBSDID("$FreeBSD: head/lib/libc/stdlib/qsort.c 334928 2018-06-10 17:54:44Z
// kib $");
#include <stdlib.h>
#ifdef I_AM_QSORT_R
typedef int cmp_t(void *, const void *, const void *);
typedef int cmp_t(void *, const void *, const void *);
#else
typedef int cmp_t(const void *, const void *);
typedef int cmp_t(const void *, const void *);
#endif
static inline char *med3(char *, char *, char *, cmp_t *, void *);
static inline void swapfunc(char *, char *, int, int);
static inline char *med3(char *, char *, char *, cmp_t *, void *);
#define min(a, b) (a) < (b) ? a : b
#define MIN(a, b) ((a) < (b) ? a : b)
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#define swapcode(TYPE, parmi, parmj, n) { \
long i = (n) / sizeof (TYPE); \
TYPE *pi = (TYPE *) (parmi); \
TYPE *pj = (TYPE *) (parmj); \
do { \
TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
} while (--i > 0); \
static inline void swapfunc(char *a, char *b, size_t es) {
char t;
do {
t = *a;
*a++ = *b;
*b++ = t;
} while (--es > 0);
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static inline void
swapfunc(a, b, n, swaptype)
char *a, *b;
int n, swaptype;
{
if(swaptype <= 1)
swapcode(long, a, b, n)
else
swapcode(char, a, b, n)
}
#define swap(a, b) \
if (swaptype == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
} else \
swapfunc(a, b, es, swaptype)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
#define vecswap(a, b, n) \
if ((n) > 0) \
swapfunc(a, b, n)
#ifdef I_AM_QSORT_R
#define CMP(t, x, y) (cmp((t), (x), (y)))
@ -88,108 +71,123 @@ swapfunc(a, b, n, swaptype)
#define CMP(t, x, y) (cmp((x), (y)))
#endif
static inline char *
med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
static inline char *med3(char *a, char *b, char *c, cmp_t *cmp,
void *thunk
#ifndef I_AM_QSORT_R
__unused
__unused
#endif
)
{
return CMP(thunk, a, b) < 0 ?
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
:(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
) {
return CMP(thunk, a, b) < 0
? (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a))
: (CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c));
}
#ifdef I_AM_QSORT_R
void
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
void qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
#else
#define thunk NULL
void
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
void qsort(void *a, size_t n, size_t es, cmp_t *cmp)
#endif
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
size_t d, r;
int cmp_result;
int swaptype, swap_cnt;
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
size_t d1, d2;
int cmp_result;
int swap_cnt;
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm;
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pm = (char *)a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *)a + (n - 1) * es;
if (n > 40) {
d = (n / 8) * es;
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
pm = med3(pm - d, pm, pm + d, cmp, thunk);
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
}
pm = med3(pl, pm, pn, cmp, thunk);
}
swap(a, pm);
pa = pb = (char *)a + es;
loop:
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es)
swapfunc(pl, pl - es, es);
return;
}
pm = (char *)a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *)a + (n - 1) * es;
if (n > 40) {
size_t d = (n / 8) * es;
pc = pd = (char *)a + (n - 1) * es;
for (;;) {
while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
pb += es;
}
while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm;
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
pm = med3(pm - d, pm, pm + d, cmp, thunk);
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
}
pm = med3(pl, pm, pn, cmp, thunk);
}
swapfunc(a, pm, es);
pa = pb = (char *)a + es;
pn = (char *)a + n * es;
r = min(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r);
r = min(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
pc = pd = (char *)a + (n - 1) * es;
for (;;) {
while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swapfunc(pa, pb, es);
pa += es;
}
pb += es;
}
while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swapfunc(pc, pd, es);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swapfunc(pb, pc, es);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es)
swapfunc(pl, pl - es, es);
return;
}
pn = (char *)a + n * es;
d1 = MIN(pa - (char *)a, pb - pa);
vecswap(a, pb - d1, d1);
d1 = MIN(pd - pc, pn - pd - es);
vecswap(pb, pn - d1, d1);
d1 = pb - pa;
d2 = pd - pc;
if (d1 <= d2) {
/* Recurse on left partition, then iterate on right partition */
if (d1 > es) {
#ifdef I_AM_QSORT_R
qsort_r(a, r / es, es, thunk, cmp);
qsort_r(a, d1 / es, es, thunk, cmp);
#else
qsort(a, r / es, es, cmp);
qsort(a, d1 / es, es, cmp);
#endif
if ((r = pd - pc) > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;
goto loop;
}
/* qsort(pn - r, r / es, es, cmp);*/
}
if (d2 > es) {
/* Iterate rather than recurse to save stack space */
/* qsort(pn - d2, d2 / es, es, cmp); */
a = pn - d2;
n = d2 / es;
goto loop;
}
} else {
/* Recurse on right partition, then iterate on left partition */
if (d2 > es) {
#ifdef I_AM_QSORT_R
qsort_r(pn - d2, d2 / es, es, thunk, cmp);
#else
qsort(pn - d2, d2 / es, es, cmp);
#endif
}
if (d1 > es) {
/* Iterate rather than recurse to save stack space */
/* qsort(a, d1 / es, es, cmp); */
n = d1 / es;
goto loop;
}
}
}

View File

@ -0,0 +1,67 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
//__FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate.c 326193 2017-11-25 17:12:48Z
//pfg $");
#include "search.h"
#include <stdbool.h>
#include <stddef.h>
/*
* Thread unsafe interface: use a single process-wide hash table and
* forward calls to *_r() functions.
*/
static struct hsearch_data global_hashtable;
static bool global_hashtable_initialized = false;
int hcreate(size_t nel) { return (1); }
void hdestroy(void) {
/* Destroy global hash table if present. */
if (global_hashtable_initialized) {
hdestroy_r(&global_hashtable);
global_hashtable_initialized = false;
}
}
ENTRY *hsearch(ENTRY item, ACTION action) {
ENTRY *retval;
/* Create global hash table if needed. */
if (!global_hashtable_initialized) {
if (hcreate_r(0, &global_hashtable) == 0)
return (NULL);
global_hashtable_initialized = true;
}
if (hsearch_r(item, action, &retval, &global_hashtable) == 0)
return (NULL);
return (retval);
}

View File

@ -0,0 +1,62 @@
/*-
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
// __FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate_r.c 292767 2015-12-27
// 07:50:11Z ed $");
#include "search.h"
#include <stdlib.h>
#include "hsearch.h"
int hcreate_r(size_t nel, struct hsearch_data *htab) {
struct __hsearch *hsearch;
/*
* Allocate a hash table object. Ignore the provided hint and start
* off with a table of sixteen entries. In most cases this hint is
* just a wild guess. Resizing the table dynamically if the use
* increases a threshold does not affect the worst-case running time.
*/
hsearch = malloc(sizeof(*hsearch));
if (hsearch == NULL)
return 0;
hsearch->entries = calloc(16, sizeof(ENTRY));
if (hsearch->entries == NULL) {
free(hsearch);
return 0;
}
/*
* Pick a random initialization for the FNV-1a hashing. This makes it
* hard to come up with a fixed set of keys to force hash collisions.
*/
arc4random_buf(&hsearch->offset_basis, sizeof(hsearch->offset_basis));
hsearch->index_mask = 0xf;
hsearch->entries_used = 0;
htab->__hsearch = hsearch;
return 1;
}

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
// __FBSDID("$FreeBSD: head/lib/libc/stdlib/hdestroy_r.c 292767 2015-12-27
// 07:50:11Z ed $");
#include "search.h"
#include <stdlib.h>
#include "hsearch.h"
void hdestroy_r(struct hsearch_data *htab) {
struct __hsearch *hsearch;
/* Free hash table object and its entries. */
hsearch = htab->__hsearch;
free(hsearch->entries);
free(hsearch);
}

View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: head/lib/libc/stdlib/hsearch.h 292767 2015-12-27 07:50:11Z ed $
*/
#ifndef HSEARCH_H
#define HSEARCH_H
#include "search.h"
struct __hsearch {
size_t offset_basis; /* Initial value for FNV-1a hashing. */
size_t index_mask; /* Bitmask for indexing the table. */
size_t entries_used; /* Number of entries currently used. */
ENTRY *entries; /* Hash table entries. */
};
#endif

View File

@ -0,0 +1,144 @@
/*-
* Copyright (c) 2015 Nuxi, https://nuxi.nl/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
// __FBSDID("$FreeBSD: head/lib/libc/stdlib/hsearch_r.c 292767 2015-12-27
// 07:50:11Z ed $");
#include "search.h"
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "hsearch.h"
/*
* Look up an unused entry in the hash table for a given hash. For this
* implementation we use quadratic probing. Quadratic probing has the
* advantage of preventing primary clustering.
*/
static ENTRY *hsearch_lookup_free(struct __hsearch *hsearch, size_t hash) {
size_t index, i;
for (index = hash, i = 0;; index += ++i) {
ENTRY *entry = &hsearch->entries[index & hsearch->index_mask];
if (entry->key == NULL)
return (entry);
}
}
/*
* Computes an FNV-1a hash of the key. Depending on the pointer size, this
* either uses the 32- or 64-bit FNV prime.
*/
static size_t hsearch_hash(size_t offset_basis, const char *str) {
size_t hash;
hash = offset_basis;
while (*str != '\0') {
hash ^= (uint8_t)*str++;
if (sizeof(size_t) * CHAR_BIT <= 32)
hash *= UINT32_C(16777619);
else
hash *= UINT64_C(1099511628211);
}
return (hash);
}
int hsearch_r(ENTRY item, ACTION action, ENTRY **retval,
struct hsearch_data *htab) {
struct __hsearch *hsearch;
ENTRY *entry, *old_entries, *new_entries;
size_t hash, index, i, old_hash, old_count, new_count;
hsearch = htab->__hsearch;
hash = hsearch_hash(hsearch->offset_basis, item.key);
/*
* Search the hash table for an existing entry for this key.
* Stop searching if we run into an unused hash table entry.
*/
for (index = hash, i = 0;; index += ++i) {
entry = &hsearch->entries[index & hsearch->index_mask];
if (entry->key == NULL)
break;
if (strcmp(entry->key, item.key) == 0) {
*retval = entry;
return (1);
}
}
/* Only perform the insertion if action is set to ENTER. */
if (action == FIND) {
errno = ESRCH;
return (0);
}
if (hsearch->entries_used * 2 >= hsearch->index_mask) {
/* Preserve the old hash table entries. */
old_count = hsearch->index_mask + 1;
old_entries = hsearch->entries;
/*
* Allocate and install a new table if insertion would
* yield a hash table that is more than 50% used. By
* using 50% as a threshold, a lookup will only take up
* to two steps on average.
*/
new_count = (hsearch->index_mask + 1) * 2;
new_entries = calloc(new_count, sizeof(ENTRY));
if (new_entries == NULL)
return (0);
hsearch->entries = new_entries;
hsearch->index_mask = new_count - 1;
/* Copy over the entries from the old table to the new table. */
for (i = 0; i < old_count; ++i) {
entry = &old_entries[i];
if (entry->key != NULL) {
old_hash = hsearch_hash(hsearch->offset_basis, entry->key);
*hsearch_lookup_free(hsearch, old_hash) = *entry;
}
}
/* Destroy the old hash table entries. */
free(old_entries);
/*
* Perform a new lookup for a free table entry, so that
* we insert the entry into the new hash table.
*/
hsearch = htab->__hsearch;
entry = hsearch_lookup_free(hsearch, hash);
}
/* Insert the new entry into the hash table. */
*entry = item;
++hsearch->entries_used;
*retval = entry;
return (1);
}

View File

@ -0,0 +1,225 @@
/*-
* Written by J.T. Conklin <jtc@netbsd.org>
* Public domain.
*
* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
* $FreeBSD: release/9.0.0/include/search.h 105250 2002-10-16 14:29:23Z robert $
*/
#pragma once
/**
* @file search.h
* @brief Queues, hash tables, trees, and linear array searches.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
/** See hsearch()/hsearch_r(). */
typedef enum { FIND, ENTER } ACTION;
/** See hsearch()/hsearch_r(). */
typedef struct entry {
/** The string key. */
char *key;
/** The associated data. */
void *data;
} ENTRY;
/**
* Constants given to the twalk() visitor.
* Note that the constant names are misleading.
*/
typedef enum {
/**
* If this is the first visit to a non-leaf node.
* Use this for *preorder* traversal.
*/
preorder,
/**
* If this is the second visit to a non-leaf node.
* Use this for *inorder* traversal.
*/
postorder,
/**
* If this is the third visit to a non-leaf node.
* Use this for *postorder* traversal.
*/
endorder,
/** If this is the first and only visit to a leaf node. */
leaf
} VISIT;
#if defined(__USE_BSD) || defined(__USE_GNU)
/** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */
struct hsearch_data {
struct __hsearch *__hsearch;
};
#endif
__BEGIN_DECLS
/**
* [insque(3)](http://man7.org/linux/man-pages/man3/insque.3.html) inserts
* an item in a queue (an intrusive doubly-linked list).
*
* Available since API level 21.
*/
void insque(void *__element, void *__previous) ;
/**
* [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
* an item from a queue (an intrusive doubly-linked list).
*
* Available since API level 21.
*/
void remque(void *__element) ;
/**
* [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
* initializes the global hash table, with space for at least `__n` elements.
*
* See hcreate_r() if you need more than one hash table.
*
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
*
* Available since API level 28.
*/
int hcreate(size_t __n) ;
/**
* [hdestroy(3)](http://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
* the global hash table.
*
* See hdestroy_r() if you need more than one hash table.
*
* Available since API level 28.
*/
void hdestroy(void) ;
/**
* [hsearch(3)](http://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
* inserts `__entry` in the global hash table, based on `__action`.
*
* See hsearch_r() if you need more than one hash table.
*
* Returns a pointer to the entry on success, and returns NULL and sets
* `errno` on failure.
*
* Available since API level 28.
*/
ENTRY *hsearch(ENTRY __entry, ACTION __action) ;
#if defined(__USE_BSD) || defined(__USE_GNU)
/**
* [hcreate_r(3)](http://man7.org/linux/man-pages/man3/hcreate_r.3.html)
* initializes a hash table `__table` with space for at least `__n` elements.
*
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
*
* Available since API level 28.
*/
int hcreate_r(size_t __n, struct hsearch_data *__table) ;
/**
* [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html)
* destroys the hash table `__table`.
*
* Available since API level 28.
*/
void hdestroy_r(struct hsearch_data *__table) ;
/**
* [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds
* or inserts `__entry` in the hash table `__table`, based on `__action`.
*
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
* A pointer to the entry is returned in `*__result`.
*
* Available since API level 28.
*/
int hsearch_r(ENTRY __entry, ACTION __action, ENTRY **__result,
struct hsearch_data *__table) ;
#endif
/**
* [lfind(3)](http://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
* searches the unsorted array `__array` (of `__count` items each of size
* `__size`) for `__key`, using `__comparator`.
*
* See bsearch() if you have a sorted array.
*
* Returns a pointer to the matching element on success, or NULL on failure.
*
* Available since API level 21.
*/
void *lfind(const void *__key, const void *__array, size_t *__count,
size_t __size, int (*__comparator)(const void *, const void *))
;
/**
* [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
* searches the unsorted array `__array` (of `__count` items each of size
* `__size`) for `__key`, using `__comparator`.
*
* Unlike lfind(), on failure lsearch() will *insert* `__key` at the end of
* `__array` and increment `*__count`.
*
* Returns a pointer to the matching element on success, or to the newly-added
* element on failure.
*
* Available since API level 21.
*/
void *lsearch(const void *__key, void *__array, size_t *__count, size_t __size,
int (*__comparator)(const void *, const void *))
;
/**
* [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
* for and removes an element in the tree `*__root_ptr`. The search is performed
* using `__comparator`.
*
* Returns a pointer to the parent of the deleted node, or NULL on failure.
*/
void *tdelete(const void *__key, void **__root_ptr,
int (*__comparator)(const void *, const void *));
/**
* [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
* the hash table `__root` using `__free_fn` on each node.
*/
void tdestroy(void *__root, void (*__free_fn)(void *));
/**
* [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
* for an element in the tree `*__root_ptr`. The search is performed using
* `__comparator`.
*
* Returns a pointer to the matching node, or NULL on failure.
*/
void *tfind(const void *__key, void *const *__root_ptr,
int (*__comparator)(const void *, const void *));
/**
* [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches
* for an element in the tree `*__root_ptr`. The search is performed using
* `__comparator`.
*
* Unlike tfind(), on failure tsearch() will *insert* `__key` into the tree.
*
* Returns a pointer to the matching node, or to the newly-added node.
*/
void *tsearch(const void *__key, void **__root_ptr,
int (*__comparator)(const void *, const void *));
/**
* [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls
* `__visitor` on every node in the tree.
*/
void twalk(const void *__root, void (*__visitor)(const void *, VISIT, int))
;
__END_DECLS

View File

@ -0,0 +1,11 @@
--- elfutils-0.185/src/ar.c 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/src/ar.c 2021-08-29 20:21:23.873999934 +0530
@@ -27,7 +27,7 @@
#include <libintl.h>
#include <limits.h>
#include <locale.h>
-#include <search.h>
+#include "search/search.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

View File

@ -0,0 +1,11 @@
--- elfutils-0.185/src/elflint.c 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/src/elflint.c 2021-08-29 21:49:43.425999943 +0530
@@ -3434,7 +3434,7 @@
return p - (const unsigned char *) data->d_buf;
}
-inline size_t
+static inline size_t
buffer_left (Elf_Data *data, const unsigned char *p)
{
return (const unsigned char *) data->d_buf + data->d_size - p;

View File

@ -0,0 +1,23 @@
--- elfutils-0.185/src/Makefile.am 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/src/Makefile.am 2021-08-29 20:44:45.441999945 +0530
@@ -33,6 +33,11 @@
libar_a_SOURCES = arlib.c arlib2.c arlib-argp.c
+libar_a_SOURCES += search/hcreate.c \
+ search/hcreate_r.c \
+ search/hsearch_r.c \
+ search/hdestroy_r.c
+
EXTRA_DIST = arlib.h debugpred.h
bin_SCRIPTS = make-debug-archive
@@ -41,7 +46,7 @@
if BUILD_STATIC
libasm = ../libasm/libasm.a
-libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl -lpthread
+libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl
libelf = ../libelf/libelf.a -lz
else
libasm = ../libasm/libasm.so

View File

@ -1,11 +0,0 @@
diff -u -r ../elfutils-0.170/src/readelf.c ./src/readelf.c
--- ../elfutils-0.170/src/readelf.c 2017-08-02 14:06:25.000000000 +0200
+++ ./src/readelf.c 2017-12-10 01:14:25.898858528 +0100
@@ -43,6 +43,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
+#include <qsort_r.h>
#include <libeu.h>
#include <system.h>

View File

@ -0,0 +1,26 @@
--- elfutils-0.185/src/readelf.c 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/src/readelf.c 2021-08-29 13:17:30.120999962 +0530
@@ -8763,13 +8763,16 @@
/* Apply the "operation advance" from a special opcode
or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
unsigned int op_addr_advance;
- inline void advance_pc (unsigned int op_advance)
- {
- op_addr_advance = minimum_instr_len * ((op_index + op_advance)
- / max_ops_per_instr);
- address += op_addr_advance;
- op_index = (op_index + op_advance) % max_ops_per_instr;
- }
+ #define advance_pc(op_advance_arg) \
+ ({ \
+ unsigned int op_advance = op_advance_arg; \
+ op_addr_advance = \
+ minimum_instr_len * ((op_index + (op_advance)) / max_ops_per_instr); \
+ address += (op_advance); \
+ op_index = (op_index + (op_advance)) % max_ops_per_instr; \
+ })
+
+
if (max_ops_per_instr == 0)
{

View File

@ -7,41 +7,28 @@
#define FSETLOCKING_INTERNAL 1
#define FSETLOCKING_BYCALLER 2
#define FSETLOCKING_QUERY 3
static inline int __fsetlocking(FILE *stream, int type)
{
(void) stream;
(void) type;
return FSETLOCKING_INTERNAL;
static inline int __fsetlocking(FILE *stream, int type) {
(void)stream;
(void)type;
return FSETLOCKING_INTERNAL;
}
static inline int feof_unlocked(FILE *stream)
{
return feof(stream);
static inline int fputs_unlocked(const char *s, FILE *stream) {
return fputs(s, stream);
}
static inline int ferror_unlocked(FILE *stream)
{
return ferror(stream);
static inline int fputc_unlocked(int c, FILE *stream) {
return fputc(c, stream);
}
static inline int fputs_unlocked(const char *s, FILE *stream)
{
return fputs(s, stream);
static inline size_t fread_unlocked(void *data, size_t size, size_t count,
FILE *stream) {
return fread(data, size, count, stream);
}
static inline int fputc_unlocked(int c, FILE *stream)
{
return fputc(c, stream);
}
static inline size_t fread_unlocked(void *data, size_t size, size_t count, FILE *stream)
{
return fread(data, size, count, stream);
}
static inline size_t fwrite_unlocked(const void *data, size_t size, size_t count, FILE *stream)
{
return fwrite(data, size, count, stream);
static inline size_t fwrite_unlocked(const void *data, size_t size,
size_t count, FILE *stream) {
return fwrite(data, size, count, stream);
}
#endif

View File

@ -0,0 +1,12 @@
--- elfutils-0.185/lib/system.h 2021-05-22 23:55:24.000000000 +0530
+++ elfutils-0.185-patch/lib/system.h 2021-08-29 15:35:57.670999911 +0530
@@ -39,6 +39,9 @@
#include <unistd.h>
#include <string.h>
+extern char* __progname;
+#define program_invocation_short_name __progname
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define LE32(n) (n)
# define LE64(n) (n)