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