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