xref: /freebsd/contrib/elftoolchain/elfcopy/sections.c (revision 545ddfbe7d4fe8adfb862903b24eac1d5896c1ef)
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 (s->align == 0)
781 			s->align = 1;
782 		if (off <= s->off) {
783 			if (!s->loadable)
784 				s->off = roundup(off, s->align);
785 		} else {
786 			if (s->loadable)
787 				warnx("moving loadable section %s, "
788 				    "is this intentional?", s->name);
789 			s->off = roundup(off, s->align);
790 		}
791 
792 		/* Calculate next section offset. */
793 		off = s->off;
794 		if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
795 			off += s->sz;
796 
797 		if (s->pseudo) {
798 			ps = NULL;
799 			continue;
800 		}
801 
802 		/* Count padding bytes added through --pad-to. */
803 		if (s->pad_sz > 0)
804 			off += s->pad_sz;
805 
806 		/* Update section header accordingly. */
807 		if (gelf_getshdr(s->os, &osh) == NULL)
808 			errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
809 			    elf_errmsg(-1));
810 		osh.sh_addr = s->vma;
811 		osh.sh_offset = s->off;
812 		osh.sh_size = s->sz;
813 		if (!gelf_update_shdr(s->os, &osh))
814 			errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
815 			    elf_errmsg(-1));
816 
817 		/* Add padding for previous section, if need. */
818 		if (ps != NULL) {
819 			if (ps->pad_sz > 0) {
820 				/* Apply padding added by --pad-to. */
821 				pad_section(ecp, ps);
822 			} else if ((ecp->flags & GAP_FILL) &&
823 			    (ps->off + ps->sz < s->off)) {
824 				/*
825 				 * Fill the gap between sections by padding
826 				 * the section with lower address.
827 				 */
828 				ps->pad_sz = s->off - (ps->off + ps->sz);
829 				pad_section(ecp, ps);
830 			}
831 		}
832 
833 		ps = s;
834 	}
835 
836 	/* Pad the last section, if need. */
837 	if (ps != NULL && ps->pad_sz > 0)
838 		pad_section(ecp, ps);
839 }
840 
841 static void
842 modify_section(struct elfcopy *ecp, struct section *s)
843 {
844 	struct sec_action	*sac;
845 	size_t			 srcsz, dstsz, p, len;
846 	char			*b, *c, *d, *src, *end;
847 	int			 dupe;
848 
849 	src = read_section(s, &srcsz);
850 	if (src == NULL || srcsz == 0) {
851 		/* For empty section, we proceed if we need to append. */
852 		if (!is_append_section(ecp, s->name))
853 			return;
854 	}
855 
856 	/* Allocate buffer needed for new section data. */
857 	dstsz = srcsz;
858 	if (is_append_section(ecp, s->name)) {
859 		sac = lookup_sec_act(ecp, s->name, 0);
860 		dstsz += strlen(sac->string) + 1;
861 	}
862 	if ((b = malloc(dstsz)) == NULL)
863 		err(EXIT_FAILURE, "malloc failed");
864 	s->buf = b;
865 
866 	/* Compress section. */
867 	p = 0;
868 	if (is_compress_section(ecp, s->name)) {
869 		end = src + srcsz;
870 		for(c = src; c < end;) {
871 			len = 0;
872 			while(c + len < end && c[len] != '\0')
873 				len++;
874 			if (c + len == end) {
875 				/* XXX should we warn here? */
876 				strncpy(&b[p], c, len);
877 				p += len;
878 				break;
879 			}
880 			dupe = 0;
881 			for (d = b; d < b + p; ) {
882 				if (strcmp(d, c) == 0) {
883 					dupe = 1;
884 					break;
885 				}
886 				d += strlen(d) + 1;
887 			}
888 			if (!dupe) {
889 				strncpy(&b[p], c, len);
890 				b[p + len] = '\0';
891 				p += len + 1;
892 			}
893 			c += len + 1;
894 		}
895 	} else {
896 		memcpy(b, src, srcsz);
897 		p += srcsz;
898 	}
899 
900 	/* Append section. */
901 	if (is_append_section(ecp, s->name)) {
902 		sac = lookup_sec_act(ecp, s->name, 0);
903 		len = strlen(sac->string);
904 		strncpy(&b[p], sac->string, len);
905 		b[p + len] = '\0';
906 		p += len + 1;
907 	}
908 
909 	s->sz = p;
910 	s->nocopy = 1;
911 }
912 
913 static void
914 print_data(const char *d, size_t sz)
915 {
916 	const char *c;
917 
918 	for (c = d; c < d + sz; c++) {
919 		if (*c == '\0')
920 			putchar('\n');
921 		else
922 			putchar(*c);
923 	}
924 }
925 
926 static void
927 print_section(struct section *s)
928 {
929 	Elf_Data	*id;
930 	int		 elferr;
931 
932 	if (s->buf != NULL && s->sz > 0) {
933 		print_data(s->buf, s->sz);
934 	} else {
935 		id = NULL;
936 		while ((id = elf_getdata(s->is, id)) != NULL)
937 			print_data(id->d_buf, id->d_size);
938 		elferr = elf_errno();
939 		if (elferr != 0)
940 			errx(EXIT_FAILURE, "elf_getdata() failed: %s",
941 			    elf_errmsg(elferr));
942 	}
943 	putchar('\n');
944 }
945 
946 static void *
947 read_section(struct section *s, size_t *size)
948 {
949 	Elf_Data	*id;
950 	char		*b;
951 	size_t		 sz;
952 	int		 elferr;
953 
954 	sz = 0;
955 	b = NULL;
956 	id = NULL;
957 	while ((id = elf_getdata(s->is, id)) != NULL) {
958 		if (b == NULL)
959 			b = malloc(id->d_size);
960 		else
961 			b = malloc(sz + id->d_size);
962 		if (b == NULL)
963 			err(EXIT_FAILURE, "malloc or realloc failed");
964 
965 		memcpy(&b[sz], id->d_buf, id->d_size);
966 		sz += id->d_size;
967 	}
968 	elferr = elf_errno();
969 	if (elferr != 0)
970 		errx(EXIT_FAILURE, "elf_getdata() failed: %s",
971 		    elf_errmsg(elferr));
972 
973 	*size = sz;
974 
975 	return (b);
976 }
977 
978 void
979 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
980     int sec_flags)
981 {
982 	GElf_Shdr ish, osh;
983 
984 	if (gelf_getshdr(s->is, &ish) == NULL)
985 		errx(EXIT_FAILURE, "526 gelf_getshdr() failed: %s",
986 		    elf_errmsg(-1));
987 	if (gelf_getshdr(s->os, &osh) == NULL)
988 		errx(EXIT_FAILURE, "529 gelf_getshdr() failed: %s",
989 		    elf_errmsg(-1));
990 
991 	if (copy)
992 		(void) memcpy(&osh, &ish, sizeof(ish));
993 	else {
994 		osh.sh_type		= s->type;
995 		osh.sh_addr		= s->vma;
996 		osh.sh_offset		= s->off;
997 		osh.sh_size		= s->sz;
998 		osh.sh_link		= ish.sh_link;
999 		osh.sh_info		= ish.sh_info;
1000 		osh.sh_addralign	= s->align;
1001 		osh.sh_entsize		= ish.sh_entsize;
1002 
1003 		if (sec_flags) {
1004 			osh.sh_flags = 0;
1005 			if (sec_flags & SF_ALLOC) {
1006 				osh.sh_flags |= SHF_ALLOC;
1007 				if (!s->loadable)
1008 					warnx("set SHF_ALLOC flag for "
1009 					    "unloadable section %s",
1010 					    s->name);
1011 			}
1012 			if ((sec_flags & SF_READONLY) == 0)
1013 				osh.sh_flags |= SHF_WRITE;
1014 			if (sec_flags & SF_CODE)
1015 				osh.sh_flags |= SHF_EXECINSTR;
1016 		} else
1017 			osh.sh_flags = ish.sh_flags;
1018 	}
1019 
1020 	if (name == NULL)
1021 		add_to_shstrtab(ecp, s->name);
1022 	else
1023 		add_to_shstrtab(ecp, name);
1024 
1025 	if (!gelf_update_shdr(s->os, &osh))
1026 		errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1027 		    elf_errmsg(-1));
1028 }
1029 
1030 void
1031 copy_data(struct section *s)
1032 {
1033 	Elf_Data	*id, *od;
1034 	int		 elferr;
1035 
1036 	if (s->nocopy && s->buf == NULL)
1037 		return;
1038 
1039 	if ((id = elf_getdata(s->is, NULL)) == NULL) {
1040 		elferr = elf_errno();
1041 		if (elferr != 0)
1042 			errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1043 			    elf_errmsg(elferr));
1044 		return;
1045 	}
1046 
1047 	if ((od = elf_newdata(s->os)) == NULL)
1048 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1049 		    elf_errmsg(-1));
1050 
1051 	if (s->nocopy) {
1052 		/* Use s->buf as content if s->nocopy is set. */
1053 		od->d_align	= id->d_align;
1054 		od->d_off	= 0;
1055 		od->d_buf	= s->buf;
1056 		od->d_type	= id->d_type;
1057 		od->d_size	= s->sz;
1058 		od->d_version	= id->d_version;
1059 	} else {
1060 		od->d_align	= id->d_align;
1061 		od->d_off	= id->d_off;
1062 		od->d_buf	= id->d_buf;
1063 		od->d_type	= id->d_type;
1064 		od->d_size	= id->d_size;
1065 		od->d_version	= id->d_version;
1066 	}
1067 
1068 	/*
1069 	 * Alignment Fixup. libelf does not allow the alignment for
1070 	 * Elf_Data descriptor to be set to 0. In this case we workaround
1071 	 * it by setting the alignment to 1.
1072 	 *
1073 	 * According to the ELF ABI, alignment 0 and 1 has the same
1074 	 * meaning: the section has no alignment constraints.
1075 	 */
1076 	if (od->d_align == 0)
1077 		od->d_align = 1;
1078 }
1079 
1080 struct section *
1081 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1082     void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1083     uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1084 {
1085 	struct section	*s;
1086 	Elf_Scn		*os;
1087 	Elf_Data	*od;
1088 	GElf_Shdr	 osh;
1089 
1090 	if ((os = elf_newscn(ecp->eout)) == NULL)
1091 		errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1092 		    elf_errmsg(-1));
1093 	if ((s = calloc(1, sizeof(*s))) == NULL)
1094 		err(EXIT_FAILURE, "calloc failed");
1095 	s->name = name;
1096 	s->newname = newname;	/* needs to be free()'ed */
1097 	s->off = off;
1098 	s->sz = size;
1099 	s->vma = vma;
1100 	s->align = align;
1101 	s->loadable = loadable;
1102 	s->is = NULL;
1103 	s->os = os;
1104 	s->type = stype;
1105 	s->nocopy = 1;
1106 	insert_to_sec_list(ecp, s, 1);
1107 
1108 	if (gelf_getshdr(os, &osh) == NULL)
1109 		errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1110 		    elf_errmsg(-1));
1111 	osh.sh_flags = flags;
1112 	osh.sh_type = s->type;
1113 	osh.sh_addr = s->vma;
1114 	osh.sh_addralign = s->align;
1115 	if (!gelf_update_shdr(os, &osh))
1116 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1117 		    elf_errmsg(-1));
1118 	add_to_shstrtab(ecp, name);
1119 
1120 	if (buf != NULL && size != 0) {
1121 		if ((od = elf_newdata(os)) == NULL)
1122 			errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1123 			    elf_errmsg(-1));
1124 		od->d_align = align;
1125 		od->d_off = 0;
1126 		od->d_buf = buf;
1127 		od->d_size = size;
1128 		od->d_type = dtype;
1129 		od->d_version = EV_CURRENT;
1130 	}
1131 
1132 	/*
1133 	 * Clear SYMTAB_INTACT, as we probably need to update/add new
1134 	 * STT_SECTION symbols into the symbol table.
1135 	 */
1136 	ecp->flags &= ~SYMTAB_INTACT;
1137 
1138 	return (s);
1139 }
1140 
1141 /*
1142  * Insert sections specified by --add-section to the end of section list.
1143  */
1144 static void
1145 insert_sections(struct elfcopy *ecp)
1146 {
1147 	struct sec_add	*sa;
1148 	struct section	*s;
1149 	size_t		 off;
1150 
1151 	/* Put these sections in the end of current list. */
1152 	off = 0;
1153 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1154 		if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1155 			off = s->off + s->sz;
1156 		else
1157 			off = s->off;
1158 	}
1159 
1160 	STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1161 
1162 		/* TODO: Add section header vma/lma, flag changes here */
1163 
1164 		(void) create_external_section(ecp, sa->name, NULL, sa->content,
1165 		    sa->size, off, SHT_PROGBITS, ELF_T_BYTE, 0, 1, 0, 0);
1166 	}
1167 }
1168 
1169 void
1170 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1171 {
1172 	struct section *s;
1173 
1174 	s = ecp->shstrtab;
1175 	insert_to_strtab(s, name);
1176 }
1177 
1178 void
1179 update_shdr(struct elfcopy *ecp, int update_link)
1180 {
1181 	struct section	*s;
1182 	GElf_Shdr	 osh;
1183 	int		 elferr;
1184 
1185 	TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1186 		if (s->pseudo)
1187 			continue;
1188 
1189 		if (gelf_getshdr(s->os, &osh) == NULL)
1190 			errx(EXIT_FAILURE, "668 gelf_getshdr failed: %s",
1191 			    elf_errmsg(-1));
1192 
1193 		/* Find section name in string table and set sh_name. */
1194 		osh.sh_name = lookup_string(ecp->shstrtab, s->name);
1195 
1196 		/*
1197 		 * sh_link needs to be updated, since the index of the
1198 		 * linked section might have changed.
1199 		 */
1200 		if (update_link && osh.sh_link != 0)
1201 			osh.sh_link = ecp->secndx[osh.sh_link];
1202 
1203 		/*
1204 		 * sh_info of relocation section links to the section to which
1205 		 * its relocation info applies. So it may need update as well.
1206 		 */
1207 		if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1208 		    osh.sh_info != 0)
1209 			osh.sh_info = ecp->secndx[osh.sh_info];
1210 
1211 		if (!gelf_update_shdr(s->os, &osh))
1212 			errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1213 			    elf_errmsg(-1));
1214 	}
1215 	elferr = elf_errno();
1216 	if (elferr != 0)
1217 		errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1218 		    elf_errmsg(elferr));
1219 }
1220 
1221 void
1222 init_shstrtab(struct elfcopy *ecp)
1223 {
1224 	struct section *s;
1225 
1226 	if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1227 		err(EXIT_FAILURE, "calloc failed");
1228 	s = ecp->shstrtab;
1229 	s->name = ".shstrtab";
1230 	s->is = NULL;
1231 	s->sz = 0;
1232 	s->align = 1;
1233 	s->loadable = 0;
1234 	s->type = SHT_STRTAB;
1235 	s->vma = 0;
1236 
1237 	insert_to_strtab(s, "");
1238 	insert_to_strtab(s, ".symtab");
1239 	insert_to_strtab(s, ".strtab");
1240 	insert_to_strtab(s, ".shstrtab");
1241 }
1242 
1243 void
1244 set_shstrtab(struct elfcopy *ecp)
1245 {
1246 	struct section	*s;
1247 	Elf_Data	*data;
1248 	GElf_Shdr	 sh;
1249 
1250 	s = ecp->shstrtab;
1251 
1252 	if (gelf_getshdr(s->os, &sh) == NULL)
1253 		errx(EXIT_FAILURE, "692 gelf_getshdr() failed: %s",
1254 		    elf_errmsg(-1));
1255 	sh.sh_addr	= 0;
1256 	sh.sh_addralign	= 1;
1257 	sh.sh_offset	= s->off;
1258 	sh.sh_type	= SHT_STRTAB;
1259 	sh.sh_flags	= 0;
1260 	sh.sh_entsize	= 0;
1261 	sh.sh_info	= 0;
1262 	sh.sh_link	= 0;
1263 
1264 	if ((data = elf_newdata(s->os)) == NULL)
1265 		errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1266 		    elf_errmsg(-1));
1267 
1268 	/*
1269 	 * If we don't have a symbol table, skip those a few bytes
1270 	 * which are reserved for this in the beginning of shstrtab.
1271 	 */
1272 	if (!(ecp->flags & SYMTAB_EXIST)) {
1273 		s->sz -= sizeof(".symtab\0.strtab");
1274 		memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"),
1275 		    s->sz);
1276 	}
1277 
1278 	sh.sh_size	= s->sz;
1279 	if (!gelf_update_shdr(s->os, &sh))
1280 		errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1281 		    elf_errmsg(-1));
1282 
1283 	data->d_align	= 1;
1284 	data->d_buf	= s->buf;
1285 	data->d_size	= s->sz;
1286 	data->d_off	= 0;
1287 	data->d_type	= ELF_T_BYTE;
1288 	data->d_version	= EV_CURRENT;
1289 
1290 	if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1291 		errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1292 		     elf_errmsg(-1));
1293 }
1294 
1295 void
1296 add_section(struct elfcopy *ecp, const char *arg)
1297 {
1298 	struct sec_add	*sa;
1299 	struct stat	 sb;
1300 	const char	*s, *fn;
1301 	FILE		*fp;
1302 	int		 len;
1303 
1304 	if ((s = strchr(arg, '=')) == NULL)
1305 		errx(EXIT_FAILURE,
1306 		    "illegal format for --add-section option");
1307 	if ((sa = malloc(sizeof(*sa))) == NULL)
1308 		err(EXIT_FAILURE, "malloc failed");
1309 
1310 	len = s - arg;
1311 	if ((sa->name = malloc(len + 1)) == NULL)
1312 		err(EXIT_FAILURE, "malloc failed");
1313 	strncpy(sa->name, arg, len);
1314 	sa->name[len] = '\0';
1315 
1316 	fn = s + 1;
1317 	if (stat(fn, &sb) == -1)
1318 		err(EXIT_FAILURE, "stat failed");
1319 	sa->size = sb.st_size;
1320 	if ((sa->content = malloc(sa->size)) == NULL)
1321 		err(EXIT_FAILURE, "malloc failed");
1322 	if ((fp = fopen(fn, "r")) == NULL)
1323 		err(EXIT_FAILURE, "can not open %s", fn);
1324 	if (fread(sa->content, 1, sa->size, fp) == 0 ||
1325 	    ferror(fp))
1326 		err(EXIT_FAILURE, "fread failed");
1327 	fclose(fp);
1328 
1329 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1330 	ecp->flags |= SEC_ADD;
1331 }
1332 
1333 void
1334 free_sec_add(struct elfcopy *ecp)
1335 {
1336 	struct sec_add *sa, *sa_temp;
1337 
1338 	STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1339 		STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1340 		free(sa->name);
1341 		free(sa->content);
1342 		free(sa);
1343 	}
1344 }
1345 
1346 static void
1347 add_gnu_debuglink(struct elfcopy *ecp)
1348 {
1349 	struct sec_add	*sa;
1350 	struct stat	 sb;
1351 	FILE		*fp;
1352 	char		*fnbase, *buf;
1353 	int		 crc_off;
1354 	int		 crc;
1355 
1356 	if (ecp->debuglink == NULL)
1357 		return;
1358 
1359 	/* Read debug file content. */
1360 	if ((sa = malloc(sizeof(*sa))) == NULL)
1361 		err(EXIT_FAILURE, "malloc failed");
1362 	if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1363 		err(EXIT_FAILURE, "strdup failed");
1364 	if (stat(ecp->debuglink, &sb) == -1)
1365 		err(EXIT_FAILURE, "stat failed");
1366 	if ((buf = malloc(sb.st_size)) == NULL)
1367 		err(EXIT_FAILURE, "malloc failed");
1368 	if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1369 		err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1370 	if (fread(buf, 1, sb.st_size, fp) == 0 ||
1371 	    ferror(fp))
1372 		err(EXIT_FAILURE, "fread failed");
1373 	fclose(fp);
1374 
1375 	/* Calculate crc checksum.  */
1376 	crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1377 	free(buf);
1378 
1379 	/* Calculate section size and the offset to store crc checksum. */
1380 	if ((fnbase = basename(ecp->debuglink)) == NULL)
1381 		err(EXIT_FAILURE, "basename failed");
1382 	crc_off = roundup(strlen(fnbase) + 1, 4);
1383 	sa->size = crc_off + 4;
1384 
1385 	/* Section content. */
1386 	if ((sa->content = calloc(1, sa->size)) == NULL)
1387 		err(EXIT_FAILURE, "malloc failed");
1388 	strncpy(sa->content, fnbase, strlen(fnbase));
1389 	if (ecp->oed == ELFDATA2LSB) {
1390 		sa->content[crc_off] = crc & 0xFF;
1391 		sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1392 		sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1393 		sa->content[crc_off + 3] = crc >> 24;
1394 	} else {
1395 		sa->content[crc_off] = crc >> 24;
1396 		sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1397 		sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1398 		sa->content[crc_off + 3] = crc & 0xFF;
1399 	}
1400 
1401 	STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1402 	ecp->flags |= SEC_ADD;
1403 }
1404 
1405 static void
1406 insert_to_strtab(struct section *t, const char *s)
1407 {
1408 	const char	*r;
1409 	char		*b, *c;
1410 	size_t		 len, slen;
1411 	int		 append;
1412 
1413 	if (t->sz == 0) {
1414 		t->cap = 512;
1415 		if ((t->buf = malloc(t->cap)) == NULL)
1416 			err(EXIT_FAILURE, "malloc failed");
1417 	}
1418 
1419 	slen = strlen(s);
1420 	append = 0;
1421 	b = t->buf;
1422 	for (c = b; c < b + t->sz;) {
1423 		len = strlen(c);
1424 		if (!append && len >= slen) {
1425 			r = c + (len - slen);
1426 			if (strcmp(r, s) == 0)
1427 				return;
1428 		} else if (len < slen && len != 0) {
1429 			r = s + (slen - len);
1430 			if (strcmp(c, r) == 0) {
1431 				t->sz -= len + 1;
1432 				memmove(c, c + len + 1, t->sz - (c - b));
1433 				append = 1;
1434 				continue;
1435 			}
1436 		}
1437 		c += len + 1;
1438 	}
1439 
1440 	while (t->sz + slen + 1 >= t->cap) {
1441 		t->cap *= 2;
1442 		if ((t->buf = realloc(t->buf, t->cap)) == NULL)
1443 			err(EXIT_FAILURE, "realloc failed");
1444 	}
1445 	b = t->buf;
1446 	strncpy(&b[t->sz], s, slen);
1447 	b[t->sz + slen] = '\0';
1448 	t->sz += slen + 1;
1449 }
1450 
1451 static int
1452 lookup_string(struct section *t, const char *s)
1453 {
1454 	const char	*b, *c, *r;
1455 	size_t		 len, slen;
1456 
1457 	slen = strlen(s);
1458 	b = t->buf;
1459 	for (c = b; c < b + t->sz;) {
1460 		len = strlen(c);
1461 		if (len >= slen) {
1462 			r = c + (len - slen);
1463 			if (strcmp(r, s) == 0)
1464 				return (r - b);
1465 		}
1466 		c += len + 1;
1467 	}
1468 
1469 	return (-1);
1470 }
1471 
1472 static uint32_t crctable[256] =
1473 {
1474 	0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1475 	0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1476 	0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1477 	0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1478 	0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1479 	0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1480 	0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1481 	0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1482 	0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1483 	0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1484 	0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1485 	0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1486 	0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1487 	0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1488 	0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1489 	0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1490 	0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1491 	0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1492 	0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1493 	0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1494 	0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1495 	0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1496 	0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1497 	0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1498 	0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1499 	0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1500 	0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1501 	0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1502 	0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1503 	0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1504 	0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1505 	0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1506 	0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1507 	0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1508 	0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1509 	0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1510 	0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1511 	0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1512 	0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1513 	0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1514 	0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1515 	0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1516 	0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1517 	0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1518 	0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1519 	0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1520 	0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1521 	0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1522 	0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1523 	0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1524 	0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1525 	0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1526 	0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1527 	0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1528 	0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1529 	0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1530 	0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1531 	0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1532 	0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1533 	0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1534 	0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1535 	0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1536 	0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1537 	0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1538 };
1539 
1540 static uint32_t
1541 calc_crc32(const char *p, size_t len, uint32_t crc)
1542 {
1543 	uint32_t i;
1544 
1545 	for (i = 0; i < len; i++) {
1546 		crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1547 	}
1548 
1549 	return (crc ^ 0xFFFFFFFF);
1550 }
1551