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