xref: /freebsd/contrib/elftoolchain/elfcopy/elfcopy.h (revision 5ac70383c8b32eeec80426e837960977971c7c2b)
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  *
26d003e0d7SEd Maste  * $Id: elfcopy.h 3757 2019-06-28 01:15:28Z emaste $
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 */
1184a85c691SEd 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 */
13048d41ef0SPhil Shafer 	uint64_t	 flags;	/* section flags */
131a85fe12eSEd Maste 	uint64_t	 vma;	/* section virtual addr */
132a85fe12eSEd Maste 	uint64_t	 lma;	/* section load addr */
133a85fe12eSEd Maste 	uint64_t	 pad_sz;/* section padding size */
134a85fe12eSEd Maste 	int		 loadable; /* whether loadable */
135a85fe12eSEd Maste 	int		 pseudo;
136a85fe12eSEd Maste 	int		 nocopy;
137a85fe12eSEd Maste 
138bc589b72SMark Johnston 	Elftc_String_Table *strtab;
139bc589b72SMark Johnston 
140a85fe12eSEd Maste 	TAILQ_ENTRY(section) sec_list;	/* next section */
141a85fe12eSEd Maste };
142a85fe12eSEd Maste 
14302816870SMark Johnston TAILQ_HEAD(sectionlist, section);
14402816870SMark Johnston 
145a85fe12eSEd Maste /* Internal data structure for segments. */
146a85fe12eSEd Maste struct segment {
147676e25abSEd Maste 	uint64_t	vaddr;	/* virtual addr (VMA) */
148676e25abSEd Maste 	uint64_t	paddr;	/* physical addr (LMA) */
149a85fe12eSEd Maste 	uint64_t	off;	/* file offset */
150a85fe12eSEd Maste 	uint64_t	fsz;	/* file size */
151a85fe12eSEd Maste 	uint64_t	msz;	/* memory size */
152a85fe12eSEd Maste 	uint64_t	type;	/* segment type */
153a85fe12eSEd Maste 	int		remove;	/* whether remove */
154a85fe12eSEd Maste 	int		nsec;	/* number of sections contained */
155a85fe12eSEd Maste 	struct section **v_sec;	/* list of sections contained */
156a85fe12eSEd Maste 
157a85fe12eSEd Maste 	STAILQ_ENTRY(segment) seg_list; /* next segment */
158a85fe12eSEd Maste };
159a85fe12eSEd Maste 
160a85fe12eSEd Maste /*
161a85fe12eSEd Maste  * In-memory representation of ar(1) archive member(object).
162a85fe12eSEd Maste  */
163a85fe12eSEd Maste struct ar_obj {
164a85fe12eSEd Maste 	char	*name;		/* member name */
165a85fe12eSEd Maste 	char	*buf;		/* member content */
166a85fe12eSEd Maste 	void	*maddr;		/* mmap start address */
167a85fe12eSEd Maste 	uid_t	 uid;		/* user id */
168a85fe12eSEd Maste 	gid_t	 gid;		/* group id */
169a85fe12eSEd Maste 	mode_t	 md;		/* octal file permissions */
170a85fe12eSEd Maste 	size_t	 size;		/* member size */
171a85fe12eSEd Maste 	time_t	 mtime;		/* modification time */
172a85fe12eSEd Maste 
173a85fe12eSEd Maste 	STAILQ_ENTRY(ar_obj) objs;
174a85fe12eSEd Maste };
175a85fe12eSEd Maste 
176a85fe12eSEd Maste /*
177a85fe12eSEd Maste  * Structure encapsulates the "global" data for "elfcopy" program.
178a85fe12eSEd Maste  */
179a85fe12eSEd Maste struct elfcopy {
180a85fe12eSEd Maste 	const char	*progname; /* program name */
181a85fe12eSEd Maste 	int		 iec;	/* elfclass of input object */
182a85fe12eSEd Maste 	Elftc_Bfd_Target_Flavor itf; /* flavour of input object */
183a85fe12eSEd Maste 	Elftc_Bfd_Target_Flavor otf; /* flavour of output object */
184a85fe12eSEd Maste 	const char	*otgt;	/* output target name */
185a85fe12eSEd Maste 	int		 oec;	/* elfclass of output object */
186b6b6f9ccSEd Maste 	unsigned char	 oed;	/* endianness of output object */
187a85fe12eSEd Maste 	int		 oem;	/* EM_XXX of output object */
188a85fe12eSEd Maste 	int		 abi;	/* OSABI of output object */
189a85fe12eSEd Maste 	Elf		*ein;	/* ELF descriptor of input object */
190a85fe12eSEd Maste 	Elf		*eout;	/* ELF descriptor of output object */
191a85fe12eSEd Maste 	int		 iphnum; /* num. of input object phdr entries */
192a85fe12eSEd Maste 	int		 ophnum; /* num. of output object phdr entries */
193a85fe12eSEd Maste 	int		 nos;	/* num. of output object sections */
194a85fe12eSEd Maste 
195a85fe12eSEd Maste 	enum {
196a85fe12eSEd Maste 		STRIP_NONE = 0,
197a85fe12eSEd Maste 		STRIP_ALL,
198a85fe12eSEd Maste 		STRIP_DEBUG,
19967d97fe7SEd Maste 		STRIP_DWO,
200a85fe12eSEd Maste 		STRIP_NONDEBUG,
20167d97fe7SEd Maste 		STRIP_NONDWO,
202a85fe12eSEd Maste 		STRIP_UNNEEDED
203a85fe12eSEd Maste 	} strip;
204a85fe12eSEd Maste 
205a85fe12eSEd Maste #define	EXECUTABLE	0x00000001U
206a85fe12eSEd Maste #define	DYNAMIC		0x00000002U
207a85fe12eSEd Maste #define	RELOCATABLE	0x00000004U
208a85fe12eSEd Maste #define	SYMTAB_EXIST	0x00000010U
209a85fe12eSEd Maste #define	SYMTAB_INTACT	0x00000020U
210a85fe12eSEd Maste #define	KEEP_GLOBAL	0x00000040U
211a85fe12eSEd Maste #define	DISCARD_LOCAL	0x00000080U
212a85fe12eSEd Maste #define	WEAKEN_ALL	0x00000100U
213a85fe12eSEd Maste #define	PRESERVE_DATE	0x00001000U
214a85fe12eSEd Maste #define	SREC_FORCE_S3	0x00002000U
215a85fe12eSEd Maste #define	SREC_FORCE_LEN	0x00004000U
216a85fe12eSEd Maste #define	SET_START	0x00008000U
217a85fe12eSEd Maste #define	GAP_FILL	0x00010000U
218a85fe12eSEd Maste #define	WILDCARD	0x00020000U
219a85fe12eSEd Maste #define	NO_CHANGE_WARN	0x00040000U
220a85fe12eSEd Maste #define	SEC_ADD		0x00080000U
221a85fe12eSEd Maste #define	SEC_APPEND	0x00100000U
222a85fe12eSEd Maste #define	SEC_COMPRESS	0x00200000U
223a85fe12eSEd Maste #define	SEC_PRINT	0x00400000U
224a85fe12eSEd Maste #define	SEC_REMOVE	0x00800000U
225a85fe12eSEd Maste #define	SEC_COPY	0x01000000U
226a85fe12eSEd Maste #define	DISCARD_LLABEL	0x02000000U
22767d97fe7SEd Maste #define	LOCALIZE_HIDDEN	0x04000000U
228a85fe12eSEd Maste 
229a85fe12eSEd Maste 	int		 flags;		/* elfcopy run control flags. */
230a85fe12eSEd Maste 	int64_t		 change_addr;	/* Section address adjustment. */
231a85fe12eSEd Maste 	int64_t		 change_start;	/* Entry point adjustment. */
232a85fe12eSEd Maste 	uint64_t	 set_start;	/* Entry point value. */
233a85fe12eSEd Maste 	unsigned long	 srec_len;	/* S-Record length. */
234a85fe12eSEd Maste 	uint64_t	 pad_to;	/* load address padding. */
235a85fe12eSEd Maste 	uint8_t		 fill;		/* gap fill value. */
236a85fe12eSEd Maste 	char		*prefix_sec;	/* section prefix. */
237a85fe12eSEd Maste 	char		*prefix_alloc;	/* alloc section prefix. */
238a85fe12eSEd Maste 	char		*prefix_sym;	/* symbol prefix. */
239a85fe12eSEd Maste 	char		*debuglink;	/* GNU debuglink file. */
240a85fe12eSEd Maste 	struct section	*symtab;	/* .symtab section. */
241a85fe12eSEd Maste 	struct section	*strtab;	/* .strtab section. */
242a85fe12eSEd Maste 	struct section	*shstrtab;	/* .shstrtab section. */
243a85fe12eSEd Maste 	uint64_t	*secndx;	/* section index map. */
244a85fe12eSEd Maste 	uint64_t	*symndx;	/* symbol index map. */
245a85fe12eSEd Maste 	unsigned char	*v_rel;		/* symbols needed by relocation. */
246b6b6f9ccSEd Maste 	unsigned char	*v_grp;		/* symbols referred by section group. */
247a85fe12eSEd Maste 	unsigned char	*v_secsym;	/* sections with section symbol. */
248a85fe12eSEd Maste 	STAILQ_HEAD(, segment) v_seg;	/* list of segments. */
249a85fe12eSEd Maste 	STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */
250a85fe12eSEd Maste 	STAILQ_HEAD(, sec_add) v_sadd;	/* list of sections to add. */
251a85fe12eSEd Maste 	STAILQ_HEAD(, symop) v_symop;	/* list of symbols operations. */
252a85fe12eSEd Maste 	STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */
253a85fe12eSEd Maste 	TAILQ_HEAD(, section) v_sec;	/* list of sections. */
254a85fe12eSEd Maste 
255a85fe12eSEd Maste 	/*
256a85fe12eSEd Maste 	 * Fields for the ar(1) archive.
257a85fe12eSEd Maste 	 */
258a85fe12eSEd Maste 	char		*as;		/* buffer for archive string table. */
259a85fe12eSEd Maste 	size_t		 as_sz;		/* current size of as table. */
260a85fe12eSEd Maste 	size_t		 as_cap;	/* capacity of as table buffer. */
261a85fe12eSEd Maste 	uint32_t	 s_cnt;		/* current number of symbols. */
262a85fe12eSEd Maste 	uint32_t	*s_so;		/* symbol offset table. */
263a85fe12eSEd Maste 	size_t		 s_so_cap;	/* capacity of so table buffer. */
264a85fe12eSEd Maste 	char		*s_sn;		/* symbol name table */
265a85fe12eSEd Maste 	size_t		 s_sn_cap;	/* capacity of sn table buffer. */
266a85fe12eSEd Maste 	size_t		 s_sn_sz;	/* current size of sn table. */
267a85fe12eSEd Maste 	off_t		 rela_off;	/* offset relative to pseudo members. */
268a85fe12eSEd Maste 	STAILQ_HEAD(, ar_obj) v_arobj;	/* archive object(member) list. */
269a85fe12eSEd Maste };
270a85fe12eSEd Maste 
271a85fe12eSEd Maste void	add_section(struct elfcopy *_ecp, const char *_optarg);
272a85fe12eSEd Maste void	add_to_shstrtab(struct elfcopy *_ecp, const char *_name);
273a85fe12eSEd Maste void	add_to_symop_list(struct elfcopy *_ecp, const char *_name,
274a85fe12eSEd Maste     const char *_newname, unsigned int _op);
275a85fe12eSEd Maste void	add_to_symtab(struct elfcopy *_ecp, const char *_name,
276a85fe12eSEd Maste     uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx,
277a85fe12eSEd Maste     unsigned char _st_info, unsigned char _st_other, int _ndx_known);
278a85fe12eSEd Maste int	add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec);
279a85fe12eSEd Maste void	adjust_addr(struct elfcopy *_ecp);
280*5ac70383SChris Rees int	cleanup_tempfile(char *_fn);
281a85fe12eSEd Maste void	copy_content(struct elfcopy *_ecp);
282a85fe12eSEd Maste void	copy_data(struct section *_s);
283a85fe12eSEd Maste void	copy_phdr(struct elfcopy *_ecp);
284a85fe12eSEd Maste void	copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name,
285a85fe12eSEd Maste     int _copy, int _sec_flags);
286a85fe12eSEd Maste void	create_binary(int _ifd, int _ofd);
287a85fe12eSEd Maste void	create_elf(struct elfcopy *_ecp);
288a85fe12eSEd Maste void	create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn);
289a85fe12eSEd Maste void	create_elf_from_ihex(struct elfcopy *_ecp, int _ifd);
290a85fe12eSEd Maste void	create_elf_from_srec(struct elfcopy *_ecp, int _ifd);
291a85fe12eSEd Maste struct section *create_external_section(struct elfcopy *_ecp, const char *_name,
292a85fe12eSEd Maste     char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype,
293a85fe12eSEd Maste     Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma,
294a85fe12eSEd Maste     int _loadable);
295a85fe12eSEd Maste void	create_external_symtab(struct elfcopy *_ecp);
296a85fe12eSEd Maste void	create_ihex(int _ifd, int _ofd);
297839529caSEd Maste void	create_pe(struct elfcopy *_ecp, int _ifd, int _ofd);
298a85fe12eSEd Maste void	create_scn(struct elfcopy *_ecp);
299a85fe12eSEd Maste void	create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);
300a85fe12eSEd Maste void	create_symtab(struct elfcopy *_ecp);
301a85fe12eSEd Maste void	create_symtab_data(struct elfcopy *_ecp);
3021e4896b1SDimitry Andric void	create_tempfile(const char *_src, char **_fn, int *_fd);
303a85fe12eSEd Maste void	finalize_external_symtab(struct elfcopy *_ecp);
304a85fe12eSEd Maste void	free_elf(struct elfcopy *_ecp);
305a85fe12eSEd Maste void	free_sec_act(struct elfcopy *_ecp);
306a85fe12eSEd Maste void	free_sec_add(struct elfcopy *_ecp);
307a85fe12eSEd Maste void	free_symtab(struct elfcopy *_ecp);
308a85fe12eSEd Maste void	init_shstrtab(struct elfcopy *_ecp);
309a85fe12eSEd Maste void	insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec,
310a85fe12eSEd Maste     int _tail);
311a85fe12eSEd Maste struct section *insert_shtab(struct elfcopy *_ecp, int tail);
312a85fe12eSEd Maste int	is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info);
313a85fe12eSEd Maste int	is_remove_section(struct elfcopy *_ecp, const char *_name);
314a85fe12eSEd Maste struct sec_action *lookup_sec_act(struct elfcopy *_ecp,
315a85fe12eSEd Maste     const char *_name, int _add);
316a85fe12eSEd Maste struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
317a85fe12eSEd Maste     unsigned int _op);
318a85fe12eSEd Maste void	resync_sections(struct elfcopy *_ecp);
319a85fe12eSEd Maste void	setup_phdr(struct elfcopy *_ecp);
320a85fe12eSEd Maste void	update_shdr(struct elfcopy *_ecp, int _update_link);
321a85fe12eSEd Maste 
322a85fe12eSEd Maste #ifndef LIBELF_AR
323a85fe12eSEd Maste int	ac_detect_ar(int _ifd);
324a85fe12eSEd Maste void	ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd);
325a85fe12eSEd Maste #endif	/* ! LIBELF_AR */
326