xref: /freebsd/contrib/elftoolchain/elfcopy/sections.c (revision f0cfa1b168014f56c02b83e5f28412cc5f78d117)
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 3443 2016-04-15 18:57:54Z kaiwang27 $");
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->vma		= ish.sh_addr;
415 
416 			/*
417 			 * Search program headers to determine whether section
418 			 * is loadable, but if user explicitly set section flags
419 			 * while neither "load" nor "alloc" is set, we make the
420 			 * section unloadable.
421 			 *
422 			 * Sections in relocatable object is loadable if
423 			 * section flag SHF_ALLOC is set.
424 			 */
425 			if (sec_flags &&
426 			    (sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
427 				s->loadable = 0;
428 			else {
429 				s->loadable = add_to_inseg_list(ecp, s);
430 				if ((ecp->flags & RELOCATABLE) &&
431 				    (ish.sh_flags & SHF_ALLOC))
432 					s->loadable = 1;
433 			}
434 		} else {
435 			/* Assuming .shstrtab is "unloadable". */
436 			s		= ecp->shstrtab;
437 			s->off		= ish.sh_offset;
438 		}
439 
440 		oldndx = newndx = SHN_UNDEF;
441 		if (strcmp(name, ".symtab") != 0 &&
442 		    strcmp(name, ".strtab") != 0) {
443 			if (!strcmp(name, ".shstrtab")) {
444 				/*
445 				 * Add sections specified by --add-section and
446 				 * gnu debuglink. we want these sections have
447 				 * smaller index than .shstrtab section.
448 				 */
449 				if (ecp->debuglink != NULL)
450 					add_gnu_debuglink(ecp);
451 				if (ecp->flags & SEC_ADD)
452 					insert_sections(ecp);
453 			}
454  			if ((s->os = elf_newscn(ecp->eout)) == NULL)
455 				errx(EXIT_FAILURE, "elf_newscn failed: %s",
456 				    elf_errmsg(-1));
457 			if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF)
458 				errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
459 				    elf_errmsg(-1));
460 		}
461 		if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF)
462 			errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
463 			    elf_errmsg(-1));
464 		if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF)
465 			ecp->secndx[oldndx] = newndx;
466 
467 		/*
468 		 * If strip action is STRIP_NONDEBUG(only keep debug),
469 		 * change sections type of loadable sections and section
470 		 * groups to SHT_NOBITS, and the content of those sections
471 		 * will be discarded. However, SHT_NOTE sections should
472 		 * be kept.
473 		 */
474 		if (ecp->strip == STRIP_NONDEBUG) {
475 			if (((ish.sh_flags & SHF_ALLOC) ||
476 			    (ish.sh_flags & SHF_GROUP)) &&
477 			    ish.sh_type != SHT_NOTE)
478 				s->type = SHT_NOBITS;
479 		}
480 
481 		check_section_rename(ecp, s);
482 
483 		/* create section header based on input object. */
484 		if (strcmp(name, ".symtab") != 0 &&
485 		    strcmp(name, ".strtab") != 0 &&
486 		    strcmp(name, ".shstrtab") != 0) {
487 			copy_shdr(ecp, s, NULL, 0, sec_flags);
488 			/*
489 			 * elfcopy puts .symtab, .strtab and .shstrtab
490 			 * sections in the end of the output object.
491 			 * If the input objects have more sections
492 			 * after any of these 3 sections, the section
493 			 * table will be reordered. section symbols
494 			 * should be regenerated for relocations.
495 			 */
496 			if (reorder)
497 				ecp->flags &= ~SYMTAB_INTACT;
498 		} else
499 			reorder = 1;
500 
501 		if (strcmp(name, ".symtab") == 0) {
502 			ecp->flags |= SYMTAB_EXIST;
503 			ecp->symtab = s;
504 		}
505 		if (strcmp(name, ".strtab") == 0)
506 			ecp->strtab = s;
507 
508 		insert_to_sec_list(ecp, s, 0);
509 	}
510 	elferr = elf_errno();
511 	if (elferr != 0)
512 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
513 		    elf_errmsg(elferr));
514 }
515 
516 struct section *
517 insert_shtab(struct elfcopy *ecp, int tail)
518 {
519 	struct section	*s, *shtab;
520 	GElf_Ehdr	 ieh;
521 	int		 nsecs;
522 
523 	/*
524 	 * Treat section header table as a "pseudo" section, insert it
525 	 * into section list, so later it will get sorted and resynced
526 	 * just as normal sections.
527 	 */
528 	if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
529 		errx(EXIT_FAILURE, "calloc failed");
530 	if (!tail) {
531 		/*
532 		 * "shoff" of input object is used as a hint for section
533 		 * resync later.
534 		 */
535 		if (gelf_getehdr(ecp->ein, &ieh) == NULL)
536 			errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
537 			    elf_errmsg(-1));
538 		shtab->off = ieh.e_shoff;
539 	} else
540 		shtab->off = 0;
541 	/* Calculate number of sections in the output object. */
542 	nsecs = 0;
543 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
544 		if (!s->pseudo)
545 			nsecs++;
546 	}
547 	/* Remember there is always a null section, so we +1 here. */
548 	shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT);
549 	if (shtab->sz == 0)
550 		errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1));
551 	shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8);
552 	shtab->loadable = 0;
553 	shtab->pseudo = 1;
554 	insert_to_sec_list(ecp, shtab, tail);
555 
556 	return (shtab);
557 }
558 
559 void
560 copy_content(struct elfcopy *ecp)
561 {
562 	struct section *s;
563 
564 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
565 		/* Skip pseudo section. */
566 		if (s->pseudo)
567 			continue;
568 
569 		/* Skip special sections. */
570 		if (strcmp(s->name, ".symtab") == 0 ||
571 		    strcmp(s->name, ".strtab") == 0 ||
572 		    strcmp(s->name, ".shstrtab") == 0)
573 			continue;
574 
575 		/*
576 		 * If strip action is STRIP_ALL, relocation info need
577 		 * to be stripped. Skip filtering otherwisw.
578 		 */
579 		if (ecp->strip == STRIP_ALL &&
580 		    (s->type == SHT_REL || s->type == SHT_RELA))
581 			filter_reloc(ecp, s);
582 
583 		/*
584 		 * The section indices in the SHT_GROUP section needs
585 		 * to be updated since we might have stripped some
586 		 * sections and changed section numbering.
587 		 */
588 		if (s->type == SHT_GROUP)
589 			update_section_group(ecp, s);
590 
591 		if (is_modify_section(ecp, s->name))
592 			modify_section(ecp, s);
593 
594 		copy_data(s);
595 
596 		/*
597 		 * If symbol table is modified, relocation info might
598 		 * need update, as symbol index may have changed.
599 		 */
600 		if ((ecp->flags & SYMTAB_INTACT) == 0 &&
601 		    (ecp->flags & SYMTAB_EXIST) &&
602 		    (s->type == SHT_REL || s->type == SHT_RELA))
603 			update_reloc(ecp, s);
604 
605 		if (is_print_section(ecp, s->name))
606 			print_section(s);
607 	}
608 }
609 
610 
611 /*
612  * Update section group section. The section indices in the SHT_GROUP
613  * section need update after section numbering changed.
614  */
615 static void
616 update_section_group(struct elfcopy *ecp, struct section *s)
617 {
618 	GElf_Shdr	 ish;
619 	Elf_Data	*id;
620 	uint32_t	*ws, *wd;
621 	uint64_t	 n;
622 	size_t		 ishnum;
623 	int		 i, j;
624 
625 	if (!elf_getshnum(ecp->ein, &ishnum))
626 		errx(EXIT_FAILURE, "elf_getshnum failed: %s",
627 		    elf_errmsg(-1));
628 
629 	if (gelf_getshdr(s->is, &ish) == NULL)
630 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
631 		    elf_errmsg(-1));
632 
633 	if ((id = elf_getdata(s->is, NULL)) == NULL)
634 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
635 		    elf_errmsg(-1));
636 
637 	if (ish.sh_size == 0)
638 		return;
639 
640 	if (ish.sh_entsize == 0)
641 		ish.sh_entsize = 4;
642 
643 	ws = id->d_buf;
644 
645 	/* We only support COMDAT section. */
646 #ifndef GRP_COMDAT
647 #define	GRP_COMDAT 0x1
648 #endif
649 	if ((*ws & GRP_COMDAT) == 0)
650 		return;
651 
652 	if ((s->buf = malloc(ish.sh_size)) == NULL)
653 		err(EXIT_FAILURE, "malloc failed");
654 
655 	s->sz = ish.sh_size;
656 
657 	wd = s->buf;
658 
659 	/* Copy the flag word as-is. */
660 	*wd = *ws;
661 
662 	/* Update the section indices. */
663 	n = ish.sh_size / ish.sh_entsize;
664 	for(i = 1, j = 1; (uint64_t)i < n; i++) {
665 		if (ws[i] != SHN_UNDEF && ws[i] < ishnum &&
666 		    ecp->secndx[ws[i]] != 0)
667 			wd[j++] = ecp->secndx[ws[i]];
668 		else
669 			s->sz -= 4;
670 	}
671 
672 	s->nocopy = 1;
673 }
674 
675 /*
676  * Filter relocation entries, only keep those entries whose
677  * symbol is in the keep list.
678  */
679 static void
680 filter_reloc(struct elfcopy *ecp, struct section *s)
681 {
682 	const char	*name;
683 	GElf_Shdr	 ish;
684 	GElf_Rel	 rel;
685 	GElf_Rela	 rela;
686 	Elf32_Rel	*rel32;
687 	Elf64_Rel	*rel64;
688 	Elf32_Rela	*rela32;
689 	Elf64_Rela	*rela64;
690 	Elf_Data	*id;
691 	uint64_t	 cap, n, nrels;
692 	int		 elferr, i;
693 
694 	if (gelf_getshdr(s->is, &ish) == NULL)
695 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
696 		    elf_errmsg(-1));
697 
698 	/* We don't want to touch relocation info for dynamic symbols. */
699 	if ((ecp->flags & SYMTAB_EXIST) == 0) {
700 		if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0) {
701 			/*
702 			 * This reloc section applies to the symbol table
703 			 * that was stripped, so discard whole section.
704 			 */
705 			s->nocopy = 1;
706 			s->sz = 0;
707 		}
708 		return;
709 	} else {
710 		/* Symbol table exist, check if index equals. */
711 		if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
712 			return;
713 	}
714 
715 #define	COPYREL(REL, SZ) do {					\
716 	if (nrels == 0) {					\
717 		if ((REL##SZ = malloc(cap *			\
718 		    sizeof(Elf##SZ##_Rel))) == NULL)		\
719 			err(EXIT_FAILURE, "malloc failed");	\
720 	}							\
721 	if (nrels >= cap) {					\
722 		cap *= 2;					\
723 		if ((REL##SZ = realloc(REL##SZ, cap *		\
724 		    sizeof(Elf##SZ##_Rel))) == NULL)		\
725 			err(EXIT_FAILURE, "realloc failed");	\
726 	}							\
727 	REL##SZ[nrels].r_offset = REL.r_offset;			\
728 	REL##SZ[nrels].r_info	= REL.r_info;			\
729 	if (s->type == SHT_RELA)				\
730 		rela##SZ[nrels].r_addend = rela.r_addend;	\
731 	nrels++;						\
732 } while (0)
733 
734 	nrels = 0;
735 	cap = 4;		/* keep list is usually small. */
736 	rel32 = NULL;
737 	rel64 = NULL;
738 	rela32 = NULL;
739 	rela64 = NULL;
740 	if ((id = elf_getdata(s->is, NULL)) == NULL)
741 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
742 		    elf_errmsg(-1));
743 	n = ish.sh_size / ish.sh_entsize;
744 	for(i = 0; (uint64_t)i < n; i++) {
745 		if (s->type == SHT_REL) {
746 			if (gelf_getrel(id, i, &rel) != &rel)
747 				errx(EXIT_FAILURE, "gelf_getrel failed: %s",
748 				    elf_errmsg(-1));
749 		} else {
750 			if (gelf_getrela(id, i, &rela) != &rela)
751 				errx(EXIT_FAILURE, "gelf_getrel failed: %s",
752 				    elf_errmsg(-1));
753 		}
754 		name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
755 		    GELF_R_SYM(rel.r_info));
756 		if (name == NULL)
757 			errx(EXIT_FAILURE, "elf_strptr failed: %s",
758 			    elf_errmsg(-1));
759 		if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) {
760 			if (ecp->oec == ELFCLASS32) {
761 				if (s->type == SHT_REL)
762 					COPYREL(rel, 32);
763 				else
764 					COPYREL(rela, 32);
765 			} else {
766 				if (s->type == SHT_REL)
767 					COPYREL(rel, 64);
768 				else
769 					COPYREL(rela, 64);
770 			}
771 		}
772 	}
773 	elferr = elf_errno();
774 	if (elferr != 0)
775 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
776 		    elf_errmsg(elferr));
777 
778 	if (ecp->oec == ELFCLASS32) {
779 		if (s->type == SHT_REL)
780 			s->buf = rel32;
781 		else
782 			s->buf = rela32;
783 	} else {
784 		if (s->type == SHT_REL)
785 			s->buf = rel64;
786 		else
787 			s->buf = rela64;
788 	}
789 	s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
790 	    ELF_T_RELA), nrels, EV_CURRENT);
791 	s->nocopy = 1;
792 }
793 
794 static void
795 update_reloc(struct elfcopy *ecp, struct section *s)
796 {
797 	GElf_Shdr	 osh;
798 	GElf_Rel	 rel;
799 	GElf_Rela	 rela;
800 	Elf_Data	*od;
801 	uint64_t	 n;
802 	int		 i;
803 
804 #define UPDATEREL(REL) do {						\
805 	if (gelf_get##REL(od, i, &REL) != &REL)				\
806 		errx(EXIT_FAILURE, "gelf_get##REL failed: %s",		\
807 		    elf_errmsg(-1));					\
808 	REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)],	\
809 	    GELF_R_TYPE(REL.r_info));					\
810 	if (!gelf_update_##REL(od, i, &REL))				\
811 		errx(EXIT_FAILURE, "gelf_update_##REL failed: %s",	\
812 		    elf_errmsg(-1));					\
813 } while(0)
814 
815 	if (s->sz == 0)
816 		return;
817 	if (gelf_getshdr(s->os, &osh) == NULL)
818 		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
819 		    elf_errmsg(-1));
820 	/* Only process .symtab reloc info. */
821 	if (osh.sh_link != elf_ndxscn(ecp->symtab->is))
822 		return;
823 	if ((od = elf_getdata(s->os, NULL)) == NULL)
824 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
825 		    elf_errmsg(-1));
826 	n = osh.sh_size / osh.sh_entsize;
827 	for(i = 0; (uint64_t)i < n; i++) {
828 		if (s->type == SHT_REL)
829 			UPDATEREL(rel);
830 		else
831 			UPDATEREL(rela);
832 	}
833 }
834 
835 static void
836 pad_section(struct elfcopy *ecp, struct section *s)
837 {
838 	GElf_Shdr	 osh;
839 	Elf_Data	*od;
840 
841 	if (s == NULL || s->pad_sz == 0)
842 		return;
843 
844 	if ((s->pad = malloc(s->pad_sz)) == NULL)
845 		err(EXIT_FAILURE, "malloc failed");
846 	memset(s->pad, ecp->fill, s->pad_sz);
847 
848 	/* Create a new Elf_Data to contain the padding bytes. */
849 	if ((od = elf_newdata(s->os)) == NULL)
850 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
851 		    elf_errmsg(-1));
852 	od->d_align = 1;
853 	od->d_off = s->sz;
854 	od->d_buf = s->pad;
855 	od->d_type = ELF_T_BYTE;
856 	od->d_size = s->pad_sz;
857 	od->d_version = EV_CURRENT;
858 
859 	/* Update section header. */
860 	if (gelf_getshdr(s->os, &osh) == NULL)
861 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
862 		    elf_errmsg(-1));
863 	osh.sh_size = s->sz + s->pad_sz;
864 	if (!gelf_update_shdr(s->os, &osh))
865 		errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
866 		    elf_errmsg(-1));
867 }
868 
869 void
870 resync_sections(struct elfcopy *ecp)
871 {
872 	struct section	*s, *ps;
873 	GElf_Shdr	 osh;
874 	uint64_t	 off;
875 	int		 first;
876 
877 	ps = NULL;
878 	first = 1;
879 	off = 0;
880 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
881 		if (first) {
882 			off = s->off;
883 			first = 0;
884 		}
885 
886 		/*
887 		 * Ignore TLS sections with load address 0 and without
888 		 * content. We don't need to adjust their file offset or
889 		 * VMA, only the size matters.
890 		 */
891 		if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
892 		    s->off == 0)
893 			continue;
894 
895 		/* Align section offset. */
896 		if (s->align == 0)
897 			s->align = 1;
898 		if (off <= s->off) {
899 			if (!s->loadable || (ecp->flags & RELOCATABLE))
900 				s->off = roundup(off, s->align);
901 		} else {
902 			if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
903 				warnx("moving loadable section %s, "
904 				    "is this intentional?", s->name);
905 			s->off = roundup(off, s->align);
906 		}
907 
908 		/* Calculate next section offset. */
909 		off = s->off;
910 		if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
911 			off += s->sz;
912 
913 		if (s->pseudo) {
914 			ps = NULL;
915 			continue;
916 		}
917 
918 		/* Count padding bytes added through --pad-to. */
919 		if (s->pad_sz > 0)
920 			off += s->pad_sz;
921 
922 		/* Update section header accordingly. */
923 		if (gelf_getshdr(s->os, &osh) == NULL)
924 			errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
925 			    elf_errmsg(-1));
926 		osh.sh_addr = s->vma;
927 		osh.sh_offset = s->off;
928 		osh.sh_size = s->sz;
929 		if (!gelf_update_shdr(s->os, &osh))
930 			errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
931 			    elf_errmsg(-1));
932 
933 		/* Add padding for previous section, if need. */
934 		if (ps != NULL) {
935 			if (ps->pad_sz > 0) {
936 				/* Apply padding added by --pad-to. */
937 				pad_section(ecp, ps);
938 			} else if ((ecp->flags & GAP_FILL) &&
939 			    (ps->off + ps->sz < s->off)) {
940 				/*
941 				 * Fill the gap between sections by padding
942 				 * the section with lower address.
943 				 */
944 				ps->pad_sz = s->off - (ps->off + ps->sz);
945 				pad_section(ecp, ps);
946 			}
947 		}
948 
949 		ps = s;
950 	}
951 
952 	/* Pad the last section, if need. */
953 	if (ps != NULL && ps->pad_sz > 0)
954 		pad_section(ecp, ps);
955 }
956 
957 static void
958 modify_section(struct elfcopy *ecp, struct section *s)
959 {
960 	struct sec_action	*sac;
961 	size_t			 srcsz, dstsz, p, len;
962 	char			*b, *c, *d, *src, *end;
963 	int			 dupe;
964 
965 	src = read_section(s, &srcsz);
966 	if (src == NULL || srcsz == 0) {
967 		/* For empty section, we proceed if we need to append. */
968 		if (!is_append_section(ecp, s->name))
969 			return;
970 	}
971 
972 	/* Allocate buffer needed for new section data. */
973 	dstsz = srcsz;
974 	if (is_append_section(ecp, s->name)) {
975 		sac = lookup_sec_act(ecp, s->name, 0);
976 		dstsz += strlen(sac->string) + 1;
977 	}
978 	if ((b = malloc(dstsz)) == NULL)
979 		err(EXIT_FAILURE, "malloc failed");
980 	s->buf = b;
981 
982 	/* Compress section. */
983 	p = 0;
984 	if (is_compress_section(ecp, s->name)) {
985 		end = src + srcsz;
986 		for(c = src; c < end;) {
987 			len = 0;
988 			while(c + len < end && c[len] != '\0')
989 				len++;
990 			if (c + len == end) {
991 				/* XXX should we warn here? */
992 				strncpy(&b[p], c, len);
993 				p += len;
994 				break;
995 			}
996 			dupe = 0;
997 			for (d = b; d < b + p; ) {
998 				if (strcmp(d, c) == 0) {
999 					dupe = 1;
1000 					break;
1001 				}
1002 				d += strlen(d) + 1;
1003 			}
1004 			if (!dupe) {
1005 				strncpy(&b[p], c, len);
1006 				b[p + len] = '\0';
1007 				p += len + 1;
1008 			}
1009 			c += len + 1;
1010 		}
1011 	} else {
1012 		memcpy(b, src, srcsz);
1013 		p += srcsz;
1014 	}
1015 
1016 	/* Append section. */
1017 	if (is_append_section(ecp, s->name)) {
1018 		sac = lookup_sec_act(ecp, s->name, 0);
1019 		len = strlen(sac->string);
1020 		strncpy(&b[p], sac->string, len);
1021 		b[p + len] = '\0';
1022 		p += len + 1;
1023 	}
1024 
1025 	s->sz = p;
1026 	s->nocopy = 1;
1027 }
1028 
1029 static void
1030 print_data(const char *d, size_t sz)
1031 {
1032 	const char *c;
1033 
1034 	for (c = d; c < d + sz; c++) {
1035 		if (*c == '\0')
1036 			putchar('\n');
1037 		else
1038 			putchar(*c);
1039 	}
1040 }
1041 
1042 static void
1043 print_section(struct section *s)
1044 {
1045 	Elf_Data	*id;
1046 	int		 elferr;
1047 
1048 	if (s->buf != NULL && s->sz > 0) {
1049 		print_data(s->buf, s->sz);
1050 	} else {
1051 		id = NULL;
1052 		while ((id = elf_getdata(s->is, id)) != NULL ||
1053 		    (id = elf_rawdata(s->is, id)) != NULL) {
1054 			(void) elf_errno();
1055 			print_data(id->d_buf, id->d_size);
1056 		}
1057 		elferr = elf_errno();
1058 		if (elferr != 0)
1059 			errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1060 			    elf_errmsg(elferr));
1061 	}
1062 	putchar('\n');
1063 }
1064 
1065 static void *
1066 read_section(struct section *s, size_t *size)
1067 {
1068 	Elf_Data	*id;
1069 	char		*b;
1070 	size_t		 sz;
1071 	int		 elferr;
1072 
1073 	sz = 0;
1074 	b = NULL;
1075 	id = NULL;
1076 	while ((id = elf_getdata(s->is, id)) != NULL ||
1077 	    (id = elf_rawdata(s->is, id)) != NULL) {
1078 		(void) elf_errno();
1079 		if (b == NULL)
1080 			b = malloc(id->d_size);
1081 		else
1082 			b = malloc(sz + id->d_size);
1083 		if (b == NULL)
1084 			err(EXIT_FAILURE, "malloc or realloc failed");
1085 
1086 		memcpy(&b[sz], id->d_buf, id->d_size);
1087 		sz += id->d_size;
1088 	}
1089 	elferr = elf_errno();
1090 	if (elferr != 0)
1091 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1092 		    elf_errmsg(elferr));
1093 
1094 	*size = sz;
1095 
1096 	return (b);
1097 }
1098 
1099 void
1100 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1101     int sec_flags)
1102 {
1103 	GElf_Shdr ish, osh;
1104 
1105 	if (gelf_getshdr(s->is, &ish) == NULL)
1106 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1107 		    elf_errmsg(-1));
1108 	if (gelf_getshdr(s->os, &osh) == NULL)
1109 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1110 		    elf_errmsg(-1));
1111 
1112 	if (copy)
1113 		(void) memcpy(&osh, &ish, sizeof(ish));
1114 	else {
1115 		osh.sh_type		= s->type;
1116 		osh.sh_addr		= s->vma;
1117 		osh.sh_offset		= s->off;
1118 		osh.sh_size		= s->sz;
1119 		osh.sh_link		= ish.sh_link;
1120 		osh.sh_info		= ish.sh_info;
1121 		osh.sh_addralign	= s->align;
1122 		osh.sh_entsize		= ish.sh_entsize;
1123 
1124 		if (sec_flags) {
1125 			osh.sh_flags = 0;
1126 			if (sec_flags & SF_ALLOC)
1127 				osh.sh_flags |= SHF_ALLOC;
1128 			if ((sec_flags & SF_READONLY) == 0)
1129 				osh.sh_flags |= SHF_WRITE;
1130 			if (sec_flags & SF_CODE)
1131 				osh.sh_flags |= SHF_EXECINSTR;
1132 			if ((sec_flags & SF_CONTENTS) &&
1133 			    s->type == SHT_NOBITS && s->sz > 0) {
1134 				/*
1135 				 * Convert SHT_NOBITS section to section with
1136 				 * (zero'ed) content on file.
1137 				 */
1138 				osh.sh_type = s->type = SHT_PROGBITS;
1139 				if ((s->buf = calloc(1, s->sz)) == NULL)
1140 					err(EXIT_FAILURE, "malloc failed");
1141 				s->nocopy = 1;
1142 			}
1143 		} else {
1144 			osh.sh_flags = ish.sh_flags;
1145 			/*
1146 			 * Newer binutils as(1) emits the section flag
1147 			 * SHF_INFO_LINK for relocation sections. elfcopy
1148 			 * emits this flag in the output section if it's
1149 			 * missing in the input section, to remain compatible
1150 			 * with binutils.
1151 			 */
1152 			if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1153 				osh.sh_flags |= SHF_INFO_LINK;
1154 		}
1155 	}
1156 
1157 	if (name == NULL)
1158 		add_to_shstrtab(ecp, s->name);
1159 	else
1160 		add_to_shstrtab(ecp, name);
1161 
1162 	if (!gelf_update_shdr(s->os, &osh))
1163 		errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1164 		    elf_errmsg(-1));
1165 }
1166 
1167 void
1168 copy_data(struct section *s)
1169 {
1170 	Elf_Data	*id, *od;
1171 	int		 elferr;
1172 
1173 	if (s->nocopy && s->buf == NULL)
1174 		return;
1175 
1176 	if ((id = elf_getdata(s->is, NULL)) == NULL) {
1177 		(void) elf_errno();
1178 		if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1179 			elferr = elf_errno();
1180 			if (elferr != 0)
1181 				errx(EXIT_FAILURE, "failed to read section:"
1182 				    " %s", s->name);
1183 			return;
1184 		}
1185 	}
1186 
1187 	if ((od = elf_newdata(s->os)) == NULL)
1188 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1189 		    elf_errmsg(-1));
1190 
1191 	if (s->nocopy) {
1192 		/* Use s->buf as content if s->nocopy is set. */
1193 		od->d_align	= id->d_align;
1194 		od->d_off	= 0;
1195 		od->d_buf	= s->buf;
1196 		od->d_type	= id->d_type;
1197 		od->d_size	= s->sz;
1198 		od->d_version	= id->d_version;
1199 	} else {
1200 		od->d_align	= id->d_align;
1201 		od->d_off	= id->d_off;
1202 		od->d_buf	= id->d_buf;
1203 		od->d_type	= id->d_type;
1204 		od->d_size	= id->d_size;
1205 		od->d_version	= id->d_version;
1206 	}
1207 
1208 	/*
1209 	 * Alignment Fixup. libelf does not allow the alignment for
1210 	 * Elf_Data descriptor to be set to 0. In this case we workaround
1211 	 * it by setting the alignment to 1.
1212 	 *
1213 	 * According to the ELF ABI, alignment 0 and 1 has the same
1214 	 * meaning: the section has no alignment constraints.
1215 	 */
1216 	if (od->d_align == 0)
1217 		od->d_align = 1;
1218 }
1219 
1220 struct section *
1221 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1222     void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1223     uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1224 {
1225 	struct section	*s;
1226 	Elf_Scn		*os;
1227 	Elf_Data	*od;
1228 	GElf_Shdr	 osh;
1229 
1230 	if ((os = elf_newscn(ecp->eout)) == NULL)
1231 		errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1232 		    elf_errmsg(-1));
1233 	if ((s = calloc(1, sizeof(*s))) == NULL)
1234 		err(EXIT_FAILURE, "calloc failed");
1235 	s->name = name;
1236 	s->newname = newname;	/* needs to be free()'ed */
1237 	s->off = off;
1238 	s->sz = size;
1239 	s->vma = vma;
1240 	s->align = align;
1241 	s->loadable = loadable;
1242 	s->is = NULL;
1243 	s->os = os;
1244 	s->type = stype;
1245 	s->nocopy = 1;
1246 	insert_to_sec_list(ecp, s, 1);
1247 
1248 	if (gelf_getshdr(os, &osh) == NULL)
1249 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1250 		    elf_errmsg(-1));
1251 	osh.sh_flags = flags;
1252 	osh.sh_type = s->type;
1253 	osh.sh_addr = s->vma;
1254 	osh.sh_addralign = s->align;
1255 	if (!gelf_update_shdr(os, &osh))
1256 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1257 		    elf_errmsg(-1));
1258 	add_to_shstrtab(ecp, name);
1259 
1260 	if (buf != NULL && size != 0) {
1261 		if ((od = elf_newdata(os)) == NULL)
1262 			errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1263 			    elf_errmsg(-1));
1264 		od->d_align = align;
1265 		od->d_off = 0;
1266 		od->d_buf = buf;
1267 		od->d_size = size;
1268 		od->d_type = dtype;
1269 		od->d_version = EV_CURRENT;
1270 	}
1271 
1272 	/*
1273 	 * Clear SYMTAB_INTACT, as we probably need to update/add new
1274 	 * STT_SECTION symbols into the symbol table.
1275 	 */
1276 	ecp->flags &= ~SYMTAB_INTACT;
1277 
1278 	return (s);
1279 }
1280 
1281 /*
1282  * Insert sections specified by --add-section to the end of section list.
1283  */
1284 static void
1285 insert_sections(struct elfcopy *ecp)
1286 {
1287 	struct sec_add	*sa;
1288 	struct section	*s;
1289 	size_t		 off;
1290 	uint64_t	 stype;
1291 
1292 	/* Put these sections in the end of current list. */
1293 	off = 0;
1294 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1295 		if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1296 			off = s->off + s->sz;
1297 		else
1298 			off = s->off;
1299 	}
1300 
1301 	STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1302 
1303 		/* TODO: Add section header vma/lma, flag changes here */
1304 
1305 		/*
1306 		 * The default section type for user added section is
1307 		 * SHT_PROGBITS. If the section name match certain patterns,
1308 		 * elfcopy will try to set a more appropriate section type.
1309 		 * However, data type is always set to ELF_T_BYTE and no
1310 		 * translation is performed by libelf.
1311 		 */
1312 		stype = SHT_PROGBITS;
1313 		if (strcmp(sa->name, ".note") == 0 ||
1314 		    strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1315 			stype = SHT_NOTE;
1316 
1317 		(void) create_external_section(ecp, sa->name, NULL, sa->content,
1318 		    sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1319 	}
1320 }
1321 
1322 void
1323 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1324 {
1325 	struct section *s;
1326 
1327 	s = ecp->shstrtab;
1328 	insert_to_strtab(s, name);
1329 }
1330 
1331 void
1332 update_shdr(struct elfcopy *ecp, int update_link)
1333 {
1334 	struct section	*s;
1335 	GElf_Shdr	 osh;
1336 	int		 elferr;
1337 
1338 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1339 		if (s->pseudo)
1340 			continue;
1341 
1342 		if (gelf_getshdr(s->os, &osh) == NULL)
1343 			errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1344 			    elf_errmsg(-1));
1345 
1346 		/* Find section name in string table and set sh_name. */
1347 		osh.sh_name = lookup_string(ecp->shstrtab, s->name);
1348 
1349 		/*
1350 		 * sh_link needs to be updated, since the index of the
1351 		 * linked section might have changed.
1352 		 */
1353 		if (update_link && osh.sh_link != 0)
1354 			osh.sh_link = ecp->secndx[osh.sh_link];
1355 
1356 		/*
1357 		 * sh_info of relocation section links to the section to which
1358 		 * its relocation info applies. So it may need update as well.
1359 		 */
1360 		if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1361 		    osh.sh_info != 0)
1362 			osh.sh_info = ecp->secndx[osh.sh_info];
1363 
1364 		/*
1365 		 * sh_info of SHT_GROUP section needs to point to the correct
1366 		 * string in the symbol table.
1367 		 */
1368 		if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) &&
1369 		    (ecp->flags & SYMTAB_INTACT) == 0)
1370 			osh.sh_info = ecp->symndx[osh.sh_info];
1371 
1372 		if (!gelf_update_shdr(s->os, &osh))
1373 			errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1374 			    elf_errmsg(-1));
1375 	}
1376 	elferr = elf_errno();
1377 	if (elferr != 0)
1378 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1379 		    elf_errmsg(elferr));
1380 }
1381 
1382 void
1383 init_shstrtab(struct elfcopy *ecp)
1384 {
1385 	struct section *s;
1386 
1387 	if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1388 		err(EXIT_FAILURE, "calloc failed");
1389 	s = ecp->shstrtab;
1390 	s->name = ".shstrtab";
1391 	s->is = NULL;
1392 	s->sz = 0;
1393 	s->align = 1;
1394 	s->loadable = 0;
1395 	s->type = SHT_STRTAB;
1396 	s->vma = 0;
1397 
1398 	insert_to_strtab(s, "");
1399 	insert_to_strtab(s, ".symtab");
1400 	insert_to_strtab(s, ".strtab");
1401 	insert_to_strtab(s, ".shstrtab");
1402 }
1403 
1404 void
1405 set_shstrtab(struct elfcopy *ecp)
1406 {
1407 	struct section	*s;
1408 	Elf_Data	*data;
1409 	GElf_Shdr	 sh;
1410 
1411 	s = ecp->shstrtab;
1412 
1413 	if (s->os == NULL) {
1414 		/* Input object does not contain .shstrtab section */
1415 		if ((s->os = elf_newscn(ecp->eout)) == NULL)
1416 			errx(EXIT_FAILURE, "elf_newscn failed: %s",
1417 			    elf_errmsg(-1));
1418 		insert_to_sec_list(ecp, s, 1);
1419 	}
1420 
1421 	if (gelf_getshdr(s->os, &sh) == NULL)
1422 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1423 		    elf_errmsg(-1));
1424 	sh.sh_addr	= 0;
1425 	sh.sh_addralign	= 1;
1426 	sh.sh_offset	= s->off;
1427 	sh.sh_type	= SHT_STRTAB;
1428 	sh.sh_flags	= 0;
1429 	sh.sh_entsize	= 0;
1430 	sh.sh_info	= 0;
1431 	sh.sh_link	= 0;
1432 
1433 	if ((data = elf_newdata(s->os)) == NULL)
1434 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1435 		    elf_errmsg(-1));
1436 
1437 	/*
1438 	 * If we don't have a symbol table, skip those a few bytes
1439 	 * which are reserved for this in the beginning of shstrtab.
1440 	 */
1441 	if (!(ecp->flags & SYMTAB_EXIST)) {
1442 		s->sz -= sizeof(".symtab\0.strtab");
1443 		memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
1444 		    s->sz);
1445 	}
1446 
1447 	sh.sh_size	= s->sz;
1448 	if (!gelf_update_shdr(s->os, &sh))
1449 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1450 		    elf_errmsg(-1));
1451 
1452 	data->d_align	= 1;
1453 	data->d_buf	= s->buf;
1454 	data->d_size	= s->sz;
1455 	data->d_off	= 0;
1456 	data->d_type	= ELF_T_BYTE;
1457 	data->d_version	= EV_CURRENT;
1458 
1459 	if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1460 		errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1461 		     elf_errmsg(-1));
1462 }
1463 
1464 void
1465 add_section(struct elfcopy *ecp, const char *arg)
1466 {
1467 	struct sec_add	*sa;
1468 	struct stat	 sb;
1469 	const char	*s, *fn;
1470 	FILE		*fp;
1471 	int		 len;
1472 
1473 	if ((s = strchr(arg, '=')) == NULL)
1474 		errx(EXIT_FAILURE,
1475 		    "illegal format for --add-section option");
1476 	if ((sa = malloc(sizeof(*sa))) == NULL)
1477 		err(EXIT_FAILURE, "malloc failed");
1478 
1479 	len = s - arg;
1480 	if ((sa->name = malloc(len + 1)) == NULL)
1481 		err(EXIT_FAILURE, "malloc failed");
1482 	strncpy(sa->name, arg, len);
1483 	sa->name[len] = '\0';
1484 
1485 	fn = s + 1;
1486 	if (stat(fn, &sb) == -1)
1487 		err(EXIT_FAILURE, "stat failed");
1488 	sa->size = sb.st_size;
1489 	if (sa->size > 0) {
1490 		if ((sa->content = malloc(sa->size)) == NULL)
1491 			err(EXIT_FAILURE, "malloc failed");
1492 		if ((fp = fopen(fn, "r")) == NULL)
1493 			err(EXIT_FAILURE, "can not open %s", fn);
1494 		if (fread(sa->content, 1, sa->size, fp) == 0 ||
1495 		    ferror(fp))
1496 			err(EXIT_FAILURE, "fread failed");
1497 		fclose(fp);
1498 	} else
1499 		sa->content = NULL;
1500 
1501 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1502 	ecp->flags |= SEC_ADD;
1503 }
1504 
1505 void
1506 free_sec_add(struct elfcopy *ecp)
1507 {
1508 	struct sec_add *sa, *sa_temp;
1509 
1510 	STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1511 		STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1512 		free(sa->name);
1513 		free(sa->content);
1514 		free(sa);
1515 	}
1516 }
1517 
1518 static void
1519 add_gnu_debuglink(struct elfcopy *ecp)
1520 {
1521 	struct sec_add	*sa;
1522 	struct stat	 sb;
1523 	FILE		*fp;
1524 	char		*fnbase, *buf;
1525 	int		 crc_off;
1526 	int		 crc;
1527 
1528 	if (ecp->debuglink == NULL)
1529 		return;
1530 
1531 	/* Read debug file content. */
1532 	if ((sa = malloc(sizeof(*sa))) == NULL)
1533 		err(EXIT_FAILURE, "malloc failed");
1534 	if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1535 		err(EXIT_FAILURE, "strdup failed");
1536 	if (stat(ecp->debuglink, &sb) == -1)
1537 		err(EXIT_FAILURE, "stat failed");
1538 	if (sb.st_size == 0)
1539 		errx(EXIT_FAILURE, "empty debug link target %s",
1540 		    ecp->debuglink);
1541 	if ((buf = malloc(sb.st_size)) == NULL)
1542 		err(EXIT_FAILURE, "malloc failed");
1543 	if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1544 		err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1545 	if (fread(buf, 1, sb.st_size, fp) == 0 ||
1546 	    ferror(fp))
1547 		err(EXIT_FAILURE, "fread failed");
1548 	fclose(fp);
1549 
1550 	/* Calculate crc checksum.  */
1551 	crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1552 	free(buf);
1553 
1554 	/* Calculate section size and the offset to store crc checksum. */
1555 	if ((fnbase = basename(ecp->debuglink)) == NULL)
1556 		err(EXIT_FAILURE, "basename failed");
1557 	crc_off = roundup(strlen(fnbase) + 1, 4);
1558 	sa->size = crc_off + 4;
1559 
1560 	/* Section content. */
1561 	if ((sa->content = calloc(1, sa->size)) == NULL)
1562 		err(EXIT_FAILURE, "malloc failed");
1563 	strncpy(sa->content, fnbase, strlen(fnbase));
1564 	if (ecp->oed == ELFDATA2LSB) {
1565 		sa->content[crc_off] = crc & 0xFF;
1566 		sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1567 		sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1568 		sa->content[crc_off + 3] = crc >> 24;
1569 	} else {
1570 		sa->content[crc_off] = crc >> 24;
1571 		sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1572 		sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1573 		sa->content[crc_off + 3] = crc & 0xFF;
1574 	}
1575 
1576 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1577 	ecp->flags |= SEC_ADD;
1578 }
1579 
1580 static void
1581 insert_to_strtab(struct section *t, const char *s)
1582 {
1583 	const char	*r;
1584 	char		*b, *c;
1585 	size_t		 len, slen;
1586 	int		 append;
1587 
1588 	if (t->sz == 0) {
1589 		t->cap = 512;
1590 		if ((t->buf = malloc(t->cap)) == NULL)
1591 			err(EXIT_FAILURE, "malloc failed");
1592 	}
1593 
1594 	slen = strlen(s);
1595 	append = 0;
1596 	b = t->buf;
1597 	for (c = b; c < b + t->sz;) {
1598 		len = strlen(c);
1599 		if (!append && len >= slen) {
1600 			r = c + (len - slen);
1601 			if (strcmp(r, s) == 0)
1602 				return;
1603 		} else if (len < slen && len != 0) {
1604 			r = s + (slen - len);
1605 			if (strcmp(c, r) == 0) {
1606 				t->sz -= len + 1;
1607 				memmove(c, c + len + 1, t->sz - (c - b));
1608 				append = 1;
1609 				continue;
1610 			}
1611 		}
1612 		c += len + 1;
1613 	}
1614 
1615 	while (t->sz + slen + 1 >= t->cap) {
1616 		t->cap *= 2;
1617 		if ((t->buf = realloc(t->buf, t->cap)) == NULL)
1618 			err(EXIT_FAILURE, "realloc failed");
1619 	}
1620 	b = t->buf;
1621 	strncpy(&b[t->sz], s, slen);
1622 	b[t->sz + slen] = '\0';
1623 	t->sz += slen + 1;
1624 }
1625 
1626 static int
1627 lookup_string(struct section *t, const char *s)
1628 {
1629 	const char	*b, *c, *r;
1630 	size_t		 len, slen;
1631 
1632 	slen = strlen(s);
1633 	b = t->buf;
1634 	for (c = b; c < b + t->sz;) {
1635 		len = strlen(c);
1636 		if (len >= slen) {
1637 			r = c + (len - slen);
1638 			if (strcmp(r, s) == 0)
1639 				return (r - b);
1640 		}
1641 		c += len + 1;
1642 	}
1643 
1644 	return (-1);
1645 }
1646 
1647 static uint32_t crctable[256] =
1648 {
1649 	0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1650 	0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1651 	0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1652 	0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1653 	0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1654 	0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1655 	0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1656 	0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1657 	0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1658 	0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1659 	0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1660 	0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1661 	0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1662 	0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1663 	0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1664 	0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1665 	0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1666 	0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1667 	0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1668 	0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1669 	0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1670 	0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1671 	0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1672 	0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1673 	0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1674 	0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1675 	0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1676 	0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1677 	0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1678 	0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1679 	0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1680 	0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1681 	0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1682 	0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1683 	0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1684 	0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1685 	0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1686 	0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1687 	0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1688 	0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1689 	0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1690 	0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1691 	0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1692 	0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1693 	0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1694 	0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1695 	0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1696 	0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1697 	0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1698 	0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1699 	0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1700 	0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1701 	0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1702 	0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1703 	0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1704 	0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1705 	0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1706 	0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1707 	0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1708 	0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1709 	0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1710 	0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1711 	0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1712 	0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1713 };
1714 
1715 static uint32_t
1716 calc_crc32(const char *p, size_t len, uint32_t crc)
1717 {
1718 	uint32_t i;
1719 
1720 	for (i = 0; i < len; i++) {
1721 		crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1722 	}
1723 
1724 	return (crc ^ 0xFFFFFFFF);
1725 }
1726