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