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