Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Jun 2019 18:34:05 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348657 - head/contrib/elftoolchain/elfcopy
Message-ID:  <201906041834.x54IY5Qs035508@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Jun  4 18:34:05 2019
New Revision: 348657
URL: https://svnweb.freebsd.org/changeset/base/348657

Log:
  elfcopy: Use libelftc's string table routines to build .shstrtab.
  
  This replaces some hand-rolled routines and is substantially faster
  since libelftc uses a hash table for lookups and insertions, whereas
  elfcopy would perform a linear scan of the table.
  
  PR:		234949
  Reviewed by:	emaste
  MFC after:	2 weeks
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D20473

Modified:
  head/contrib/elftoolchain/elfcopy/ascii.c
  head/contrib/elftoolchain/elfcopy/binary.c
  head/contrib/elftoolchain/elfcopy/elfcopy.h
  head/contrib/elftoolchain/elfcopy/main.c
  head/contrib/elftoolchain/elfcopy/sections.c

Modified: head/contrib/elftoolchain/elfcopy/ascii.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/ascii.c	Tue Jun  4 18:31:52 2019	(r348656)
+++ head/contrib/elftoolchain/elfcopy/ascii.c	Tue Jun  4 18:34:05 2019	(r348657)
@@ -378,9 +378,6 @@ done:
 		errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
 		    elf_errmsg(-1));
 
-	/* Generate section name string table (.shstrtab). */
-	set_shstrtab(ecp);
-
 	/* Update sh_name pointer for each section header entry. */
 	update_shdr(ecp, 0);
 
@@ -604,9 +601,6 @@ done:
 	if (gelf_update_ehdr(ecp->eout, &oeh) == 0)
 		errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
 		    elf_errmsg(-1));
-
-	/* Generate section name string table (.shstrtab). */
-	set_shstrtab(ecp);
 
 	/* Update sh_name pointer for each section header entry. */
 	update_shdr(ecp, 0);

Modified: head/contrib/elftoolchain/elfcopy/binary.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/binary.c	Tue Jun  4 18:31:52 2019	(r348656)
+++ head/contrib/elftoolchain/elfcopy/binary.c	Tue Jun  4 18:34:05 2019	(r348657)
@@ -250,11 +250,8 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, c
 		errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s",
 		    elf_errmsg(-1));
 
-	/* Generate section name string table (.shstrtab). */
-	ecp->flags |= SYMTAB_EXIST;
-	set_shstrtab(ecp);
-
 	/* Update sh_name pointer for each section header entry. */
+	ecp->flags |= SYMTAB_EXIST;
 	update_shdr(ecp, 0);
 
 	/* Properly set sh_link field of .symtab section. */

Modified: head/contrib/elftoolchain/elfcopy/elfcopy.h
==============================================================================
--- head/contrib/elftoolchain/elfcopy/elfcopy.h	Tue Jun  4 18:31:52 2019	(r348656)
+++ head/contrib/elftoolchain/elfcopy/elfcopy.h	Tue Jun  4 18:34:05 2019	(r348657)
@@ -135,6 +135,8 @@ struct section {
 	int		 pseudo;
 	int		 nocopy;
 
+	Elftc_String_Table *strtab;
+
 	TAILQ_ENTRY(section) sec_list;	/* next section */
 };
 
@@ -313,7 +315,6 @@ struct sec_action *lookup_sec_act(struct elfcopy *_ecp
 struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
     unsigned int _op);
 void	resync_sections(struct elfcopy *_ecp);
-void	set_shstrtab(struct elfcopy *_ecp);
 void	setup_phdr(struct elfcopy *_ecp);
 void	update_shdr(struct elfcopy *_ecp, int _update_link);
 

Modified: head/contrib/elftoolchain/elfcopy/main.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/main.c	Tue Jun  4 18:31:52 2019	(r348656)
+++ head/contrib/elftoolchain/elfcopy/main.c	Tue Jun  4 18:34:05 2019	(r348657)
@@ -388,9 +388,6 @@ create_elf(struct elfcopy *ecp)
 	 */
 	copy_content(ecp);
 
-	/* Generate section name string table (.shstrtab). */
-	set_shstrtab(ecp);
-
 	/*
 	 * Second processing of output sections: Update section headers.
 	 * At this stage we set name string index, update st_link and st_info
@@ -485,6 +482,9 @@ free_elf(struct elfcopy *ecp)
 
 	/* Free symbol table buffers. */
 	free_symtab(ecp);
+
+	/* Free section name string table. */
+	elftc_string_table_destroy(ecp->shstrtab->strtab);
 
 	/* Free internal section list. */
 	if (!TAILQ_EMPTY(&ecp->v_sec)) {

Modified: head/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/sections.c	Tue Jun  4 18:31:52 2019	(r348656)
+++ head/contrib/elftoolchain/elfcopy/sections.c	Tue Jun  4 18:34:05 2019	(r348657)
@@ -42,19 +42,18 @@ static void	check_section_rename(struct elfcopy *ecp, 
 static void	filter_reloc(struct elfcopy *ecp, struct section *s);
 static int	get_section_flags(struct elfcopy *ecp, const char *name);
 static void	insert_sections(struct elfcopy *ecp);
-static void	insert_to_strtab(struct section *t, const char *s);
 static int	is_append_section(struct elfcopy *ecp, const char *name);
 static int	is_compress_section(struct elfcopy *ecp, const char *name);
 static int	is_debug_section(const char *name);
 static int	is_dwo_section(const char *name);
 static int	is_modify_section(struct elfcopy *ecp, const char *name);
 static int	is_print_section(struct elfcopy *ecp, const char *name);
-static int	lookup_string(struct section *t, const char *s);
 static void	modify_section(struct elfcopy *ecp, struct section *s);
 static void	pad_section(struct elfcopy *ecp, struct section *s);
 static void	print_data(const char *d, size_t sz);
 static void	print_section(struct section *s);
 static void	*read_section(struct section *s, size_t *size);
+static void	set_shstrtab(struct elfcopy *ecp);
 static void	update_reloc(struct elfcopy *ecp, struct section *s);
 static void	update_section_group(struct elfcopy *ecp, struct section *s);
 
@@ -1336,10 +1335,9 @@ insert_sections(struct elfcopy *ecp)
 void
 add_to_shstrtab(struct elfcopy *ecp, const char *name)
 {
-	struct section *s;
 
-	s = ecp->shstrtab;
-	insert_to_strtab(s, name);
+	if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
+		errx(EXIT_FAILURE, "elftc_string_table_insert failed");
 }
 
 void
@@ -1349,6 +1347,9 @@ update_shdr(struct elfcopy *ecp, int update_link)
 	GElf_Shdr	 osh;
 	int		 elferr;
 
+	/* Finalize the section name string table (.shstrtab). */
+	set_shstrtab(ecp);
+
 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
 		if (s->pseudo)
 			continue;
@@ -1358,7 +1359,8 @@ update_shdr(struct elfcopy *ecp, int update_link)
 			    elf_errmsg(-1));
 
 		/* Find section name in string table and set sh_name. */
-		osh.sh_name = lookup_string(ecp->shstrtab, s->name);
+		osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
+		    s->name);
 
 		/*
 		 * sh_link needs to be updated, since the index of the
@@ -1408,19 +1410,22 @@ init_shstrtab(struct elfcopy *ecp)
 	s->loadable = 0;
 	s->type = SHT_STRTAB;
 	s->vma = 0;
+	s->strtab = elftc_string_table_create(0);
 
-	insert_to_strtab(s, "");
-	insert_to_strtab(s, ".symtab");
-	insert_to_strtab(s, ".strtab");
-	insert_to_strtab(s, ".shstrtab");
+	add_to_shstrtab(ecp, "");
+	add_to_shstrtab(ecp, ".symtab");
+	add_to_shstrtab(ecp, ".strtab");
+	add_to_shstrtab(ecp, ".shstrtab");
 }
 
-void
+static void
 set_shstrtab(struct elfcopy *ecp)
 {
 	struct section	*s;
 	Elf_Data	*data;
 	GElf_Shdr	 sh;
+	const char	*image;
+	size_t		 sz;
 
 	s = ecp->shstrtab;
 
@@ -1453,19 +1458,21 @@ set_shstrtab(struct elfcopy *ecp)
 	 * which are reserved for this in the beginning of shstrtab.
 	 */
 	if (!(ecp->flags & SYMTAB_EXIST)) {
-		s->sz -= sizeof(".symtab\0.strtab");
-		memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
-		    s->sz);
+		elftc_string_table_remove(s->strtab, ".symtab");
+		elftc_string_table_remove(s->strtab, ".strtab");
 	}
 
-	sh.sh_size	= s->sz;
+	image = elftc_string_table_image(s->strtab, &sz);
+	s->sz = sz;
+
+	sh.sh_size	= sz;
 	if (!gelf_update_shdr(s->os, &sh))
 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
 		    elf_errmsg(-1));
 
 	data->d_align	= 1;
-	data->d_buf	= s->buf;
-	data->d_size	= s->sz;
+	data->d_buf	= (void *)(uintptr_t)image;
+	data->d_size	= sz;
 	data->d_off	= 0;
 	data->d_type	= ELF_T_BYTE;
 	data->d_version	= EV_CURRENT;
@@ -1589,73 +1596,6 @@ add_gnu_debuglink(struct elfcopy *ecp)
 
 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
 	ecp->flags |= SEC_ADD;
-}
-
-static void
-insert_to_strtab(struct section *t, const char *s)
-{
-	const char	*r;
-	char		*b, *c;
-	size_t		 len, slen;
-	int		 append;
-
-	if (t->sz == 0) {
-		t->cap = 512;
-		if ((t->buf = malloc(t->cap)) == NULL)
-			err(EXIT_FAILURE, "malloc failed");
-	}
-
-	slen = strlen(s);
-	append = 0;
-	b = t->buf;
-	for (c = b; c < b + t->sz;) {
-		len = strlen(c);
-		if (!append && len >= slen) {
-			r = c + (len - slen);
-			if (strcmp(r, s) == 0)
-				return;
-		} else if (len < slen && len != 0) {
-			r = s + (slen - len);
-			if (strcmp(c, r) == 0) {
-				t->sz -= len + 1;
-				memmove(c, c + len + 1, t->sz - (c - b));
-				append = 1;
-				continue;
-			}
-		}
-		c += len + 1;
-	}
-
-	while (t->sz + slen + 1 >= t->cap) {
-		t->cap *= 2;
-		if ((t->buf = realloc(t->buf, t->cap)) == NULL)
-			err(EXIT_FAILURE, "realloc failed");
-	}
-	b = t->buf;
-	strncpy(&b[t->sz], s, slen);
-	b[t->sz + slen] = '\0';
-	t->sz += slen + 1;
-}
-
-static int
-lookup_string(struct section *t, const char *s)
-{
-	const char	*b, *c, *r;
-	size_t		 len, slen;
-
-	slen = strlen(s);
-	b = t->buf;
-	for (c = b; c < b + t->sz;) {
-		len = strlen(c);
-		if (len >= slen) {
-			r = c + (len - slen);
-			if (strcmp(r, s) == 0)
-				return (r - b);
-		}
-		c += len + 1;
-	}
-
-	return (-1);
 }
 
 static uint32_t crctable[256] =



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906041834.x54IY5Qs035508>