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