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