forked from rpms/elfutils
		
	import CS elfutils-0.189-3.el8
This commit is contained in:
		
							parent
							
								
									083ad3b547
								
							
						
					
					
						commit
						15a1c9c996
					
				| @ -1 +1 @@ | ||||
| 5e23c010b7f9f45140a43e95d8d1f7fb04aa8302 SOURCES/elfutils-0.188.tar.bz2 | ||||
| a4b4a20bf3976e71c280b6dfb8443dbdcdd3f2f0 SOURCES/elfutils-0.189.tar.bz2 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | ||||
| SOURCES/elfutils-0.188.tar.bz2 | ||||
| SOURCES/elfutils-0.189.tar.bz2 | ||||
|  | ||||
| @ -1,109 +0,0 @@ | ||||
| commit 75f2de448f311807e2493f2a37a980e2d872b229 | ||||
| Author: Mark Wielaard <mark@klomp.org> | ||||
| Date:   Thu Nov 3 13:38:45 2022 +0100 | ||||
| 
 | ||||
|     readelf: Check phdr != NULL or shdr != NULL in handle_dynamic. | ||||
|      | ||||
|     The compiler doesn't know that when use_dynamic_segment is true, | ||||
|     then phdr should/will be non-NULL and otherwise shdr is non-NULL. | ||||
|     Add explicit checks to help the compiler out and in case an error | ||||
|     is made calling the handle_dynamic function. | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| 
 | ||||
| diff --git a/src/readelf.c b/src/readelf.c
 | ||||
| index 0e0b05c4..e721a209 100644
 | ||||
| --- a/src/readelf.c
 | ||||
| +++ b/src/readelf.c
 | ||||
| @@ -1828,7 +1828,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
 | ||||
|    size_t dyn_ents; | ||||
|   | ||||
|    /* Get the data of the section.  */ | ||||
| -  if (use_dynamic_segment)
 | ||||
| +  if (use_dynamic_segment && phdr != NULL)
 | ||||
|      data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset, | ||||
|  				phdr->p_filesz, ELF_T_DYN); | ||||
|    else | ||||
| @@ -1840,7 +1840,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
 | ||||
|    /* Get the dynamic section entry number */ | ||||
|    dyn_ents = get_dyn_ents (data); | ||||
|   | ||||
| -  if (!use_dynamic_segment)
 | ||||
| +  if (!use_dynamic_segment && shdr != NULL)
 | ||||
|      { | ||||
|        /* Get the section header string table index.  */ | ||||
|        if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) | ||||
| @@ -1862,7 +1862,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
 | ||||
|  	      (int) shdr->sh_link, | ||||
|  	      elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | ||||
|      } | ||||
| -  else
 | ||||
| +  else if (phdr != NULL)
 | ||||
|      { | ||||
|        printf (ngettext ("\ | ||||
|  \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "\n", | ||||
| @@ -1879,7 +1879,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
 | ||||
|    /* if --use-dynamic option is enabled, | ||||
|       use the string table to get the related library info.  */ | ||||
|    Elf_Data *strtab_data = NULL; | ||||
| -  if (use_dynamic_segment)
 | ||||
| +  if (use_dynamic_segment && phdr != NULL)
 | ||||
|      { | ||||
|        strtab_data = get_dynscn_strtab(ebl->elf, phdr); | ||||
|        if (strtab_data == NULL) | ||||
| @@ -1903,7 +1903,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
 | ||||
|  	  || dyn->d_tag == DT_RPATH | ||||
|  	  || dyn->d_tag == DT_RUNPATH) | ||||
|  	{ | ||||
| -	  if (! use_dynamic_segment)
 | ||||
| +	  if (! use_dynamic_segment && shdr != NULL)
 | ||||
|  	    name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val); | ||||
|  	  else if (dyn->d_un.d_val < strtab_data->d_size | ||||
|  		   && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0', | ||||
| 
 | ||||
| commit b0a0235771906e3bcd6174c4e3c020b5522b0be5 | ||||
| Author: Mark Wielaard <mark@klomp.org> | ||||
| Date:   Thu Nov 3 13:44:35 2022 +0100 | ||||
| 
 | ||||
|     libdw: Don't dereference and assign values we are skipping | ||||
|      | ||||
|     We don't use the FDE address encoding byte, so no reason | ||||
|     to read and store it. Just skip past it. | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| 
 | ||||
| diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c
 | ||||
| index 23b16885..be08984f 100644
 | ||||
| --- a/libdw/dwarf_next_cfi.c
 | ||||
| +++ b/libdw/dwarf_next_cfi.c
 | ||||
| @@ -226,7 +226,7 @@ dwarf_next_cfi (const unsigned char e_ident[],
 | ||||
|  	      if (sized_augmentation) | ||||
|  		{ | ||||
|  		  /* Skip FDE address encoding byte.  */ | ||||
| -		  encoding = *bytes++;
 | ||||
| +		  bytes++;
 | ||||
|  		  continue; | ||||
|  		} | ||||
|  	      break; | ||||
| 
 | ||||
| commit 52a6a3110e019d696284fdd822c2a2f0987dded2 | ||||
| Author: Mark Wielaard <mark@klomp.org> | ||||
| Date:   Thu Nov 3 13:52:32 2022 +0100 | ||||
| 
 | ||||
|     readelf: Check gelf_getdyn doesn't return NULL | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| 
 | ||||
| diff --git a/src/readelf.c b/src/readelf.c
 | ||||
| index e721a209..3dafb041 100644
 | ||||
| --- a/src/readelf.c
 | ||||
| +++ b/src/readelf.c
 | ||||
| @@ -4910,7 +4910,7 @@ get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max])
 | ||||
|      GElf_Dyn dyn_mem; | ||||
|      GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem); | ||||
|      /* DT_NULL Marks end of dynamic section.  */ | ||||
| -    if (dyn->d_tag == DT_NULL)
 | ||||
| +    if (dyn == NULL || dyn->d_tag == DT_NULL)
 | ||||
|        break; | ||||
|   | ||||
|      switch (dyn->d_tag) { | ||||
| @ -1,171 +0,0 @@ | ||||
| commit c424e5f3d24f76e01242d15ba361dc6234706fed | ||||
| Author: Frank Ch. Eigler <fche@redhat.com> | ||||
| Date:   Thu Nov 3 10:07:31 2022 -0400 | ||||
| 
 | ||||
|     debuginfod.cxx: fix coverity-found use-after-release error | ||||
|      | ||||
|     The debuginfod_client object lifetime needs more careful handling, | ||||
|     made easier with the defer_dtor<> gadget. | ||||
|      | ||||
|     Signed-off-by: Frank Ch. Eigler <fche@redhat.com> | ||||
| 
 | ||||
| diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
 | ||||
| index f46da6ef..02a11477 100644
 | ||||
| --- a/debuginfod/debuginfod.cxx
 | ||||
| +++ b/debuginfod/debuginfod.cxx
 | ||||
| @@ -2249,85 +2249,82 @@ handle_buildid (MHD_Connection* conn,
 | ||||
|   | ||||
|    int fd = -1; | ||||
|    debuginfod_client *client = debuginfod_pool_begin (); | ||||
| -  if (client != NULL)
 | ||||
| -    {
 | ||||
| -      debuginfod_set_progressfn (client, & debuginfod_find_progress);
 | ||||
| +  if (client == NULL)
 | ||||
| +    throw libc_exception(errno, "debuginfod client pool alloc");
 | ||||
| +  defer_dtor<debuginfod_client*,void> client_closer (client, debuginfod_pool_end);
 | ||||
| +  
 | ||||
| +  debuginfod_set_progressfn (client, & debuginfod_find_progress);
 | ||||
|   | ||||
| -      if (conn)
 | ||||
| -        {
 | ||||
| -          // Transcribe incoming User-Agent:
 | ||||
| -          string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: "";
 | ||||
| -          string ua_complete = string("User-Agent: ") + ua;
 | ||||
| -          debuginfod_add_http_header (client, ua_complete.c_str());
 | ||||
| -
 | ||||
| -          // Compute larger XFF:, for avoiding info loss during
 | ||||
| -          // federation, and for future cyclicity detection.
 | ||||
| -          string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: "";
 | ||||
| -          if (xff != "")
 | ||||
| -            xff += string(", "); // comma separated list
 | ||||
| -
 | ||||
| -          unsigned int xff_count = 0;
 | ||||
| -          for (auto&& i : xff){
 | ||||
| -            if (i == ',') xff_count++;
 | ||||
| -          }
 | ||||
| +  if (conn)
 | ||||
| +    {
 | ||||
| +      // Transcribe incoming User-Agent:
 | ||||
| +      string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: "";
 | ||||
| +      string ua_complete = string("User-Agent: ") + ua;
 | ||||
| +      debuginfod_add_http_header (client, ua_complete.c_str());
 | ||||
| +      
 | ||||
| +      // Compute larger XFF:, for avoiding info loss during
 | ||||
| +      // federation, and for future cyclicity detection.
 | ||||
| +      string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: "";
 | ||||
| +      if (xff != "")
 | ||||
| +        xff += string(", "); // comma separated list
 | ||||
| +      
 | ||||
| +      unsigned int xff_count = 0;
 | ||||
| +      for (auto&& i : xff){
 | ||||
| +        if (i == ',') xff_count++;
 | ||||
| +      }
 | ||||
|   | ||||
| -          // if X-Forwarded-For: exceeds N hops,
 | ||||
| -          // do not delegate a local lookup miss to upstream debuginfods.
 | ||||
| -          if (xff_count >= forwarded_ttl_limit)
 | ||||
| -            throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \
 | ||||
| +      // if X-Forwarded-For: exceeds N hops,
 | ||||
| +      // do not delegate a local lookup miss to upstream debuginfods.
 | ||||
| +      if (xff_count >= forwarded_ttl_limit)
 | ||||
| +        throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \
 | ||||
|  and will not query the upstream servers"); | ||||
|   | ||||
| -          // Compute the client's numeric IP address only - so can't merge with conninfo()
 | ||||
| -          const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn,
 | ||||
| -                                                                       MHD_CONNECTION_INFO_CLIENT_ADDRESS);
 | ||||
| -          struct sockaddr *so = u ? u->client_addr : 0;
 | ||||
| -          char hostname[256] = ""; // RFC1035
 | ||||
| -          if (so && so->sa_family == AF_INET) {
 | ||||
| -            (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0,
 | ||||
| -                                NI_NUMERICHOST);
 | ||||
| -          } else if (so && so->sa_family == AF_INET6) {
 | ||||
| -            struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so;
 | ||||
| -            if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | ||||
| -              struct sockaddr_in addr4;
 | ||||
| -              memset (&addr4, 0, sizeof(addr4));
 | ||||
| -              addr4.sin_family = AF_INET;
 | ||||
| -              addr4.sin_port = addr6->sin6_port;
 | ||||
| -              memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
 | ||||
| -              (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4),
 | ||||
| -                                  hostname, sizeof (hostname), NULL, 0,
 | ||||
| -                                  NI_NUMERICHOST);
 | ||||
| -            } else {
 | ||||
| -              (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0,
 | ||||
| -                                  NI_NUMERICHOST);
 | ||||
| -            }
 | ||||
| -          }
 | ||||
| -          
 | ||||
| -          string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname);
 | ||||
| -          debuginfod_add_http_header (client, xff_complete.c_str());
 | ||||
| +      // Compute the client's numeric IP address only - so can't merge with conninfo()
 | ||||
| +      const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn,
 | ||||
| +                                                                   MHD_CONNECTION_INFO_CLIENT_ADDRESS);
 | ||||
| +      struct sockaddr *so = u ? u->client_addr : 0;
 | ||||
| +      char hostname[256] = ""; // RFC1035
 | ||||
| +      if (so && so->sa_family == AF_INET) {
 | ||||
| +        (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0,
 | ||||
| +                            NI_NUMERICHOST);
 | ||||
| +      } else if (so && so->sa_family == AF_INET6) {
 | ||||
| +        struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so;
 | ||||
| +        if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | ||||
| +          struct sockaddr_in addr4;
 | ||||
| +          memset (&addr4, 0, sizeof(addr4));
 | ||||
| +          addr4.sin_family = AF_INET;
 | ||||
| +          addr4.sin_port = addr6->sin6_port;
 | ||||
| +          memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
 | ||||
| +          (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4),
 | ||||
| +                              hostname, sizeof (hostname), NULL, 0,
 | ||||
| +                              NI_NUMERICHOST);
 | ||||
| +        } else {
 | ||||
| +          (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0,
 | ||||
| +                              NI_NUMERICHOST);
 | ||||
|          } | ||||
| -
 | ||||
| -      if (artifacttype == "debuginfo")
 | ||||
| -	fd = debuginfod_find_debuginfo (client,
 | ||||
| -					(const unsigned char*) buildid.c_str(),
 | ||||
| -					0, NULL);
 | ||||
| -      else if (artifacttype == "executable")
 | ||||
| -	fd = debuginfod_find_executable (client,
 | ||||
| -					 (const unsigned char*) buildid.c_str(),
 | ||||
| -					 0, NULL);
 | ||||
| -      else if (artifacttype == "source")
 | ||||
| -	fd = debuginfod_find_source (client,
 | ||||
| -				     (const unsigned char*) buildid.c_str(),
 | ||||
| -				     0, suffix.c_str(), NULL);
 | ||||
| -      else if (artifacttype == "section")
 | ||||
| -	fd = debuginfod_find_section (client,
 | ||||
| -				      (const unsigned char*) buildid.c_str(),
 | ||||
| -				      0, section.c_str(), NULL);
 | ||||
| -
 | ||||
| +      }
 | ||||
| +          
 | ||||
| +      string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname);
 | ||||
| +      debuginfod_add_http_header (client, xff_complete.c_str());
 | ||||
|      } | ||||
| -  else
 | ||||
| -    fd = -errno; /* Set by debuginfod_begin.  */
 | ||||
| -  debuginfod_pool_end (client);
 | ||||
| -
 | ||||
| +  
 | ||||
| +  if (artifacttype == "debuginfo")
 | ||||
| +    fd = debuginfod_find_debuginfo (client,
 | ||||
| +                                    (const unsigned char*) buildid.c_str(),
 | ||||
| +                                    0, NULL);
 | ||||
| +  else if (artifacttype == "executable")
 | ||||
| +    fd = debuginfod_find_executable (client,
 | ||||
| +                                     (const unsigned char*) buildid.c_str(),
 | ||||
| +                                     0, NULL);
 | ||||
| +  else if (artifacttype == "source")
 | ||||
| +    fd = debuginfod_find_source (client,
 | ||||
| +                                 (const unsigned char*) buildid.c_str(),
 | ||||
| +                                 0, suffix.c_str(), NULL);
 | ||||
| +  else if (artifacttype == "section")
 | ||||
| +    fd = debuginfod_find_section (client,
 | ||||
| +                                  (const unsigned char*) buildid.c_str(),
 | ||||
| +                                  0, section.c_str(), NULL);
 | ||||
| +  
 | ||||
|    if (fd >= 0) | ||||
|      { | ||||
|        if (conn != 0) | ||||
| @ -1,24 +0,0 @@ | ||||
| commit 58a7aa900bc2d9822b0d0cb596ba95a21ff0fd2d | ||||
| Author: Mark Wielaard <mark@klomp.org> | ||||
| Date:   Wed Nov 2 17:54:11 2022 +0100 | ||||
| 
 | ||||
|     debuginfod: Mark extract_section function static | ||||
|      | ||||
|     The extract_section function in debuginfod-client.c is an internal | ||||
|     function and should not be exported. Mark it as static. | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| 
 | ||||
| diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
 | ||||
| index 0c4a00cf..f48e32cc 100644
 | ||||
| --- a/debuginfod/debuginfod-client.c
 | ||||
| +++ b/debuginfod/debuginfod-client.c
 | ||||
| @@ -621,7 +621,7 @@ path_escape (const char *src, char *dest)
 | ||||
|     section name was not found.  -EEXIST indicates that the section was | ||||
|     found but had type SHT_NOBITS.  */ | ||||
|   | ||||
| -int
 | ||||
| +static int
 | ||||
|  extract_section (int fd, const char *section, char *fd_path, char **usr_path) | ||||
|  { | ||||
|    elf_version (EV_CURRENT); | ||||
| @ -0,0 +1,73 @@ | ||||
| diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
 | ||||
| index ef4d47e3..d92d8d62 100644
 | ||||
| --- a/debuginfod/debuginfod-client.c
 | ||||
| +++ b/debuginfod/debuginfod-client.c
 | ||||
| @@ -248,7 +248,7 @@ debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data)
 | ||||
|   | ||||
|  /* handle config file read and write */ | ||||
|  static int | ||||
| -debuginfod_config_cache(char *config_path,
 | ||||
| +debuginfod_config_cache(debuginfod_client *c, char *config_path,
 | ||||
|  			long cache_config_default_s, | ||||
|  			struct stat *st) | ||||
|  { | ||||
| @@ -277,17 +277,27 @@ debuginfod_config_cache(char *config_path,
 | ||||
|      } | ||||
|   | ||||
|    long cache_config; | ||||
| +  /* PR29696 - NB: When using fdopen, the file descriptor is NOT
 | ||||
| +     dup'ed and will be closed when the stream is closed. Manually
 | ||||
| +     closing fd after fclose is called will lead to a race condition
 | ||||
| +     where, if reused, the file descriptor will compete for its
 | ||||
| +     regular use before being incorrectly closed here.  */
 | ||||
|    FILE *config_file = fdopen(fd, "r"); | ||||
|    if (config_file) | ||||
|      { | ||||
|        if (fscanf(config_file, "%ld", &cache_config) != 1) | ||||
| -        cache_config = cache_config_default_s;
 | ||||
| -      fclose(config_file);
 | ||||
| +	cache_config = cache_config_default_s;
 | ||||
| +      if (0 != fclose (config_file) && c->verbose_fd >= 0)
 | ||||
| +	dprintf (c->verbose_fd, "fclose failed with %s (err=%d)\n",
 | ||||
| +		 strerror (errno), errno);
 | ||||
|      } | ||||
|    else | ||||
| -    cache_config = cache_config_default_s;
 | ||||
| -
 | ||||
| -  close (fd);
 | ||||
| +    {
 | ||||
| +      cache_config = cache_config_default_s;
 | ||||
| +      if (0 != close (fd) && c->verbose_fd >= 0)
 | ||||
| +	dprintf (c->verbose_fd, "close failed with %s (err=%d)\n",
 | ||||
| +		 strerror (errno), errno);
 | ||||
| +    }
 | ||||
|    return cache_config; | ||||
|  } | ||||
|   | ||||
| @@ -303,7 +313,7 @@ debuginfod_clean_cache(debuginfod_client *c,
 | ||||
|    struct stat st; | ||||
|   | ||||
|    /* Create new interval file.  */ | ||||
| -  rc = debuginfod_config_cache(interval_path,
 | ||||
| +  rc = debuginfod_config_cache(c, interval_path,
 | ||||
|  			       cache_clean_default_interval_s, &st); | ||||
|    if (rc < 0) | ||||
|      return rc; | ||||
| @@ -320,7 +330,7 @@ debuginfod_clean_cache(debuginfod_client *c,
 | ||||
|    utime (interval_path, NULL); | ||||
|   | ||||
|    /* Read max unused age value from config file.  */ | ||||
| -  rc = debuginfod_config_cache(max_unused_path,
 | ||||
| +  rc = debuginfod_config_cache(c, max_unused_path,
 | ||||
|  			       cache_default_max_unused_age_s, &st); | ||||
|    if (rc < 0) | ||||
|      return rc; | ||||
| @@ -1110,7 +1135,7 @@ debuginfod_query_server (debuginfod_client *c,
 | ||||
|   | ||||
|            close(fd); /* no need to hold onto the negative-hit file descriptor */ | ||||
|             | ||||
| -          rc = debuginfod_config_cache(cache_miss_path,
 | ||||
| +          rc = debuginfod_config_cache(c, cache_miss_path,
 | ||||
|                                         cache_miss_default_s, &st); | ||||
|            if (rc < 0) | ||||
|              goto out; | ||||
							
								
								
									
										224
									
								
								SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,224 @@ | ||||
| From 3aca5b5f1f1617db2220022d9061dcaf129e54c4 Mon Sep 17 00:00:00 2001 | ||||
| From: Mark Wielaard <mark@klomp.org> | ||||
| Date: Wed, 21 Jun 2023 18:05:12 +0200 | ||||
| Subject: [PATCH] libelf: Replace list of elf_getdata_rawchunk results with a | ||||
|  tree | ||||
| 
 | ||||
| elf_getdata_rawchunks did a linear search to see if a chunk was | ||||
| already fetched. Replace this list with a binary search tree to make | ||||
| lookup faster when a lot of Elf_Data_Chunk were created. | ||||
| 
 | ||||
|        * libelf/libelfP.h (Elf_Data_Chunk): Remove next field. | ||||
|        (struct Elf): Change the rawchunks type from Elf_Data_Chunk * | ||||
|        to void *. | ||||
|        * elf_getdata_rawchunk.c (chunk_compare): New static function. | ||||
|        (elf_getdata_rawchunk): Use tsearch instead of a manual linked | ||||
|        list. | ||||
|        * elf_end.c (free_chunk): New static function. | ||||
|        (elf_end): Call tdestroy instead of walking linked list. | ||||
| 
 | ||||
| Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| ---
 | ||||
|  libelf/elf_end.c              | 22 +++++++++------- | ||||
|  libelf/elf_getdata_rawchunk.c | 47 +++++++++++++++++++++++++---------- | ||||
|  libelf/libelfP.h              | 13 ++++------ | ||||
|  3 files changed, 52 insertions(+), 30 deletions(-) | ||||
| 
 | ||||
| diff --git a/libelf/elf_end.c b/libelf/elf_end.c
 | ||||
| index 5c451f36..3e5d4c86 100644
 | ||||
| --- a/libelf/elf_end.c
 | ||||
| +++ b/libelf/elf_end.c
 | ||||
| @@ -1,5 +1,6 @@
 | ||||
|  /* Free resources associated with Elf descriptor. | ||||
|     Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc. | ||||
| +   Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org>
 | ||||
|     This file is part of elfutils. | ||||
|     Written by Ulrich Drepper <drepper@redhat.com>, 1998. | ||||
|   | ||||
| @@ -32,12 +33,22 @@
 | ||||
|  #endif | ||||
|   | ||||
|  #include <assert.h> | ||||
| +#include <search.h>
 | ||||
|  #include <stddef.h> | ||||
|  #include <stdlib.h> | ||||
|   | ||||
|  #include "libelfP.h" | ||||
|   | ||||
|   | ||||
| +static void
 | ||||
| +free_chunk (void *n)
 | ||||
| +{
 | ||||
| +  Elf_Data_Chunk *rawchunk = (Elf_Data_Chunk *)n;
 | ||||
| +  if (rawchunk->dummy_scn.flags & ELF_F_MALLOCED)
 | ||||
| +    free (rawchunk->data.d.d_buf);
 | ||||
| +  free (rawchunk);
 | ||||
| +}
 | ||||
| +
 | ||||
|  int | ||||
|  elf_end (Elf *elf) | ||||
|  { | ||||
| @@ -112,20 +123,13 @@ elf_end (Elf *elf)
 | ||||
|   | ||||
|      case ELF_K_ELF: | ||||
|        { | ||||
| -	Elf_Data_Chunk *rawchunks
 | ||||
| +	void *rawchunks
 | ||||
|  	  = (elf->class == ELFCLASS32 | ||||
|  	     || (offsetof (struct Elf, state.elf32.rawchunks) | ||||
|  		 == offsetof (struct Elf, state.elf64.rawchunks)) | ||||
|  	     ? elf->state.elf32.rawchunks | ||||
|  	     : elf->state.elf64.rawchunks); | ||||
| -	while (rawchunks != NULL)
 | ||||
| -	  {
 | ||||
| -	    Elf_Data_Chunk *next = rawchunks->next;
 | ||||
| -	    if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED)
 | ||||
| -	      free (rawchunks->data.d.d_buf);
 | ||||
| -	    free (rawchunks);
 | ||||
| -	    rawchunks = next;
 | ||||
| -	  }
 | ||||
| +	tdestroy (rawchunks, free_chunk);
 | ||||
|   | ||||
|  	Elf_ScnList *list = (elf->class == ELFCLASS32 | ||||
|  			     || (offsetof (struct Elf, state.elf32.scns) | ||||
| diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
 | ||||
| index 5a35ccdc..cfd40396 100644
 | ||||
| --- a/libelf/elf_getdata_rawchunk.c
 | ||||
| +++ b/libelf/elf_getdata_rawchunk.c
 | ||||
| @@ -1,6 +1,6 @@
 | ||||
|  /* Return converted data from raw chunk of ELF file. | ||||
|     Copyright (C) 2007, 2014, 2015 Red Hat, Inc. | ||||
| -   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
 | ||||
| +   Copyright (C) 2022, 2023 Mark J. Wielaard <mark@klomp.org>
 | ||||
|     This file is part of elfutils. | ||||
|   | ||||
|     This file is free software; you can redistribute it and/or modify | ||||
| @@ -33,12 +33,28 @@
 | ||||
|   | ||||
|  #include <assert.h> | ||||
|  #include <errno.h> | ||||
| +#include <search.h>
 | ||||
|  #include <stdlib.h> | ||||
|  #include <string.h> | ||||
|   | ||||
|  #include "libelfP.h" | ||||
|  #include "common.h" | ||||
|   | ||||
| +static int
 | ||||
| +chunk_compare (const void *a, const void *b)
 | ||||
| +{
 | ||||
| +  Elf_Data_Chunk *da = (Elf_Data_Chunk *)a;
 | ||||
| +  Elf_Data_Chunk *db = (Elf_Data_Chunk *)b;
 | ||||
| +
 | ||||
| +  if (da->offset != db->offset)
 | ||||
| +    return da->offset - db->offset;
 | ||||
| +
 | ||||
| +  if (da->data.d.d_size != db->data.d.d_size)
 | ||||
| +    return da->data.d.d_size - db->data.d.d_size;
 | ||||
| +
 | ||||
| +  return da->data.d.d_type - db->data.d.d_type;
 | ||||
| +}
 | ||||
| +
 | ||||
|  Elf_Data * | ||||
|  elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) | ||||
|  { | ||||
| @@ -75,19 +91,25 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
 | ||||
|    rwlock_rdlock (elf->lock); | ||||
|   | ||||
|    /* Maybe we already got this chunk?  */ | ||||
| -  Elf_Data_Chunk *rawchunks = elf->state.elf.rawchunks;
 | ||||
| -  while (rawchunks != NULL)
 | ||||
| +  Elf_Data_Chunk key;
 | ||||
| +  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);
 | ||||
| +  if (found == NULL)
 | ||||
| +    goto nomem;
 | ||||
| +
 | ||||
| +  /* Existing entry.  */
 | ||||
| +  if (*found != &key && *found != NULL)
 | ||||
|      { | ||||
| -      if ((rawchunks->offset == offset || size == 0)
 | ||||
| -	  && rawchunks->data.d.d_size == size
 | ||||
| -	  && rawchunks->data.d.d_type == type)
 | ||||
| -	{
 | ||||
| -	  result = &rawchunks->data.d;
 | ||||
| -	  goto out;
 | ||||
| -	}
 | ||||
| -      rawchunks = rawchunks->next;
 | ||||
| +      result = &(*found)->data.d;
 | ||||
| +      goto out;
 | ||||
|      } | ||||
|   | ||||
| +  /* New entry.  */
 | ||||
| +  *found = NULL;
 | ||||
| +
 | ||||
|    size_t align = __libelf_type_align (elf->class, type); | ||||
|    if (elf->map_address != NULL) | ||||
|      { | ||||
| @@ -189,8 +211,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type)
 | ||||
|    rwlock_unlock (elf->lock); | ||||
|    rwlock_wrlock (elf->lock); | ||||
|   | ||||
| -  chunk->next = elf->state.elf.rawchunks;
 | ||||
| -  elf->state.elf.rawchunks = chunk;
 | ||||
| +  *found = chunk;
 | ||||
|    result = &chunk->data.d; | ||||
|   | ||||
|   out: | ||||
| diff --git a/libelf/libelfP.h b/libelf/libelfP.h
 | ||||
| index 6624f38a..d3c241e5 100644
 | ||||
| --- a/libelf/libelfP.h
 | ||||
| +++ b/libelf/libelfP.h
 | ||||
| @@ -1,5 +1,6 @@
 | ||||
|  /* Internal interfaces for libelf. | ||||
|     Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc. | ||||
| +   Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org>
 | ||||
|     This file is part of elfutils. | ||||
|     Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. | ||||
|   | ||||
| @@ -262,11 +263,7 @@ typedef struct Elf_ScnList
 | ||||
|  typedef struct Elf_Data_Chunk | ||||
|  { | ||||
|    Elf_Data_Scn data; | ||||
| -  union
 | ||||
| -  {
 | ||||
| -    Elf_Scn dummy_scn;
 | ||||
| -    struct Elf_Data_Chunk *next;
 | ||||
| -  };
 | ||||
| +  Elf_Scn dummy_scn;
 | ||||
|    int64_t offset;		/* The original raw offset in the Elf image.  */ | ||||
|  } Elf_Data_Chunk; | ||||
|   | ||||
| @@ -324,7 +321,7 @@ struct Elf
 | ||||
|        Elf_ScnList *scns_last;	/* Last element in the section list. | ||||
|  				   If NULL the data has not yet been | ||||
|  				   read from the file.  */ | ||||
| -      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
 | ||||
| +      void *rawchunks;		/* Tree of elf_getdata_rawchunk results.  */
 | ||||
|        unsigned int scnincr;	/* Number of sections allocate the last | ||||
|  				   time.  */ | ||||
|        int ehdr_flags;		/* Flags (dirty) for ELF header.  */ | ||||
| @@ -343,7 +340,7 @@ struct Elf
 | ||||
|        Elf_ScnList *scns_last;	/* Last element in the section list. | ||||
|  				   If NULL the data has not yet been | ||||
|  				   read from the file.  */ | ||||
| -      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
 | ||||
| +      void *rawchunks;		/* Tree of elf_getdata_rawchunk results.  */
 | ||||
|        unsigned int scnincr;	/* Number of sections allocate the last | ||||
|  				   time.  */ | ||||
|        int ehdr_flags;		/* Flags (dirty) for ELF header.  */ | ||||
| @@ -368,7 +365,7 @@ struct Elf
 | ||||
|        Elf_ScnList *scns_last;	/* Last element in the section list. | ||||
|  				   If NULL the data has not yet been | ||||
|  				   read from the file.  */ | ||||
| -      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
 | ||||
| +      void *rawchunks;		/* Tree of elf_getdata_rawchunk results.  */
 | ||||
|        unsigned int scnincr;	/* Number of sections allocate the last | ||||
|  				   time.  */ | ||||
|        int ehdr_flags;		/* Flags (dirty) for ELF header.  */ | ||||
| -- 
 | ||||
| 2.40.1 | ||||
| 
 | ||||
							
								
								
									
										95
									
								
								SOURCES/elfutils-0.189-elfcompress.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								SOURCES/elfutils-0.189-elfcompress.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | ||||
| From ef9164520c81ea61efe88777a8ad61bf17a54201 Mon Sep 17 00:00:00 2001 | ||||
| From: Mark Wielaard <mark@klomp.org> | ||||
| Date: Sat, 22 Apr 2023 01:26:17 +0200 | ||||
| Subject: [PATCH] elfcompress: Don't compress if section already compressed | ||||
|  unless forced | ||||
| 
 | ||||
| Before commit a5b07cdf9 "support ZSTD compression algorithm" | ||||
| elfcompress would not try to compress a section if it already | ||||
| had the requested compression type (or was already uncompressed) | ||||
| unless the --force flag was given. An else if construct was changed | ||||
| to an if in the commit causing elfcompress to warn (in verbose mode) | ||||
| but then still try to (re)compress the section. | ||||
| 
 | ||||
| Add an explicit check so if nothing needs (un)compressing, the file | ||||
| isn't changed. | ||||
| 
 | ||||
| The diff looks large, but git diff -b -w is just: | ||||
| 
 | ||||
| +     if (force || type != schtype)
 | ||||
| +       {
 | ||||
|           if (shdr->sh_type != SHT_NOBITS | ||||
|               && (shdr->sh_flags & SHF_ALLOC) == 0) | ||||
|             { | ||||
| @@ -554,6 +556,7 @@ process_file (const char *fname)
 | ||||
|               printf ("[%zd] %s ignoring %s section\n", ndx, sname, | ||||
|                       (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); | ||||
|         } | ||||
| +   }
 | ||||
| 
 | ||||
| Signed-off-by: Mark Wielaard <mark@klomp.org> | ||||
| ---
 | ||||
|  src/elfcompress.c | 43 +++++++++++++++++++++++-------------------- | ||||
|  1 file changed, 23 insertions(+), 20 deletions(-) | ||||
| 
 | ||||
| diff --git a/src/elfcompress.c b/src/elfcompress.c
 | ||||
| index 18ade66f..f771b92a 100644
 | ||||
| --- a/src/elfcompress.c
 | ||||
| +++ b/src/elfcompress.c
 | ||||
| @@ -529,30 +529,33 @@ process_file (const char *fname)
 | ||||
|  		  } | ||||
|  	    } | ||||
|   | ||||
| -	  if (shdr->sh_type != SHT_NOBITS
 | ||||
| -	      && (shdr->sh_flags & SHF_ALLOC) == 0)
 | ||||
| +	  if (force || type != schtype)
 | ||||
|  	    { | ||||
| -	      set_section (sections, ndx);
 | ||||
| -	      /* Check if we might want to change this section name.  */
 | ||||
| -	      if (! adjust_names
 | ||||
| -		  && ((type != ZLIB_GNU
 | ||||
| -		       && startswith (sname, ".zdebug"))
 | ||||
| -		      || (type == ZLIB_GNU
 | ||||
| -			  && startswith (sname, ".debug"))))
 | ||||
| -		adjust_names = true;
 | ||||
| -
 | ||||
| -	      /* We need a buffer this large if we change the names.  */
 | ||||
| -	      if (adjust_names)
 | ||||
| +	      if (shdr->sh_type != SHT_NOBITS
 | ||||
| +		  && (shdr->sh_flags & SHF_ALLOC) == 0)
 | ||||
|  		{ | ||||
| -		  size_t slen = strlen (sname);
 | ||||
| -		  if (slen > maxnamelen)
 | ||||
| -		    maxnamelen = slen;
 | ||||
| +		  set_section (sections, ndx);
 | ||||
| +		  /* Check if we might want to change this section name.  */
 | ||||
| +		  if (! adjust_names
 | ||||
| +		      && ((type != ZLIB_GNU
 | ||||
| +			   && startswith (sname, ".zdebug"))
 | ||||
| +			  || (type == ZLIB_GNU
 | ||||
| +			      && startswith (sname, ".debug"))))
 | ||||
| +		    adjust_names = true;
 | ||||
| +
 | ||||
| +		  /* We need a buffer this large if we change the names.  */
 | ||||
| +		  if (adjust_names)
 | ||||
| +		    {
 | ||||
| +		      size_t slen = strlen (sname);
 | ||||
| +		      if (slen > maxnamelen)
 | ||||
| +			maxnamelen = slen;
 | ||||
| +		    }
 | ||||
|  		} | ||||
| +	      else
 | ||||
| +		if (verbose >= 0)
 | ||||
| +		  printf ("[%zd] %s ignoring %s section\n", ndx, sname,
 | ||||
| +			  (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated"));
 | ||||
|  	    } | ||||
| -	  else
 | ||||
| -	    if (verbose >= 0)
 | ||||
| -	      printf ("[%zd] %s ignoring %s section\n", ndx, sname,
 | ||||
| -		      (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated"));
 | ||||
|  	} | ||||
|   | ||||
|        if (shdr->sh_type == SHT_SYMTAB) | ||||
| -- 
 | ||||
| 2.31.1 | ||||
| 
 | ||||
| @ -1,5 +1,5 @@ | ||||
| Name: elfutils | ||||
| Version: 0.188 | ||||
| Version: 0.189 | ||||
| %global baserelease 3 | ||||
| Release: %{baserelease}%{?dist} | ||||
| URL: http://elfutils.org/ | ||||
| @ -65,12 +65,12 @@ BuildRequires: gettext-devel | ||||
| 
 | ||||
| # Patches | ||||
| 
 | ||||
| # Don't export internal function. | ||||
| Patch1: elfutils-0.188-static-extract_section.patch | ||||
| # Silence some compiler warnings | ||||
| Patch2: elfutils-0.188-compile-warnings.patch | ||||
| # The debuginfod_client object lifetime needs more careful handling | ||||
| Patch3: elfutils-0.188-debuginfod-client-lifetime.patch | ||||
| # elfcompress: Don't compress if section already compressed unless forced | ||||
| Patch1: elfutils-0.189-elfcompress.patch | ||||
| # libelf: Replace list of elf_getdata_rawchunk results with a tree | ||||
| Patch2: elfutils-0.189-elf_getdata_rawchunk.patch | ||||
| # PR29696: Removed secondary fd close in cache config causing race condition | ||||
| Patch3: elfutils-0.189-debuginfod_config_cache-double-close.patch | ||||
| 
 | ||||
| %description | ||||
| Elfutils is a collection of utilities, including stack (to show | ||||
| @ -284,9 +284,9 @@ RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -Wformat" | ||||
| trap 'cat config.log' EXIT | ||||
| 
 | ||||
| %if 0%{?centos} >= 8 | ||||
| %configure CFLAGS="$RPM_OPT_FLAGS -fexceptions" --enable-debuginfod-urls=https://debuginfod.centos.org/ | ||||
| %configure CFLAGS="$RPM_OPT_FLAGS" --enable-debuginfod-urls=https://debuginfod.centos.org/ | ||||
| %else | ||||
| %configure CFLAGS="$RPM_OPT_FLAGS -fexceptions" | ||||
| %configure CFLAGS="$RPM_OPT_FLAGS" | ||||
| %endif | ||||
| trap '' EXIT | ||||
| %make_build | ||||
| @ -461,6 +461,16 @@ exit 0 | ||||
| %systemd_postun_with_restart debuginfod.service | ||||
| 
 | ||||
| %changelog | ||||
| * Wed Jun 28 2023 Mark Wielaard <mjw@redhat.com> - 0.189-3 | ||||
| - Add elfutils-0.189-elf_getdata_rawchunk.patch | ||||
| - Add elfutils-0.189-debuginfod_config_cache-double-close.patch | ||||
| 
 | ||||
| * Mon Apr 24 2023 Mark Wielaard <mjw@redhat.com> - 0.189-2 | ||||
| - Add elfutils-0.189-elfcompress.patch | ||||
| 
 | ||||
| * Tue Apr 4 2023 Mark Wielaard <mjw@redhat.com> - 0.189-1 | ||||
| - Upgrade to upsteam elfutils 0.189. | ||||
| 
 | ||||
| * Mon Nov 7 2022 Mark Wielaard <mjw@redhat.com> - 0.188-3 | ||||
| - Add elfutils-0.188-compile-warnings.patch | ||||
| - Add elfutils-0.188-debuginfod-client-lifetime.patch | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user