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