xref: /freebsd/contrib/elftoolchain/elfcopy/elfcopy.h (revision 4a85c69160aa915853befc1efbcd83618d2eac03)
1a85fe12eSEd Maste /*-
2a85fe12eSEd Maste  * Copyright (c) 2007-2013 Kai Wang
3a85fe12eSEd Maste  * All rights reserved.
4a85fe12eSEd Maste  *
5a85fe12eSEd Maste  * Redistribution and use in source and binary forms, with or without
6a85fe12eSEd Maste  * modification, are permitted provided that the following conditions
7a85fe12eSEd Maste  * are met:
8a85fe12eSEd Maste  * 1. Redistributions of source code must retain the above copyright
9a85fe12eSEd Maste  *    notice, this list of conditions and the following disclaimer.
10a85fe12eSEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
11a85fe12eSEd Maste  *    notice, this list of conditions and the following disclaimer in the
12a85fe12eSEd Maste  *    documentation and/or other materials provided with the distribution.
13a85fe12eSEd Maste  *
14a85fe12eSEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15a85fe12eSEd Maste  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16a85fe12eSEd Maste  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17a85fe12eSEd Maste  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18a85fe12eSEd Maste  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19a85fe12eSEd Maste  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20a85fe12eSEd Maste  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21a85fe12eSEd Maste  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22a85fe12eSEd Maste  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23a85fe12eSEd Maste  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24a85fe12eSEd Maste  * SUCH DAMAGE.
25a85fe12eSEd Maste  *
26*4a85c691SEd Maste  * $Id: elfcopy.h 3134 2014-12-23 10:43:59Z kaiwang27 $
27a85fe12eSEd Maste  */
28a85fe12eSEd Maste 
29a85fe12eSEd Maste #include <sys/queue.h>
30a85fe12eSEd Maste #include <gelf.h>
31a85fe12eSEd Maste #include <libelftc.h>
32a85fe12eSEd Maste 
33a85fe12eSEd Maste #include "_elftc.h"
34a85fe12eSEd Maste 
35a85fe12eSEd Maste /*
36a85fe12eSEd Maste  * User specified symbol operation (strip, keep, localize, globalize,
37a85fe12eSEd Maste  * weaken, rename, etc).
38a85fe12eSEd Maste  */
39a85fe12eSEd Maste struct symop {
40a85fe12eSEd Maste 	const char	*name;
41a85fe12eSEd Maste 	const char	*newname;
42a85fe12eSEd Maste 
43a85fe12eSEd Maste #define SYMOP_KEEP	0x0001U
44a85fe12eSEd Maste #define SYMOP_STRIP	0x0002U
45a85fe12eSEd Maste #define SYMOP_GLOBALIZE	0x0004U
46a85fe12eSEd Maste #define SYMOP_LOCALIZE	0x0008U
47a85fe12eSEd Maste #define SYMOP_KEEPG	0x0010U
48a85fe12eSEd Maste #define SYMOP_WEAKEN	0x0020U
49a85fe12eSEd Maste #define SYMOP_REDEF	0x0040U
50a85fe12eSEd Maste 
51a85fe12eSEd Maste 	unsigned int	op;
52a85fe12eSEd Maste 
53a85fe12eSEd Maste 	STAILQ_ENTRY(symop) symop_list;
54a85fe12eSEd Maste };
55a85fe12eSEd Maste 
56a85fe12eSEd Maste /* File containing symbol list. */
57a85fe12eSEd Maste struct symfile {
58a85fe12eSEd Maste 	dev_t		 dev;
59a85fe12eSEd Maste 	ino_t		 ino;
60a85fe12eSEd Maste 	size_t		 size;
61a85fe12eSEd Maste 	char		*data;
62a85fe12eSEd Maste 	unsigned int	 op;
63a85fe12eSEd Maste 
64a85fe12eSEd Maste 	STAILQ_ENTRY(symfile) symfile_list;
65a85fe12eSEd Maste };
66a85fe12eSEd Maste 
67a85fe12eSEd Maste /* Sections to copy/remove/rename/... */
68a85fe12eSEd Maste struct sec_action {
69a85fe12eSEd Maste 	const char	*name;
70a85fe12eSEd Maste 	const char	*addopt;
71a85fe12eSEd Maste 	const char	*newname;
72a85fe12eSEd Maste 	const char	*string;
73a85fe12eSEd Maste 	uint64_t	 lma;
74a85fe12eSEd Maste 	uint64_t	 vma;
75a85fe12eSEd Maste 	int64_t		 lma_adjust;
76a85fe12eSEd Maste 	int64_t		 vma_adjust;
77a85fe12eSEd Maste 
78a85fe12eSEd Maste #define	SF_ALLOC	0x0001U
79a85fe12eSEd Maste #define	SF_LOAD		0x0002U
80a85fe12eSEd Maste #define	SF_NOLOAD	0x0004U
81a85fe12eSEd Maste #define	SF_READONLY	0x0008U
82a85fe12eSEd Maste #define	SF_DEBUG	0x0010U
83a85fe12eSEd Maste #define	SF_CODE		0x0020U
84a85fe12eSEd Maste #define	SF_DATA		0x0040U
85a85fe12eSEd Maste #define	SF_ROM		0x0080U
86a85fe12eSEd Maste #define	SF_SHARED	0X0100U
87a85fe12eSEd Maste #define	SF_CONTENTS	0x0200U
88a85fe12eSEd Maste 
89a85fe12eSEd Maste 	int	flags;
90a85fe12eSEd Maste 	int	add;
91a85fe12eSEd Maste 	int	append;
92a85fe12eSEd Maste 	int	compress;
93a85fe12eSEd Maste 	int	copy;
94a85fe12eSEd Maste 	int	print;
95a85fe12eSEd Maste 	int	remove;
96a85fe12eSEd Maste 	int	rename;
97a85fe12eSEd Maste 	int	setflags;
98a85fe12eSEd Maste 	int	setlma;
99a85fe12eSEd Maste 	int	setvma;
100a85fe12eSEd Maste 
101a85fe12eSEd Maste 	STAILQ_ENTRY(sec_action) sac_list;
102a85fe12eSEd Maste };
103a85fe12eSEd Maste 
104a85fe12eSEd Maste /* Sections to add from file. */
105a85fe12eSEd Maste struct sec_add {
106a85fe12eSEd Maste 	char	*name;
107a85fe12eSEd Maste 	char	*content;
108a85fe12eSEd Maste 	size_t	 size;
109a85fe12eSEd Maste 
110a85fe12eSEd Maste 	STAILQ_ENTRY(sec_add) sadd_list;
111a85fe12eSEd Maste };
112a85fe12eSEd Maste 
113a85fe12eSEd Maste struct segment;
114a85fe12eSEd Maste 
115a85fe12eSEd Maste /* Internal data structure for sections. */
116a85fe12eSEd Maste struct section {
117a85fe12eSEd Maste 	struct segment	*seg;	/* containing segment */
118*4a85c691SEd Maste 	struct segment	*seg_tls; /* tls segment */
119a85fe12eSEd Maste 	const char	*name;	/* section name */
120a85fe12eSEd Maste 	char		*newname; /* new section name */
121a85fe12eSEd Maste 	Elf_Scn		*is;	/* input scn */
122a85fe12eSEd Maste 	Elf_Scn		*os;	/* output scn */
123a85fe12eSEd Maste 	void		*buf;	/* section content */
124a85fe12eSEd Maste 	uint8_t		*pad;	/* section padding */
125a85fe12eSEd Maste 	uint64_t	 off;	/* section offset */
126a85fe12eSEd Maste 	uint64_t	 sz;	/* section size */
127a85fe12eSEd Maste 	uint64_t	 cap;	/* section capacity */
128a85fe12eSEd Maste 	uint64_t	 align;	/* section alignment */
129a85fe12eSEd Maste 	uint64_t	 type;	/* section type */
130a85fe12eSEd Maste 	uint64_t	 vma;	/* section virtual addr */
131a85fe12eSEd Maste 	uint64_t	 lma;	/* section load addr */
132a85fe12eSEd Maste 	uint64_t	 pad_sz;/* section padding size */
133a85fe12eSEd Maste 	int		 loadable; /* whether loadable */
134a85fe12eSEd Maste 	int		 pseudo;
135a85fe12eSEd Maste 	int		 nocopy;
136a85fe12eSEd Maste 
137a85fe12eSEd Maste 	TAILQ_ENTRY(section) sec_list;	/* next section */
138a85fe12eSEd Maste };
139a85fe12eSEd Maste 
140a85fe12eSEd Maste /* Internal data structure for segments. */
141a85fe12eSEd Maste struct segment {
142a85fe12eSEd Maste 	uint64_t	addr;	/* load addr */
143a85fe12eSEd Maste 	uint64_t	off;	/* file offset */
144a85fe12eSEd Maste 	uint64_t	fsz;	/* file size */
145a85fe12eSEd Maste 	uint64_t	msz;	/* memory size */
146a85fe12eSEd Maste 	uint64_t	type;	/* segment type */
147a85fe12eSEd Maste 	int		remove;	/* whether remove */
148a85fe12eSEd Maste 	int		nsec;	/* number of sections contained */
149a85fe12eSEd Maste 	struct section **v_sec;	/* list of sections contained */
150a85fe12eSEd Maste 
151a85fe12eSEd Maste 	STAILQ_ENTRY(segment) seg_list; /* next segment */
152a85fe12eSEd Maste };
153a85fe12eSEd Maste 
154a85fe12eSEd Maste /*
155a85fe12eSEd Maste  * In-memory representation of ar(1) archive member(object).
156a85fe12eSEd Maste  */
157a85fe12eSEd Maste struct ar_obj {
158a85fe12eSEd Maste 	char	*name;		/* member name */
159a85fe12eSEd Maste 	char	*buf;		/* member content */
160a85fe12eSEd Maste 	void	*maddr;		/* mmap start address */
161a85fe12eSEd Maste 	uid_t	 uid;		/* user id */
162a85fe12eSEd Maste 	gid_t	 gid;		/* group id */
163a85fe12eSEd Maste 	mode_t	 md;		/* octal file permissions */
164a85fe12eSEd Maste 	size_t	 size;		/* member size */
165a85fe12eSEd Maste 	time_t	 mtime;		/* modification time */
166a85fe12eSEd Maste 
167a85fe12eSEd Maste 	STAILQ_ENTRY(ar_obj) objs;
168a85fe12eSEd Maste };
169a85fe12eSEd Maste 
170a85fe12eSEd Maste /*
171a85fe12eSEd Maste  * Structure encapsulates the "global" data for "elfcopy" program.
172a85fe12eSEd Maste  */
173a85fe12eSEd Maste struct elfcopy {
174a85fe12eSEd Maste 	const char	*progname; /* program name */
175a85fe12eSEd Maste 	int		 iec;	/* elfclass of input object */
176a85fe12eSEd Maste 	Elftc_Bfd_Target_Flavor itf; /* flavour of input object */
177a85fe12eSEd Maste 	Elftc_Bfd_Target_Flavor otf; /* flavour of output object */
178a85fe12eSEd Maste 	const char	*otgt;	/* output target name */
179a85fe12eSEd Maste 	int		 oec;	/* elfclass of output object */
180a85fe12eSEd Maste 	unsigned char	 oed;	/* endianess of output object */
181a85fe12eSEd Maste 	int		 oem;	/* EM_XXX of output object */
182a85fe12eSEd Maste 	int		 abi;	/* OSABI of output object */
183a85fe12eSEd Maste 	Elf		*ein;	/* ELF descriptor of input object */
184a85fe12eSEd Maste 	Elf		*eout;	/* ELF descriptor of output object */
185a85fe12eSEd Maste 	int		 iphnum; /* num. of input object phdr entries */
186a85fe12eSEd Maste 	int		 ophnum; /* num. of output object phdr entries */
187a85fe12eSEd Maste 	int		 nos;	/* num. of output object sections */
188a85fe12eSEd Maste 
189a85fe12eSEd Maste 	enum {
190a85fe12eSEd Maste 		STRIP_NONE = 0,
191a85fe12eSEd Maste 		STRIP_ALL,
192a85fe12eSEd Maste 		STRIP_DEBUG,
193a85fe12eSEd Maste 		STRIP_NONDEBUG,
194a85fe12eSEd Maste 		STRIP_UNNEEDED
195a85fe12eSEd Maste 	} strip;
196a85fe12eSEd Maste 
197a85fe12eSEd Maste #define	EXECUTABLE	0x00000001U
198a85fe12eSEd Maste #define	DYNAMIC		0x00000002U
199a85fe12eSEd Maste #define	RELOCATABLE	0x00000004U
200a85fe12eSEd Maste #define	SYMTAB_EXIST	0x00000010U
201a85fe12eSEd Maste #define	SYMTAB_INTACT	0x00000020U
202a85fe12eSEd Maste #define	KEEP_GLOBAL	0x00000040U
203a85fe12eSEd Maste #define	DISCARD_LOCAL	0x00000080U
204a85fe12eSEd Maste #define	WEAKEN_ALL	0x00000100U
205a85fe12eSEd Maste #define	PRESERVE_DATE	0x00001000U
206a85fe12eSEd Maste #define	SREC_FORCE_S3	0x00002000U
207a85fe12eSEd Maste #define	SREC_FORCE_LEN	0x00004000U
208a85fe12eSEd Maste #define	SET_START	0x00008000U
209a85fe12eSEd Maste #define	GAP_FILL	0x00010000U
210a85fe12eSEd Maste #define	WILDCARD	0x00020000U
211a85fe12eSEd Maste #define	NO_CHANGE_WARN	0x00040000U
212a85fe12eSEd Maste #define	SEC_ADD		0x00080000U
213a85fe12eSEd Maste #define	SEC_APPEND	0x00100000U
214a85fe12eSEd Maste #define	SEC_COMPRESS	0x00200000U
215a85fe12eSEd Maste #define	SEC_PRINT	0x00400000U
216a85fe12eSEd Maste #define	SEC_REMOVE	0x00800000U
217a85fe12eSEd Maste #define	SEC_COPY	0x01000000U
218a85fe12eSEd Maste #define	DISCARD_LLABEL	0x02000000U
219a85fe12eSEd Maste 
220a85fe12eSEd Maste 	int		 flags;		/* elfcopy run control flags. */
221a85fe12eSEd Maste 	int64_t		 change_addr;	/* Section address adjustment. */
222a85fe12eSEd Maste 	int64_t		 change_start;	/* Entry point adjustment. */
223a85fe12eSEd Maste 	uint64_t	 set_start;	/* Entry point value. */
224a85fe12eSEd Maste 	unsigned long	 srec_len;	/* S-Record length. */
225a85fe12eSEd Maste 	uint64_t	 pad_to;	/* load address padding. */
226a85fe12eSEd Maste 	uint8_t		 fill;		/* gap fill value. */
227a85fe12eSEd Maste 	char		*prefix_sec;	/* section prefix. */
228a85fe12eSEd Maste 	char		*prefix_alloc;	/* alloc section prefix. */
229a85fe12eSEd Maste 	char		*prefix_sym;	/* symbol prefix. */
230a85fe12eSEd Maste 	char		*debuglink;	/* GNU debuglink file. */
231a85fe12eSEd Maste 	struct section	*symtab;	/* .symtab section. */
232a85fe12eSEd Maste 	struct section	*strtab;	/* .strtab section. */
233a85fe12eSEd Maste 	struct section	*shstrtab;	/* .shstrtab section. */
234a85fe12eSEd Maste 	uint64_t	*secndx;	/* section index map. */
235a85fe12eSEd Maste 	uint64_t	*symndx;	/* symbol index map. */
236a85fe12eSEd Maste 	unsigned char	*v_rel;		/* symbols needed by relocation. */
237a85fe12eSEd Maste 	unsigned char	*v_secsym;	/* sections with section symbol. */
238a85fe12eSEd Maste 	STAILQ_HEAD(, segment) v_seg;	/* list of segments. */
239a85fe12eSEd Maste 	STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */
240a85fe12eSEd Maste 	STAILQ_HEAD(, sec_add) v_sadd;	/* list of sections to add. */
241a85fe12eSEd Maste 	STAILQ_HEAD(, symop) v_symop;	/* list of symbols operations. */
242a85fe12eSEd Maste 	STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */
243a85fe12eSEd Maste 	TAILQ_HEAD(, section) v_sec;	/* list of sections. */
244a85fe12eSEd Maste 
245a85fe12eSEd Maste 	/*
246a85fe12eSEd Maste 	 * Fields for the ar(1) archive.
247a85fe12eSEd Maste 	 */
248a85fe12eSEd Maste 	char		*as;		/* buffer for archive string table. */
249a85fe12eSEd Maste 	size_t		 as_sz;		/* current size of as table. */
250a85fe12eSEd Maste 	size_t		 as_cap;	/* capacity of as table buffer. */
251a85fe12eSEd Maste 	uint32_t	 s_cnt;		/* current number of symbols. */
252a85fe12eSEd Maste 	uint32_t	*s_so;		/* symbol offset table. */
253a85fe12eSEd Maste 	size_t		 s_so_cap;	/* capacity of so table buffer. */
254a85fe12eSEd Maste 	char		*s_sn;		/* symbol name table */
255a85fe12eSEd Maste 	size_t		 s_sn_cap;	/* capacity of sn table buffer. */
256a85fe12eSEd Maste 	size_t		 s_sn_sz;	/* current size of sn table. */
257a85fe12eSEd Maste 	off_t		 rela_off;	/* offset relative to pseudo members. */
258a85fe12eSEd Maste 	STAILQ_HEAD(, ar_obj) v_arobj;	/* archive object(member) list. */
259a85fe12eSEd Maste };
260a85fe12eSEd Maste 
261a85fe12eSEd Maste void	add_section(struct elfcopy *_ecp, const char *_optarg);
262a85fe12eSEd Maste void	add_to_shstrtab(struct elfcopy *_ecp, const char *_name);
263a85fe12eSEd Maste void	add_to_symop_list(struct elfcopy *_ecp, const char *_name,
264a85fe12eSEd Maste     const char *_newname, unsigned int _op);
265a85fe12eSEd Maste void	add_to_symtab(struct elfcopy *_ecp, const char *_name,
266a85fe12eSEd Maste     uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx,
267a85fe12eSEd Maste     unsigned char _st_info, unsigned char _st_other, int _ndx_known);
268a85fe12eSEd Maste int	add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec);
269a85fe12eSEd Maste void	adjust_addr(struct elfcopy *_ecp);
270a85fe12eSEd Maste void	copy_content(struct elfcopy *_ecp);
271a85fe12eSEd Maste void	copy_data(struct section *_s);
272a85fe12eSEd Maste void	copy_phdr(struct elfcopy *_ecp);
273a85fe12eSEd Maste void	copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name,
274a85fe12eSEd Maste     int _copy, int _sec_flags);
275a85fe12eSEd Maste void	create_binary(int _ifd, int _ofd);
276a85fe12eSEd Maste void	create_elf(struct elfcopy *_ecp);
277a85fe12eSEd Maste void	create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn);
278a85fe12eSEd Maste void	create_elf_from_ihex(struct elfcopy *_ecp, int _ifd);
279a85fe12eSEd Maste void	create_elf_from_srec(struct elfcopy *_ecp, int _ifd);
280a85fe12eSEd Maste struct section *create_external_section(struct elfcopy *_ecp, const char *_name,
281a85fe12eSEd Maste     char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype,
282a85fe12eSEd Maste     Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma,
283a85fe12eSEd Maste     int _loadable);
284a85fe12eSEd Maste void	create_external_symtab(struct elfcopy *_ecp);
285a85fe12eSEd Maste void	create_ihex(int _ifd, int _ofd);
286a85fe12eSEd Maste void	create_scn(struct elfcopy *_ecp);
287a85fe12eSEd Maste void	create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);
288a85fe12eSEd Maste void	create_symtab(struct elfcopy *_ecp);
289a85fe12eSEd Maste void	create_symtab_data(struct elfcopy *_ecp);
290a85fe12eSEd Maste void	create_tempfile(char **_fn, int *_fd);
291a85fe12eSEd Maste void	finalize_external_symtab(struct elfcopy *_ecp);
292a85fe12eSEd Maste void	free_elf(struct elfcopy *_ecp);
293a85fe12eSEd Maste void	free_sec_act(struct elfcopy *_ecp);
294a85fe12eSEd Maste void	free_sec_add(struct elfcopy *_ecp);
295a85fe12eSEd Maste void	free_symtab(struct elfcopy *_ecp);
296a85fe12eSEd Maste void	init_shstrtab(struct elfcopy *_ecp);
297a85fe12eSEd Maste void	insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec,
298a85fe12eSEd Maste     int _tail);
299a85fe12eSEd Maste struct section *insert_shtab(struct elfcopy *_ecp, int tail);
300a85fe12eSEd Maste int	is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info);
301a85fe12eSEd Maste int	is_remove_section(struct elfcopy *_ecp, const char *_name);
302a85fe12eSEd Maste struct sec_action *lookup_sec_act(struct elfcopy *_ecp,
303a85fe12eSEd Maste     const char *_name, int _add);
304a85fe12eSEd Maste struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
305a85fe12eSEd Maste     unsigned int _op);
306a85fe12eSEd Maste void	resync_sections(struct elfcopy *_ecp);
307a85fe12eSEd Maste void	set_shstrtab(struct elfcopy *_ecp);
308a85fe12eSEd Maste void	setup_phdr(struct elfcopy *_ecp);
309a85fe12eSEd Maste void	update_shdr(struct elfcopy *_ecp, int _update_link);
310a85fe12eSEd Maste 
311a85fe12eSEd Maste #ifndef LIBELF_AR
312a85fe12eSEd Maste int	ac_detect_ar(int _ifd);
313a85fe12eSEd Maste void	ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd);
314a85fe12eSEd Maste #endif	/* ! LIBELF_AR */
315