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