xref: /freebsd/contrib/elftoolchain/elfcopy/sections.c (revision 406a584d7e80c2617dc035ede0d922215a12141c)
1 /*-
2  * Copyright (c) 2007-2011,2014 Kai Wang
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/param.h>
28 #include <sys/stat.h>
29 #include <err.h>
30 #include <libgen.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "elfcopy.h"
36 
37 ELFTC_VCSID("$Id: sections.c 3646 2018-10-27 02:25:39Z emaste $");
38 
39 static void	add_gnu_debuglink(struct elfcopy *ecp);
40 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
41 static void	check_section_rename(struct elfcopy *ecp, struct section *s);
42 static void	filter_reloc(struct elfcopy *ecp, struct section *s);
43 static int	get_section_flags(struct elfcopy *ecp, const char *name);
44 static void	insert_sections(struct elfcopy *ecp);
45 static void	insert_to_strtab(struct section *t, const char *s);
46 static int	is_append_section(struct elfcopy *ecp, const char *name);
47 static int	is_compress_section(struct elfcopy *ecp, const char *name);
48 static int	is_debug_section(const char *name);
49 static int	is_dwo_section(const char *name);
50 static int	is_modify_section(struct elfcopy *ecp, const char *name);
51 static int	is_print_section(struct elfcopy *ecp, const char *name);
52 static int	lookup_string(struct section *t, const char *s);
53 static void	modify_section(struct elfcopy *ecp, struct section *s);
54 static void	pad_section(struct elfcopy *ecp, struct section *s);
55 static void	print_data(const char *d, size_t sz);
56 static void	print_section(struct section *s);
57 static void	*read_section(struct section *s, size_t *size);
58 static void	update_reloc(struct elfcopy *ecp, struct section *s);
59 static void	update_section_group(struct elfcopy *ecp, struct section *s);
60 
61 int
62 is_remove_section(struct elfcopy *ecp, const char *name)
63 {
64 
65 	/* Always keep section name table */
66 	if (strcmp(name, ".shstrtab") == 0)
67 		return 0;
68 	if (strcmp(name, ".symtab") == 0 ||
69 	    strcmp(name, ".strtab") == 0) {
70 		if (ecp->strip == STRIP_ALL && lookup_symop_list(
71 		    ecp, NULL, SYMOP_KEEP) == NULL)
72 			return (1);
73 		else
74 			return (0);
75 	}
76 
77 	if (ecp->strip == STRIP_DWO && is_dwo_section(name))
78 		return (1);
79 	if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name))
80 		return (1);
81 
82 	if (is_debug_section(name)) {
83 		if (ecp->strip == STRIP_ALL ||
84 		    ecp->strip == STRIP_DEBUG ||
85 		    ecp->strip == STRIP_UNNEEDED ||
86 		    (ecp->flags & DISCARD_LOCAL))
87 			return (1);
88 		if (ecp->strip == STRIP_NONDEBUG)
89 			return (0);
90 	}
91 
92 	if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) {
93 		struct sec_action *sac;
94 
95 		sac = lookup_sec_act(ecp, name, 0);
96 		if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove)
97 			return (1);
98 		if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy))
99 			return (1);
100 	}
101 
102 	return (0);
103 }
104 
105 /*
106  * Relocation section needs to be removed if the section it applies to
107  * will be removed.
108  */
109 int
110 is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info)
111 {
112 	const char	*name;
113 	GElf_Shdr	 ish;
114 	Elf_Scn		*is;
115 	size_t		 indx;
116 	int		 elferr;
117 
118 	if (elf_getshstrndx(ecp->ein, &indx) == 0)
119 		errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
120 		    elf_errmsg(-1));
121 
122 	is = NULL;
123 	while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
124 		if (sh_info == elf_ndxscn(is)) {
125 			if (gelf_getshdr(is, &ish) == NULL)
126 				errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
127 				    elf_errmsg(-1));
128 			if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
129 			    NULL)
130 				errx(EXIT_FAILURE, "elf_strptr failed: %s",
131 				    elf_errmsg(-1));
132 			if (is_remove_section(ecp, name))
133 				return (1);
134 			else
135 				return (0);
136 		}
137 	}
138 	elferr = elf_errno();
139 	if (elferr != 0)
140 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
141 		    elf_errmsg(elferr));
142 
143 	/* Remove reloc section if we can't find the target section. */
144 	return (1);
145 }
146 
147 static int
148 is_append_section(struct elfcopy *ecp, const char *name)
149 {
150 	struct sec_action *sac;
151 
152 	sac = lookup_sec_act(ecp, name, 0);
153 	if (sac != NULL && sac->append != 0 && sac->string != NULL)
154 		return (1);
155 
156 	return (0);
157 }
158 
159 static int
160 is_compress_section(struct elfcopy *ecp, const char *name)
161 {
162 	struct sec_action *sac;
163 
164 	sac = lookup_sec_act(ecp, name, 0);
165 	if (sac != NULL && sac->compress != 0)
166 		return (1);
167 
168 	return (0);
169 }
170 
171 static void
172 check_section_rename(struct elfcopy *ecp, struct section *s)
173 {
174 	struct sec_action *sac;
175 	char *prefix;
176 	size_t namelen;
177 
178 	if (s->pseudo)
179 		return;
180 
181 	sac = lookup_sec_act(ecp, s->name, 0);
182 	if (sac != NULL && sac->rename)
183 		s->name = sac->newname;
184 
185 	if (!strcmp(s->name, ".symtab") ||
186 	    !strcmp(s->name, ".strtab") ||
187 	    !strcmp(s->name, ".shstrtab"))
188 		return;
189 
190 	prefix = NULL;
191 	if (s->loadable && ecp->prefix_alloc != NULL)
192 		prefix = ecp->prefix_alloc;
193 	else if (ecp->prefix_sec != NULL)
194 		prefix = ecp->prefix_sec;
195 
196 	if (prefix != NULL) {
197 		namelen = strlen(s->name) + strlen(prefix) + 1;
198 		if ((s->newname = malloc(namelen)) == NULL)
199 			err(EXIT_FAILURE, "malloc failed");
200 		snprintf(s->newname, namelen, "%s%s", prefix, s->name);
201 		s->name = s->newname;
202 	}
203 }
204 
205 static int
206 get_section_flags(struct elfcopy *ecp, const char *name)
207 {
208 	struct sec_action *sac;
209 
210 	sac = lookup_sec_act(ecp, name, 0);
211 	if (sac != NULL && sac->flags)
212 		return sac->flags;
213 
214 	return (0);
215 }
216 
217 /*
218  * Determine whether the section are debugging section.
219  * According to libbfd, debugging sections are recognized
220  * only by name.
221  */
222 static int
223 is_debug_section(const char *name)
224 {
225 	const char *dbg_sec[] = {
226 		".apple_",
227 		".debug",
228 		".gnu.linkonce.wi.",
229 		".line",
230 		".stab",
231 		NULL
232 	};
233 	const char **p;
234 
235 	for(p = dbg_sec; *p; p++) {
236 		if (strncmp(name, *p, strlen(*p)) == 0)
237 			return (1);
238 	}
239 
240 	return (0);
241 }
242 
243 static int
244 is_dwo_section(const char *name)
245 {
246 	size_t len;
247 
248 	if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0)
249 		return (1);
250 	return (0);
251 }
252 
253 static int
254 is_print_section(struct elfcopy *ecp, const char *name)
255 {
256 	struct sec_action *sac;
257 
258 	sac = lookup_sec_act(ecp, name, 0);
259 	if (sac != NULL && sac->print != 0)
260 		return (1);
261 
262 	return (0);
263 }
264 
265 static int
266 is_modify_section(struct elfcopy *ecp, const char *name)
267 {
268 
269 	if (is_append_section(ecp, name) ||
270 	    is_compress_section(ecp, name))
271 		return (1);
272 
273 	return (0);
274 }
275 
276 struct sec_action*
277 lookup_sec_act(struct elfcopy *ecp, const char *name, int add)
278 {
279 	struct sec_action *sac;
280 
281 	if (name == NULL)
282 		return NULL;
283 
284 	STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) {
285 		if (strcmp(name, sac->name) == 0)
286 			return sac;
287 	}
288 
289 	if (add == 0)
290 		return NULL;
291 
292 	if ((sac = malloc(sizeof(*sac))) == NULL)
293 		errx(EXIT_FAILURE, "not enough memory");
294 	memset(sac, 0, sizeof(*sac));
295 	sac->name = name;
296 	STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list);
297 
298 	return (sac);
299 }
300 
301 void
302 free_sec_act(struct elfcopy *ecp)
303 {
304 	struct sec_action *sac, *sac_temp;
305 
306 	STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) {
307 		STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list);
308 		free(sac);
309 	}
310 }
311 
312 void
313 insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail)
314 {
315 	struct section *s;
316 
317 	if (!tail) {
318 		TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
319 			if (sec->off < s->off) {
320 				TAILQ_INSERT_BEFORE(s, sec, sec_list);
321 				goto inc_nos;
322 			}
323 		}
324 	}
325 
326 	TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list);
327 
328 inc_nos:
329 	if (sec->pseudo == 0)
330 		ecp->nos++;
331 }
332 
333 /*
334  * First step of section creation: create scn and internal section
335  * structure, discard sections to be removed.
336  */
337 void
338 create_scn(struct elfcopy *ecp)
339 {
340 	struct section	*s;
341 	const char	*name;
342 	Elf_Scn		*is;
343 	GElf_Shdr	 ish;
344 	size_t		 indx;
345 	uint64_t	 oldndx, newndx;
346 	int		 elferr, sec_flags, reorder;
347 
348 	/*
349 	 * Insert a pseudo section that contains the ELF header
350 	 * and program header. Used as reference for section offset
351 	 * or load address adjustment.
352 	 */
353 	if ((s = calloc(1, sizeof(*s))) == NULL)
354 		err(EXIT_FAILURE, "calloc failed");
355 	s->off = 0;
356 	s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) +
357 	    gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT);
358 	s->align = 1;
359 	s->pseudo = 1;
360 	s->loadable = add_to_inseg_list(ecp, s);
361 	insert_to_sec_list(ecp, s, 0);
362 
363 	/* Create internal .shstrtab section. */
364 	init_shstrtab(ecp);
365 
366 	if (elf_getshstrndx(ecp->ein, &indx) == 0)
367 		errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
368 		    elf_errmsg(-1));
369 
370 	reorder = 0;
371 	is = NULL;
372 	while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
373 		if (gelf_getshdr(is, &ish) == NULL)
374 			errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
375 			    elf_errmsg(-1));
376 		if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL)
377 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
378 			    elf_errmsg(-1));
379 
380 		/* Skip sections to be removed. */
381 		if (is_remove_section(ecp, name))
382 			continue;
383 
384 		/*
385 		 * Relocation section need to be remove if the section
386 		 * it applies will be removed.
387 		 */
388 		if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
389 			if (ish.sh_info != 0 &&
390 			    is_remove_reloc_sec(ecp, ish.sh_info))
391 				continue;
392 
393 		/*
394 		 * Section groups should be removed if symbol table will
395 		 * be removed. (section group's signature stored in symbol
396 		 * table)
397 		 */
398 		if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL)
399 			continue;
400 
401 		/* Get section flags set by user. */
402 		sec_flags = get_section_flags(ecp, name);
403 
404 		/* Create internal section object. */
405 		if (strcmp(name, ".shstrtab") != 0) {
406 			if ((s = calloc(1, sizeof(*s))) == NULL)
407 				err(EXIT_FAILURE, "calloc failed");
408 			s->name		= name;
409 			s->is		= is;
410 			s->off		= ish.sh_offset;
411 			s->sz		= ish.sh_size;
412 			s->align	= ish.sh_addralign;
413 			s->type		= ish.sh_type;
414 			s->flags	= ish.sh_flags;
415 			s->vma		= ish.sh_addr;
416 
417 			/*
418 			 * Search program headers to determine whether section
419 			 * is loadable, but if user explicitly set section flags
420 			 * while neither "load" nor "alloc" is set, we make the
421 			 * section unloadable.
422 			 *
423 			 * Sections in relocatable object is loadable if
424 			 * section flag SHF_ALLOC is set.
425 			 */
426 			if (sec_flags &&
427 			    (sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
428 				s->loadable = 0;
429 			else {
430 				s->loadable = add_to_inseg_list(ecp, s);
431 				if ((ecp->flags & RELOCATABLE) &&
432 				    (ish.sh_flags & SHF_ALLOC))
433 					s->loadable = 1;
434 			}
435 		} else {
436 			/* Assuming .shstrtab is "unloadable". */
437 			s		= ecp->shstrtab;
438 			s->off		= ish.sh_offset;
439 		}
440 
441 		oldndx = newndx = SHN_UNDEF;
442 		if (strcmp(name, ".symtab") != 0 &&
443 		    strcmp(name, ".strtab") != 0) {
444 			if (!strcmp(name, ".shstrtab")) {
445 				/*
446 				 * Add sections specified by --add-section and
447 				 * gnu debuglink. we want these sections have
448 				 * smaller index than .shstrtab section.
449 				 */
450 				if (ecp->debuglink != NULL)
451 					add_gnu_debuglink(ecp);
452 				if (ecp->flags & SEC_ADD)
453 					insert_sections(ecp);
454 			}
455  			if ((s->os = elf_newscn(ecp->eout)) == NULL)
456 				errx(EXIT_FAILURE, "elf_newscn failed: %s",
457 				    elf_errmsg(-1));
458 			if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF)
459 				errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
460 				    elf_errmsg(-1));
461 		}
462 		if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF)
463 			errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
464 			    elf_errmsg(-1));
465 		if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF)
466 			ecp->secndx[oldndx] = newndx;
467 
468 		/*
469 		 * If strip action is STRIP_NONDEBUG(only keep debug),
470 		 * change sections type of loadable sections and section
471 		 * groups to SHT_NOBITS, and the content of those sections
472 		 * will be discarded. However, SHT_NOTE sections should
473 		 * be kept.
474 		 */
475 		if (ecp->strip == STRIP_NONDEBUG) {
476 			if (((ish.sh_flags & SHF_ALLOC) ||
477 			    (ish.sh_flags & SHF_GROUP)) &&
478 			    ish.sh_type != SHT_NOTE)
479 				s->type = SHT_NOBITS;
480 		}
481 
482 		check_section_rename(ecp, s);
483 
484 		/* create section header based on input object. */
485 		if (strcmp(name, ".symtab") != 0 &&
486 		    strcmp(name, ".strtab") != 0 &&
487 		    strcmp(name, ".shstrtab") != 0) {
488 			copy_shdr(ecp, s, NULL, 0, sec_flags);
489 			/*
490 			 * elfcopy puts .symtab, .strtab and .shstrtab
491 			 * sections in the end of the output object.
492 			 * If the input objects have more sections
493 			 * after any of these 3 sections, the section
494 			 * table will be reordered. section symbols
495 			 * should be regenerated for relocations.
496 			 */
497 			if (reorder)
498 				ecp->flags &= ~SYMTAB_INTACT;
499 		} else
500 			reorder = 1;
501 
502 		if (strcmp(name, ".symtab") == 0) {
503 			ecp->flags |= SYMTAB_EXIST;
504 			ecp->symtab = s;
505 		}
506 		if (strcmp(name, ".strtab") == 0)
507 			ecp->strtab = s;
508 
509 		insert_to_sec_list(ecp, s, 0);
510 	}
511 	elferr = elf_errno();
512 	if (elferr != 0)
513 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
514 		    elf_errmsg(elferr));
515 }
516 
517 struct section *
518 insert_shtab(struct elfcopy *ecp, int tail)
519 {
520 	struct section	*s, *shtab;
521 	GElf_Ehdr	 ieh;
522 	int		 nsecs;
523 
524 	/*
525 	 * Treat section header table as a "pseudo" section, insert it
526 	 * into section list, so later it will get sorted and resynced
527 	 * just as normal sections.
528 	 */
529 	if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
530 		errx(EXIT_FAILURE, "calloc failed");
531 	if (!tail) {
532 		/*
533 		 * "shoff" of input object is used as a hint for section
534 		 * resync later.
535 		 */
536 		if (gelf_getehdr(ecp->ein, &ieh) == NULL)
537 			errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
538 			    elf_errmsg(-1));
539 		shtab->off = ieh.e_shoff;
540 	} else
541 		shtab->off = 0;
542 	/* Calculate number of sections in the output object. */
543 	nsecs = 0;
544 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
545 		if (!s->pseudo)
546 			nsecs++;
547 	}
548 	/* Remember there is always a null section, so we +1 here. */
549 	shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT);
550 	if (shtab->sz == 0)
551 		errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1));
552 	shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8);
553 	shtab->loadable = 0;
554 	shtab->pseudo = 1;
555 	insert_to_sec_list(ecp, shtab, tail);
556 
557 	return (shtab);
558 }
559 
560 void
561 copy_content(struct elfcopy *ecp)
562 {
563 	struct section *s;
564 
565 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
566 		/* Skip pseudo section. */
567 		if (s->pseudo)
568 			continue;
569 
570 		/* Skip special sections. */
571 		if (strcmp(s->name, ".symtab") == 0 ||
572 		    strcmp(s->name, ".strtab") == 0 ||
573 		    strcmp(s->name, ".shstrtab") == 0)
574 			continue;
575 
576 		/*
577 		 * If strip action is STRIP_ALL, relocation info need
578 		 * to be stripped. Skip filtering otherwisw.
579 		 */
580 		if (ecp->strip == STRIP_ALL &&
581 		    (s->type == SHT_REL || s->type == SHT_RELA))
582 			filter_reloc(ecp, s);
583 
584 		/*
585 		 * The section indices in the SHT_GROUP section needs
586 		 * to be updated since we might have stripped some
587 		 * sections and changed section numbering.
588 		 */
589 		if (s->type == SHT_GROUP)
590 			update_section_group(ecp, s);
591 
592 		if (is_modify_section(ecp, s->name))
593 			modify_section(ecp, s);
594 
595 		copy_data(s);
596 
597 		/*
598 		 * If symbol table is modified, relocation info might
599 		 * need update, as symbol index may have changed.
600 		 */
601 		if ((ecp->flags & SYMTAB_INTACT) == 0 &&
602 		    (ecp->flags & SYMTAB_EXIST) &&
603 		    (s->type == SHT_REL || s->type == SHT_RELA))
604 			update_reloc(ecp, s);
605 
606 		if (is_print_section(ecp, s->name))
607 			print_section(s);
608 	}
609 }
610 
611 
612 /*
613  * Update section group section. The section indices in the SHT_GROUP
614  * section need update after section numbering changed.
615  */
616 static void
617 update_section_group(struct elfcopy *ecp, struct section *s)
618 {
619 	GElf_Shdr	 ish;
620 	Elf_Data	*id;
621 	uint32_t	*ws, *wd;
622 	uint64_t	 n;
623 	size_t		 ishnum;
624 	int		 i, j;
625 
626 	if (!elf_getshnum(ecp->ein, &ishnum))
627 		errx(EXIT_FAILURE, "elf_getshnum failed: %s",
628 		    elf_errmsg(-1));
629 
630 	if (gelf_getshdr(s->is, &ish) == NULL)
631 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
632 		    elf_errmsg(-1));
633 
634 	if ((id = elf_getdata(s->is, NULL)) == NULL)
635 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
636 		    elf_errmsg(-1));
637 
638 	if (ish.sh_size == 0)
639 		return;
640 
641 	if (ish.sh_entsize == 0)
642 		ish.sh_entsize = 4;
643 
644 	ws = id->d_buf;
645 
646 	/* We only support COMDAT section. */
647 #ifndef GRP_COMDAT
648 #define	GRP_COMDAT 0x1
649 #endif
650 	if ((*ws & GRP_COMDAT) == 0)
651 		return;
652 
653 	if ((s->buf = malloc(ish.sh_size)) == NULL)
654 		err(EXIT_FAILURE, "malloc failed");
655 
656 	s->sz = ish.sh_size;
657 
658 	wd = s->buf;
659 
660 	/* Copy the flag word as-is. */
661 	*wd = *ws;
662 
663 	/* Update the section indices. */
664 	n = ish.sh_size / ish.sh_entsize;
665 	for(i = 1, j = 1; (uint64_t)i < n; i++) {
666 		if (ws[i] != SHN_UNDEF && ws[i] < ishnum &&
667 		    ecp->secndx[ws[i]] != 0)
668 			wd[j++] = ecp->secndx[ws[i]];
669 		else
670 			s->sz -= 4;
671 	}
672 
673 	s->nocopy = 1;
674 }
675 
676 /*
677  * Filter relocation entries, only keep those entries whose
678  * symbol is in the keep list.
679  */
680 static void
681 filter_reloc(struct elfcopy *ecp, struct section *s)
682 {
683 	const char	*name;
684 	GElf_Shdr	 ish;
685 	GElf_Rel	 rel;
686 	GElf_Rela	 rela;
687 	Elf32_Rel	*rel32;
688 	Elf64_Rel	*rel64;
689 	Elf32_Rela	*rela32;
690 	Elf64_Rela	*rela64;
691 	Elf_Data	*id;
692 	uint64_t	 cap, n, nrels, sym;
693 	int		 elferr, i;
694 
695 	if (gelf_getshdr(s->is, &ish) == NULL)
696 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
697 		    elf_errmsg(-1));
698 
699 	/* We don't want to touch relocation info for dynamic symbols. */
700 	if ((ecp->flags & SYMTAB_EXIST) == 0) {
701 		/*
702 		 * No symbol table in output.  If sh_link points to a section
703 		 * that exists in the output object, this relocation section
704 		 * is for dynamic symbols.  Don't touch it.
705 		 */
706 		if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0)
707 			return;
708 	} else {
709 		/* Symbol table exist, check if index equals. */
710 		if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
711 			return;
712 	}
713 
714 #define	COPYREL(REL, SZ) do {					\
715 	if (nrels == 0) {					\
716 		if ((REL##SZ = malloc(cap *			\
717 		    sizeof(*REL##SZ))) == NULL)			\
718 			err(EXIT_FAILURE, "malloc failed");	\
719 	}							\
720 	if (nrels >= cap) {					\
721 		cap *= 2;					\
722 		if ((REL##SZ = realloc(REL##SZ, cap *		\
723 		    sizeof(*REL##SZ))) == NULL)			\
724 			err(EXIT_FAILURE, "realloc failed");	\
725 	}							\
726 	REL##SZ[nrels].r_offset = REL.r_offset;			\
727 	REL##SZ[nrels].r_info	= REL.r_info;			\
728 	if (s->type == SHT_RELA)				\
729 		rela##SZ[nrels].r_addend = rela.r_addend;	\
730 	nrels++;						\
731 } while (0)
732 
733 	nrels = 0;
734 	cap = 4;		/* keep list is usually small. */
735 	rel32 = NULL;
736 	rel64 = NULL;
737 	rela32 = NULL;
738 	rela64 = NULL;
739 	if ((id = elf_getdata(s->is, NULL)) == NULL)
740 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
741 		    elf_errmsg(-1));
742 	n = ish.sh_size / ish.sh_entsize;
743 	for(i = 0; (uint64_t)i < n; i++) {
744 		if (s->type == SHT_REL) {
745 			if (gelf_getrel(id, i, &rel) != &rel)
746 				errx(EXIT_FAILURE, "gelf_getrel failed: %s",
747 				    elf_errmsg(-1));
748 			sym = GELF_R_SYM(rel.r_info);
749 		} else {
750 			if (gelf_getrela(id, i, &rela) != &rela)
751 				errx(EXIT_FAILURE, "gelf_getrel failed: %s",
752 				    elf_errmsg(-1));
753 			sym = GELF_R_SYM(rela.r_info);
754 		}
755 		/*
756 		 * If a relocation references a symbol and we are omitting
757 		 * either that symbol or the entire symbol table we cannot
758 		 * produce valid output, and so just omit the relocation.
759 		 * Broken output like this is generally not useful, but some
760 		 * uses of elfcopy/strip rely on it - for example, GCC's build
761 		 * process uses it to check for build reproducibility by
762 		 * stripping objects and comparing them.
763 		 *
764 		 * Relocations that do not reference a symbol are retained.
765 		 */
766 		if (sym != 0) {
767 			if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0)
768 				continue;
769 			name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
770 			    sym);
771 			if (name == NULL)
772 				errx(EXIT_FAILURE, "elf_strptr failed: %s",
773 				    elf_errmsg(-1));
774 			if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL)
775 				continue;
776 		}
777 		if (ecp->oec == ELFCLASS32) {
778 			if (s->type == SHT_REL)
779 				COPYREL(rel, 32);
780 			else
781 				COPYREL(rela, 32);
782 		} else {
783 			if (s->type == SHT_REL)
784 				COPYREL(rel, 64);
785 			else
786 				COPYREL(rela, 64);
787 		}
788 	}
789 	elferr = elf_errno();
790 	if (elferr != 0)
791 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
792 		    elf_errmsg(elferr));
793 
794 	if (ecp->oec == ELFCLASS32) {
795 		if (s->type == SHT_REL)
796 			s->buf = rel32;
797 		else
798 			s->buf = rela32;
799 	} else {
800 		if (s->type == SHT_REL)
801 			s->buf = rel64;
802 		else
803 			s->buf = rela64;
804 	}
805 	s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
806 	    ELF_T_RELA), nrels, EV_CURRENT);
807 	s->nocopy = 1;
808 }
809 
810 static void
811 update_reloc(struct elfcopy *ecp, struct section *s)
812 {
813 	GElf_Shdr	 osh;
814 	GElf_Rel	 rel;
815 	GElf_Rela	 rela;
816 	Elf_Data	*od;
817 	uint64_t	 n;
818 	int		 i;
819 
820 #define UPDATEREL(REL) do {						\
821 	if (gelf_get##REL(od, i, &REL) != &REL)				\
822 		errx(EXIT_FAILURE, "gelf_get##REL failed: %s",		\
823 		    elf_errmsg(-1));					\
824 	REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)],	\
825 	    GELF_R_TYPE(REL.r_info));					\
826 	if (!gelf_update_##REL(od, i, &REL))				\
827 		errx(EXIT_FAILURE, "gelf_update_##REL failed: %s",	\
828 		    elf_errmsg(-1));					\
829 } while(0)
830 
831 	if (s->sz == 0)
832 		return;
833 	if (gelf_getshdr(s->os, &osh) == NULL)
834 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
835 		    elf_errmsg(-1));
836 	/* Only process .symtab reloc info. */
837 	if (osh.sh_link != elf_ndxscn(ecp->symtab->is))
838 		return;
839 	if ((od = elf_getdata(s->os, NULL)) == NULL)
840 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
841 		    elf_errmsg(-1));
842 	n = osh.sh_size / osh.sh_entsize;
843 	for(i = 0; (uint64_t)i < n; i++) {
844 		if (s->type == SHT_REL)
845 			UPDATEREL(rel);
846 		else
847 			UPDATEREL(rela);
848 	}
849 }
850 
851 static void
852 pad_section(struct elfcopy *ecp, struct section *s)
853 {
854 	GElf_Shdr	 osh;
855 	Elf_Data	*od;
856 
857 	if (s == NULL || s->pad_sz == 0)
858 		return;
859 
860 	if ((s->pad = malloc(s->pad_sz)) == NULL)
861 		err(EXIT_FAILURE, "malloc failed");
862 	memset(s->pad, ecp->fill, s->pad_sz);
863 
864 	/* Create a new Elf_Data to contain the padding bytes. */
865 	if ((od = elf_newdata(s->os)) == NULL)
866 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
867 		    elf_errmsg(-1));
868 	od->d_align = 1;
869 	od->d_off = s->sz;
870 	od->d_buf = s->pad;
871 	od->d_type = ELF_T_BYTE;
872 	od->d_size = s->pad_sz;
873 	od->d_version = EV_CURRENT;
874 
875 	/* Update section header. */
876 	if (gelf_getshdr(s->os, &osh) == NULL)
877 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
878 		    elf_errmsg(-1));
879 	osh.sh_size = s->sz + s->pad_sz;
880 	if (!gelf_update_shdr(s->os, &osh))
881 		errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
882 		    elf_errmsg(-1));
883 }
884 
885 void
886 resync_sections(struct elfcopy *ecp)
887 {
888 	struct section	*s, *ps;
889 	GElf_Shdr	 osh;
890 	uint64_t	 off;
891 	int		 first;
892 
893 	ps = NULL;
894 	first = 1;
895 	off = 0;
896 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
897 		if (first) {
898 			off = s->off;
899 			first = 0;
900 		}
901 
902 		/*
903 		 * Ignore TLS sections with load address 0 and without
904 		 * content. We don't need to adjust their file offset or
905 		 * VMA, only the size matters.
906 		 */
907 		if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
908 		    s->off == 0)
909 			continue;
910 
911 		/* Align section offset. */
912 		if (s->align == 0)
913 			s->align = 1;
914 		if (off <= s->off) {
915 			if (!s->loadable || (ecp->flags & RELOCATABLE))
916 				s->off = roundup(off, s->align);
917 		} else {
918 			if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
919 				warnx("moving loadable section %s, "
920 				    "is this intentional?", s->name);
921 			s->off = roundup(off, s->align);
922 		}
923 
924 		/* Calculate next section offset. */
925 		off = s->off;
926 		if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
927 			off += s->sz;
928 
929 		if (s->pseudo) {
930 			ps = NULL;
931 			continue;
932 		}
933 
934 		/* Count padding bytes added through --pad-to. */
935 		if (s->pad_sz > 0)
936 			off += s->pad_sz;
937 
938 		/* Update section header accordingly. */
939 		if (gelf_getshdr(s->os, &osh) == NULL)
940 			errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
941 			    elf_errmsg(-1));
942 		osh.sh_addr = s->vma;
943 		osh.sh_offset = s->off;
944 		osh.sh_size = s->sz;
945 		if (!gelf_update_shdr(s->os, &osh))
946 			errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
947 			    elf_errmsg(-1));
948 
949 		/* Add padding for previous section, if need. */
950 		if (ps != NULL) {
951 			if (ps->pad_sz > 0) {
952 				/* Apply padding added by --pad-to. */
953 				pad_section(ecp, ps);
954 			} else if ((ecp->flags & GAP_FILL) &&
955 			    (ps->off + ps->sz < s->off)) {
956 				/*
957 				 * Fill the gap between sections by padding
958 				 * the section with lower address.
959 				 */
960 				ps->pad_sz = s->off - (ps->off + ps->sz);
961 				pad_section(ecp, ps);
962 			}
963 		}
964 
965 		ps = s;
966 	}
967 
968 	/* Pad the last section, if need. */
969 	if (ps != NULL && ps->pad_sz > 0)
970 		pad_section(ecp, ps);
971 }
972 
973 static void
974 modify_section(struct elfcopy *ecp, struct section *s)
975 {
976 	struct sec_action	*sac;
977 	size_t			 srcsz, dstsz, p, len;
978 	char			*b, *c, *d, *src, *end;
979 	int			 dupe;
980 
981 	src = read_section(s, &srcsz);
982 	if (src == NULL || srcsz == 0) {
983 		/* For empty section, we proceed if we need to append. */
984 		if (!is_append_section(ecp, s->name))
985 			return;
986 	}
987 
988 	/* Allocate buffer needed for new section data. */
989 	dstsz = srcsz;
990 	if (is_append_section(ecp, s->name)) {
991 		sac = lookup_sec_act(ecp, s->name, 0);
992 		dstsz += strlen(sac->string) + 1;
993 	}
994 	if ((b = malloc(dstsz)) == NULL)
995 		err(EXIT_FAILURE, "malloc failed");
996 	s->buf = b;
997 
998 	/* Compress section. */
999 	p = 0;
1000 	if (is_compress_section(ecp, s->name)) {
1001 		end = src + srcsz;
1002 		for(c = src; c < end;) {
1003 			len = 0;
1004 			while(c + len < end && c[len] != '\0')
1005 				len++;
1006 			if (c + len == end) {
1007 				/* XXX should we warn here? */
1008 				strncpy(&b[p], c, len);
1009 				p += len;
1010 				break;
1011 			}
1012 			dupe = 0;
1013 			for (d = b; d < b + p; ) {
1014 				if (strcmp(d, c) == 0) {
1015 					dupe = 1;
1016 					break;
1017 				}
1018 				d += strlen(d) + 1;
1019 			}
1020 			if (!dupe) {
1021 				strncpy(&b[p], c, len);
1022 				b[p + len] = '\0';
1023 				p += len + 1;
1024 			}
1025 			c += len + 1;
1026 		}
1027 	} else {
1028 		memcpy(b, src, srcsz);
1029 		p += srcsz;
1030 	}
1031 
1032 	/* Append section. */
1033 	if (is_append_section(ecp, s->name)) {
1034 		sac = lookup_sec_act(ecp, s->name, 0);
1035 		len = strlen(sac->string);
1036 		strncpy(&b[p], sac->string, len);
1037 		b[p + len] = '\0';
1038 		p += len + 1;
1039 	}
1040 
1041 	s->sz = p;
1042 	s->nocopy = 1;
1043 }
1044 
1045 static void
1046 print_data(const char *d, size_t sz)
1047 {
1048 	const char *c;
1049 
1050 	for (c = d; c < d + sz; c++) {
1051 		if (*c == '\0')
1052 			putchar('\n');
1053 		else
1054 			putchar(*c);
1055 	}
1056 }
1057 
1058 static void
1059 print_section(struct section *s)
1060 {
1061 	Elf_Data	*id;
1062 	int		 elferr;
1063 
1064 	if (s->buf != NULL && s->sz > 0) {
1065 		print_data(s->buf, s->sz);
1066 	} else {
1067 		id = NULL;
1068 		while ((id = elf_getdata(s->is, id)) != NULL ||
1069 		    (id = elf_rawdata(s->is, id)) != NULL) {
1070 			(void) elf_errno();
1071 			print_data(id->d_buf, id->d_size);
1072 		}
1073 		elferr = elf_errno();
1074 		if (elferr != 0)
1075 			errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1076 			    elf_errmsg(elferr));
1077 	}
1078 	putchar('\n');
1079 }
1080 
1081 static void *
1082 read_section(struct section *s, size_t *size)
1083 {
1084 	Elf_Data	*id;
1085 	char		*b;
1086 	size_t		 sz;
1087 	int		 elferr;
1088 
1089 	sz = 0;
1090 	b = NULL;
1091 	id = NULL;
1092 	while ((id = elf_getdata(s->is, id)) != NULL ||
1093 	    (id = elf_rawdata(s->is, id)) != NULL) {
1094 		(void) elf_errno();
1095 		if (b == NULL)
1096 			b = malloc(id->d_size);
1097 		else
1098 			b = malloc(sz + id->d_size);
1099 		if (b == NULL)
1100 			err(EXIT_FAILURE, "malloc or realloc failed");
1101 
1102 		memcpy(&b[sz], id->d_buf, id->d_size);
1103 		sz += id->d_size;
1104 	}
1105 	elferr = elf_errno();
1106 	if (elferr != 0)
1107 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1108 		    elf_errmsg(elferr));
1109 
1110 	*size = sz;
1111 
1112 	return (b);
1113 }
1114 
1115 void
1116 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1117     int sec_flags)
1118 {
1119 	GElf_Shdr ish, osh;
1120 
1121 	if (gelf_getshdr(s->is, &ish) == NULL)
1122 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1123 		    elf_errmsg(-1));
1124 	if (gelf_getshdr(s->os, &osh) == NULL)
1125 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1126 		    elf_errmsg(-1));
1127 
1128 	if (copy)
1129 		(void) memcpy(&osh, &ish, sizeof(ish));
1130 	else {
1131 		osh.sh_type		= s->type;
1132 		osh.sh_addr		= s->vma;
1133 		osh.sh_offset		= s->off;
1134 		osh.sh_size		= s->sz;
1135 		osh.sh_link		= ish.sh_link;
1136 		osh.sh_info		= ish.sh_info;
1137 		osh.sh_addralign	= s->align;
1138 		osh.sh_entsize		= ish.sh_entsize;
1139 
1140 		if (sec_flags) {
1141 			osh.sh_flags = 0;
1142 			if (sec_flags & SF_ALLOC)
1143 				osh.sh_flags |= SHF_ALLOC;
1144 			if ((sec_flags & SF_READONLY) == 0)
1145 				osh.sh_flags |= SHF_WRITE;
1146 			if (sec_flags & SF_CODE)
1147 				osh.sh_flags |= SHF_EXECINSTR;
1148 			if ((sec_flags & SF_CONTENTS) &&
1149 			    s->type == SHT_NOBITS && s->sz > 0) {
1150 				/*
1151 				 * Convert SHT_NOBITS section to section with
1152 				 * (zero'ed) content on file.
1153 				 */
1154 				osh.sh_type = s->type = SHT_PROGBITS;
1155 				if ((s->buf = calloc(1, s->sz)) == NULL)
1156 					err(EXIT_FAILURE, "malloc failed");
1157 				s->nocopy = 1;
1158 			}
1159 		} else {
1160 			osh.sh_flags = ish.sh_flags;
1161 			/*
1162 			 * Newer binutils as(1) emits the section flag
1163 			 * SHF_INFO_LINK for relocation sections. elfcopy
1164 			 * emits this flag in the output section if it's
1165 			 * missing in the input section, to remain compatible
1166 			 * with binutils.
1167 			 */
1168 			if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1169 				osh.sh_flags |= SHF_INFO_LINK;
1170 		}
1171 	}
1172 
1173 	if (name == NULL)
1174 		add_to_shstrtab(ecp, s->name);
1175 	else
1176 		add_to_shstrtab(ecp, name);
1177 
1178 	if (!gelf_update_shdr(s->os, &osh))
1179 		errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1180 		    elf_errmsg(-1));
1181 }
1182 
1183 void
1184 copy_data(struct section *s)
1185 {
1186 	Elf_Data	*id, *od;
1187 	int		 elferr;
1188 
1189 	if (s->nocopy && s->buf == NULL)
1190 		return;
1191 
1192 	if ((id = elf_getdata(s->is, NULL)) == NULL) {
1193 		(void) elf_errno();
1194 		if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1195 			elferr = elf_errno();
1196 			if (elferr != 0)
1197 				errx(EXIT_FAILURE, "failed to read section:"
1198 				    " %s", s->name);
1199 			return;
1200 		}
1201 	}
1202 
1203 	if ((od = elf_newdata(s->os)) == NULL)
1204 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1205 		    elf_errmsg(-1));
1206 
1207 	if (s->nocopy) {
1208 		/* Use s->buf as content if s->nocopy is set. */
1209 		od->d_align	= id->d_align;
1210 		od->d_off	= 0;
1211 		od->d_buf	= s->buf;
1212 		od->d_type	= id->d_type;
1213 		od->d_size	= s->sz;
1214 		od->d_version	= id->d_version;
1215 	} else {
1216 		od->d_align	= id->d_align;
1217 		od->d_off	= id->d_off;
1218 		od->d_buf	= id->d_buf;
1219 		od->d_type	= id->d_type;
1220 		od->d_size	= id->d_size;
1221 		od->d_version	= id->d_version;
1222 	}
1223 
1224 	/*
1225 	 * Alignment Fixup. libelf does not allow the alignment for
1226 	 * Elf_Data descriptor to be set to 0. In this case we workaround
1227 	 * it by setting the alignment to 1.
1228 	 *
1229 	 * According to the ELF ABI, alignment 0 and 1 has the same
1230 	 * meaning: the section has no alignment constraints.
1231 	 */
1232 	if (od->d_align == 0)
1233 		od->d_align = 1;
1234 }
1235 
1236 struct section *
1237 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1238     void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1239     uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1240 {
1241 	struct section	*s;
1242 	Elf_Scn		*os;
1243 	Elf_Data	*od;
1244 	GElf_Shdr	 osh;
1245 
1246 	if ((os = elf_newscn(ecp->eout)) == NULL)
1247 		errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1248 		    elf_errmsg(-1));
1249 	if ((s = calloc(1, sizeof(*s))) == NULL)
1250 		err(EXIT_FAILURE, "calloc failed");
1251 	s->name = name;
1252 	s->newname = newname;	/* needs to be free()'ed */
1253 	s->off = off;
1254 	s->sz = size;
1255 	s->vma = vma;
1256 	s->align = align;
1257 	s->loadable = loadable;
1258 	s->is = NULL;
1259 	s->os = os;
1260 	s->type = stype;
1261 	s->nocopy = 1;
1262 	insert_to_sec_list(ecp, s, 1);
1263 
1264 	if (gelf_getshdr(os, &osh) == NULL)
1265 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1266 		    elf_errmsg(-1));
1267 	osh.sh_flags = flags;
1268 	osh.sh_type = s->type;
1269 	osh.sh_addr = s->vma;
1270 	osh.sh_addralign = s->align;
1271 	if (!gelf_update_shdr(os, &osh))
1272 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1273 		    elf_errmsg(-1));
1274 	add_to_shstrtab(ecp, name);
1275 
1276 	if (buf != NULL && size != 0) {
1277 		if ((od = elf_newdata(os)) == NULL)
1278 			errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1279 			    elf_errmsg(-1));
1280 		od->d_align = align;
1281 		od->d_off = 0;
1282 		od->d_buf = buf;
1283 		od->d_size = size;
1284 		od->d_type = dtype;
1285 		od->d_version = EV_CURRENT;
1286 	}
1287 
1288 	/*
1289 	 * Clear SYMTAB_INTACT, as we probably need to update/add new
1290 	 * STT_SECTION symbols into the symbol table.
1291 	 */
1292 	ecp->flags &= ~SYMTAB_INTACT;
1293 
1294 	return (s);
1295 }
1296 
1297 /*
1298  * Insert sections specified by --add-section to the end of section list.
1299  */
1300 static void
1301 insert_sections(struct elfcopy *ecp)
1302 {
1303 	struct sec_add	*sa;
1304 	struct section	*s;
1305 	size_t		 off;
1306 	uint64_t	 stype;
1307 
1308 	/* Put these sections in the end of current list. */
1309 	off = 0;
1310 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1311 		if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1312 			off = s->off + s->sz;
1313 		else
1314 			off = s->off;
1315 	}
1316 
1317 	STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1318 
1319 		/* TODO: Add section header vma/lma, flag changes here */
1320 
1321 		/*
1322 		 * The default section type for user added section is
1323 		 * SHT_PROGBITS. If the section name match certain patterns,
1324 		 * elfcopy will try to set a more appropriate section type.
1325 		 * However, data type is always set to ELF_T_BYTE and no
1326 		 * translation is performed by libelf.
1327 		 */
1328 		stype = SHT_PROGBITS;
1329 		if (strcmp(sa->name, ".note") == 0 ||
1330 		    strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1331 			stype = SHT_NOTE;
1332 
1333 		(void) create_external_section(ecp, sa->name, NULL, sa->content,
1334 		    sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1335 	}
1336 }
1337 
1338 void
1339 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1340 {
1341 	struct section *s;
1342 
1343 	s = ecp->shstrtab;
1344 	insert_to_strtab(s, name);
1345 }
1346 
1347 void
1348 update_shdr(struct elfcopy *ecp, int update_link)
1349 {
1350 	struct section	*s;
1351 	GElf_Shdr	 osh;
1352 	int		 elferr;
1353 
1354 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1355 		if (s->pseudo)
1356 			continue;
1357 
1358 		if (gelf_getshdr(s->os, &osh) == NULL)
1359 			errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1360 			    elf_errmsg(-1));
1361 
1362 		/* Find section name in string table and set sh_name. */
1363 		osh.sh_name = lookup_string(ecp->shstrtab, s->name);
1364 
1365 		/*
1366 		 * sh_link needs to be updated, since the index of the
1367 		 * linked section might have changed.
1368 		 */
1369 		if (update_link && osh.sh_link != 0)
1370 			osh.sh_link = ecp->secndx[osh.sh_link];
1371 
1372 		/*
1373 		 * sh_info of relocation section links to the section to which
1374 		 * its relocation info applies. So it may need update as well.
1375 		 */
1376 		if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1377 		    osh.sh_info != 0)
1378 			osh.sh_info = ecp->secndx[osh.sh_info];
1379 
1380 		/*
1381 		 * sh_info of SHT_GROUP section needs to point to the correct
1382 		 * string in the symbol table.
1383 		 */
1384 		if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) &&
1385 		    (ecp->flags & SYMTAB_INTACT) == 0)
1386 			osh.sh_info = ecp->symndx[osh.sh_info];
1387 
1388 		if (!gelf_update_shdr(s->os, &osh))
1389 			errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1390 			    elf_errmsg(-1));
1391 	}
1392 	elferr = elf_errno();
1393 	if (elferr != 0)
1394 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1395 		    elf_errmsg(elferr));
1396 }
1397 
1398 void
1399 init_shstrtab(struct elfcopy *ecp)
1400 {
1401 	struct section *s;
1402 
1403 	if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1404 		err(EXIT_FAILURE, "calloc failed");
1405 	s = ecp->shstrtab;
1406 	s->name = ".shstrtab";
1407 	s->is = NULL;
1408 	s->sz = 0;
1409 	s->align = 1;
1410 	s->loadable = 0;
1411 	s->type = SHT_STRTAB;
1412 	s->vma = 0;
1413 
1414 	insert_to_strtab(s, "");
1415 	insert_to_strtab(s, ".symtab");
1416 	insert_to_strtab(s, ".strtab");
1417 	insert_to_strtab(s, ".shstrtab");
1418 }
1419 
1420 void
1421 set_shstrtab(struct elfcopy *ecp)
1422 {
1423 	struct section	*s;
1424 	Elf_Data	*data;
1425 	GElf_Shdr	 sh;
1426 
1427 	s = ecp->shstrtab;
1428 
1429 	if (s->os == NULL) {
1430 		/* Input object does not contain .shstrtab section */
1431 		if ((s->os = elf_newscn(ecp->eout)) == NULL)
1432 			errx(EXIT_FAILURE, "elf_newscn failed: %s",
1433 			    elf_errmsg(-1));
1434 		insert_to_sec_list(ecp, s, 1);
1435 	}
1436 
1437 	if (gelf_getshdr(s->os, &sh) == NULL)
1438 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1439 		    elf_errmsg(-1));
1440 	sh.sh_addr	= 0;
1441 	sh.sh_addralign	= 1;
1442 	sh.sh_offset	= s->off;
1443 	sh.sh_type	= SHT_STRTAB;
1444 	sh.sh_flags	= 0;
1445 	sh.sh_entsize	= 0;
1446 	sh.sh_info	= 0;
1447 	sh.sh_link	= 0;
1448 
1449 	if ((data = elf_newdata(s->os)) == NULL)
1450 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1451 		    elf_errmsg(-1));
1452 
1453 	/*
1454 	 * If we don't have a symbol table, skip those a few bytes
1455 	 * which are reserved for this in the beginning of shstrtab.
1456 	 */
1457 	if (!(ecp->flags & SYMTAB_EXIST)) {
1458 		s->sz -= sizeof(".symtab\0.strtab");
1459 		memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
1460 		    s->sz);
1461 	}
1462 
1463 	sh.sh_size	= s->sz;
1464 	if (!gelf_update_shdr(s->os, &sh))
1465 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1466 		    elf_errmsg(-1));
1467 
1468 	data->d_align	= 1;
1469 	data->d_buf	= s->buf;
1470 	data->d_size	= s->sz;
1471 	data->d_off	= 0;
1472 	data->d_type	= ELF_T_BYTE;
1473 	data->d_version	= EV_CURRENT;
1474 
1475 	if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1476 		errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1477 		     elf_errmsg(-1));
1478 }
1479 
1480 void
1481 add_section(struct elfcopy *ecp, const char *arg)
1482 {
1483 	struct sec_add	*sa;
1484 	struct stat	 sb;
1485 	const char	*s, *fn;
1486 	FILE		*fp;
1487 	int		 len;
1488 
1489 	if ((s = strchr(arg, '=')) == NULL)
1490 		errx(EXIT_FAILURE,
1491 		    "illegal format for --add-section option");
1492 	if ((sa = malloc(sizeof(*sa))) == NULL)
1493 		err(EXIT_FAILURE, "malloc failed");
1494 
1495 	len = s - arg;
1496 	if ((sa->name = malloc(len + 1)) == NULL)
1497 		err(EXIT_FAILURE, "malloc failed");
1498 	strncpy(sa->name, arg, len);
1499 	sa->name[len] = '\0';
1500 
1501 	fn = s + 1;
1502 	if (stat(fn, &sb) == -1)
1503 		err(EXIT_FAILURE, "stat failed");
1504 	sa->size = sb.st_size;
1505 	if (sa->size > 0) {
1506 		if ((sa->content = malloc(sa->size)) == NULL)
1507 			err(EXIT_FAILURE, "malloc failed");
1508 		if ((fp = fopen(fn, "r")) == NULL)
1509 			err(EXIT_FAILURE, "can not open %s", fn);
1510 		if (fread(sa->content, 1, sa->size, fp) == 0 ||
1511 		    ferror(fp))
1512 			err(EXIT_FAILURE, "fread failed");
1513 		fclose(fp);
1514 	} else
1515 		sa->content = NULL;
1516 
1517 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1518 	ecp->flags |= SEC_ADD;
1519 }
1520 
1521 void
1522 free_sec_add(struct elfcopy *ecp)
1523 {
1524 	struct sec_add *sa, *sa_temp;
1525 
1526 	STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1527 		STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1528 		free(sa->name);
1529 		free(sa->content);
1530 		free(sa);
1531 	}
1532 }
1533 
1534 static void
1535 add_gnu_debuglink(struct elfcopy *ecp)
1536 {
1537 	struct sec_add	*sa;
1538 	struct stat	 sb;
1539 	FILE		*fp;
1540 	char		*fnbase, *buf;
1541 	int		 crc_off;
1542 	int		 crc;
1543 
1544 	if (ecp->debuglink == NULL)
1545 		return;
1546 
1547 	/* Read debug file content. */
1548 	if ((sa = malloc(sizeof(*sa))) == NULL)
1549 		err(EXIT_FAILURE, "malloc failed");
1550 	if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1551 		err(EXIT_FAILURE, "strdup failed");
1552 	if (stat(ecp->debuglink, &sb) == -1)
1553 		err(EXIT_FAILURE, "stat failed");
1554 	if (sb.st_size == 0)
1555 		errx(EXIT_FAILURE, "empty debug link target %s",
1556 		    ecp->debuglink);
1557 	if ((buf = malloc(sb.st_size)) == NULL)
1558 		err(EXIT_FAILURE, "malloc failed");
1559 	if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1560 		err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1561 	if (fread(buf, 1, sb.st_size, fp) == 0 ||
1562 	    ferror(fp))
1563 		err(EXIT_FAILURE, "fread failed");
1564 	fclose(fp);
1565 
1566 	/* Calculate crc checksum.  */
1567 	crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1568 	free(buf);
1569 
1570 	/* Calculate section size and the offset to store crc checksum. */
1571 	if ((fnbase = basename(ecp->debuglink)) == NULL)
1572 		err(EXIT_FAILURE, "basename failed");
1573 	crc_off = roundup(strlen(fnbase) + 1, 4);
1574 	sa->size = crc_off + 4;
1575 
1576 	/* Section content. */
1577 	if ((sa->content = calloc(1, sa->size)) == NULL)
1578 		err(EXIT_FAILURE, "malloc failed");
1579 	strncpy(sa->content, fnbase, strlen(fnbase));
1580 	if (ecp->oed == ELFDATA2LSB) {
1581 		sa->content[crc_off] = crc & 0xFF;
1582 		sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1583 		sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1584 		sa->content[crc_off + 3] = crc >> 24;
1585 	} else {
1586 		sa->content[crc_off] = crc >> 24;
1587 		sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1588 		sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1589 		sa->content[crc_off + 3] = crc & 0xFF;
1590 	}
1591 
1592 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1593 	ecp->flags |= SEC_ADD;
1594 }
1595 
1596 static void
1597 insert_to_strtab(struct section *t, const char *s)
1598 {
1599 	const char	*r;
1600 	char		*b, *c;
1601 	size_t		 len, slen;
1602 	int		 append;
1603 
1604 	if (t->sz == 0) {
1605 		t->cap = 512;
1606 		if ((t->buf = malloc(t->cap)) == NULL)
1607 			err(EXIT_FAILURE, "malloc failed");
1608 	}
1609 
1610 	slen = strlen(s);
1611 	append = 0;
1612 	b = t->buf;
1613 	for (c = b; c < b + t->sz;) {
1614 		len = strlen(c);
1615 		if (!append && len >= slen) {
1616 			r = c + (len - slen);
1617 			if (strcmp(r, s) == 0)
1618 				return;
1619 		} else if (len < slen && len != 0) {
1620 			r = s + (slen - len);
1621 			if (strcmp(c, r) == 0) {
1622 				t->sz -= len + 1;
1623 				memmove(c, c + len + 1, t->sz - (c - b));
1624 				append = 1;
1625 				continue;
1626 			}
1627 		}
1628 		c += len + 1;
1629 	}
1630 
1631 	while (t->sz + slen + 1 >= t->cap) {
1632 		t->cap *= 2;
1633 		if ((t->buf = realloc(t->buf, t->cap)) == NULL)
1634 			err(EXIT_FAILURE, "realloc failed");
1635 	}
1636 	b = t->buf;
1637 	strncpy(&b[t->sz], s, slen);
1638 	b[t->sz + slen] = '\0';
1639 	t->sz += slen + 1;
1640 }
1641 
1642 static int
1643 lookup_string(struct section *t, const char *s)
1644 {
1645 	const char	*b, *c, *r;
1646 	size_t		 len, slen;
1647 
1648 	slen = strlen(s);
1649 	b = t->buf;
1650 	for (c = b; c < b + t->sz;) {
1651 		len = strlen(c);
1652 		if (len >= slen) {
1653 			r = c + (len - slen);
1654 			if (strcmp(r, s) == 0)
1655 				return (r - b);
1656 		}
1657 		c += len + 1;
1658 	}
1659 
1660 	return (-1);
1661 }
1662 
1663 static uint32_t crctable[256] =
1664 {
1665 	0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1666 	0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1667 	0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1668 	0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1669 	0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1670 	0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1671 	0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1672 	0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1673 	0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1674 	0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1675 	0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1676 	0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1677 	0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1678 	0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1679 	0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1680 	0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1681 	0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1682 	0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1683 	0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1684 	0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1685 	0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1686 	0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1687 	0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1688 	0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1689 	0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1690 	0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1691 	0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1692 	0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1693 	0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1694 	0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1695 	0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1696 	0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1697 	0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1698 	0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1699 	0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1700 	0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1701 	0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1702 	0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1703 	0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1704 	0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1705 	0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1706 	0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1707 	0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1708 	0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1709 	0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1710 	0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1711 	0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1712 	0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1713 	0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1714 	0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1715 	0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1716 	0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1717 	0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1718 	0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1719 	0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1720 	0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1721 	0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1722 	0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1723 	0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1724 	0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1725 	0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1726 	0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1727 	0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1728 	0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1729 };
1730 
1731 static uint32_t
1732 calc_crc32(const char *p, size_t len, uint32_t crc)
1733 {
1734 	uint32_t i;
1735 
1736 	for (i = 0; i < len; i++) {
1737 		crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1738 	}
1739 
1740 	return (crc ^ 0xFFFFFFFF);
1741 }
1742