]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/elfcopy/elfcopy.h
MFV r324714:
[FreeBSD/FreeBSD.git] / contrib / elftoolchain / elfcopy / elfcopy.h
1 /*-
2  * Copyright (c) 2007-2013 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  * $Id: elfcopy.h 3446 2016-05-03 01:31:17Z emaste $
27  */
28
29 #include <sys/queue.h>
30 #include <gelf.h>
31 #include <libelftc.h>
32
33 #include "_elftc.h"
34
35 /*
36  * User specified symbol operation (strip, keep, localize, globalize,
37  * weaken, rename, etc).
38  */
39 struct symop {
40         const char      *name;
41         const char      *newname;
42
43 #define SYMOP_KEEP      0x0001U
44 #define SYMOP_STRIP     0x0002U
45 #define SYMOP_GLOBALIZE 0x0004U
46 #define SYMOP_LOCALIZE  0x0008U
47 #define SYMOP_KEEPG     0x0010U
48 #define SYMOP_WEAKEN    0x0020U
49 #define SYMOP_REDEF     0x0040U
50
51         unsigned int    op;
52
53         STAILQ_ENTRY(symop) symop_list;
54 };
55
56 /* File containing symbol list. */
57 struct symfile {
58         dev_t            dev;
59         ino_t            ino;
60         size_t           size;
61         char            *data;
62         unsigned int     op;
63
64         STAILQ_ENTRY(symfile) symfile_list;
65 };
66
67 /* Sections to copy/remove/rename/... */
68 struct sec_action {
69         const char      *name;
70         const char      *addopt;
71         const char      *newname;
72         const char      *string;
73         uint64_t         lma;
74         uint64_t         vma;
75         int64_t          lma_adjust;
76         int64_t          vma_adjust;
77
78 #define SF_ALLOC        0x0001U
79 #define SF_LOAD         0x0002U
80 #define SF_NOLOAD       0x0004U
81 #define SF_READONLY     0x0008U
82 #define SF_DEBUG        0x0010U
83 #define SF_CODE         0x0020U
84 #define SF_DATA         0x0040U
85 #define SF_ROM          0x0080U
86 #define SF_SHARED       0X0100U
87 #define SF_CONTENTS     0x0200U
88
89         int     flags;
90         int     add;
91         int     append;
92         int     compress;
93         int     copy;
94         int     print;
95         int     remove;
96         int     rename;
97         int     setflags;
98         int     setlma;
99         int     setvma;
100
101         STAILQ_ENTRY(sec_action) sac_list;
102 };
103
104 /* Sections to add from file. */
105 struct sec_add {
106         char    *name;
107         char    *content;
108         size_t   size;
109
110         STAILQ_ENTRY(sec_add) sadd_list;
111 };
112
113 struct segment;
114
115 /* Internal data structure for sections. */
116 struct section {
117         struct segment  *seg;   /* containing segment */
118         struct segment  *seg_tls; /* tls segment */
119         const char      *name;  /* section name */
120         char            *newname; /* new section name */
121         Elf_Scn         *is;    /* input scn */
122         Elf_Scn         *os;    /* output scn */
123         void            *buf;   /* section content */
124         uint8_t         *pad;   /* section padding */
125         uint64_t         off;   /* section offset */
126         uint64_t         sz;    /* section size */
127         uint64_t         cap;   /* section capacity */
128         uint64_t         align; /* section alignment */
129         uint64_t         type;  /* section type */
130         uint64_t         flags; /* section flags */
131         uint64_t         vma;   /* section virtual addr */
132         uint64_t         lma;   /* section load addr */
133         uint64_t         pad_sz;/* section padding size */
134         int              loadable; /* whether loadable */
135         int              pseudo;
136         int              nocopy;
137
138         TAILQ_ENTRY(section) sec_list;  /* next section */
139 };
140
141 /* Internal data structure for segments. */
142 struct segment {
143         uint64_t        vaddr;  /* virtual addr (VMA) */
144         uint64_t        paddr;  /* physical addr (LMA) */
145         uint64_t        off;    /* file offset */
146         uint64_t        fsz;    /* file size */
147         uint64_t        msz;    /* memory size */
148         uint64_t        type;   /* segment type */
149         int             remove; /* whether remove */
150         int             nsec;   /* number of sections contained */
151         struct section **v_sec; /* list of sections contained */
152
153         STAILQ_ENTRY(segment) seg_list; /* next segment */
154 };
155
156 /*
157  * In-memory representation of ar(1) archive member(object).
158  */
159 struct ar_obj {
160         char    *name;          /* member name */
161         char    *buf;           /* member content */
162         void    *maddr;         /* mmap start address */
163         uid_t    uid;           /* user id */
164         gid_t    gid;           /* group id */
165         mode_t   md;            /* octal file permissions */
166         size_t   size;          /* member size */
167         time_t   mtime;         /* modification time */
168
169         STAILQ_ENTRY(ar_obj) objs;
170 };
171
172 /*
173  * Structure encapsulates the "global" data for "elfcopy" program.
174  */
175 struct elfcopy {
176         const char      *progname; /* program name */
177         int              iec;   /* elfclass of input object */
178         Elftc_Bfd_Target_Flavor itf; /* flavour of input object */
179         Elftc_Bfd_Target_Flavor otf; /* flavour of output object */
180         const char      *otgt;  /* output target name */
181         int              oec;   /* elfclass of output object */
182         unsigned char    oed;   /* endianness of output object */
183         int              oem;   /* EM_XXX of output object */
184         int              abi;   /* OSABI of output object */
185         Elf             *ein;   /* ELF descriptor of input object */
186         Elf             *eout;  /* ELF descriptor of output object */
187         int              iphnum; /* num. of input object phdr entries */
188         int              ophnum; /* num. of output object phdr entries */
189         int              nos;   /* num. of output object sections */
190
191         enum {
192                 STRIP_NONE = 0,
193                 STRIP_ALL,
194                 STRIP_DEBUG,
195                 STRIP_DWO,
196                 STRIP_NONDEBUG,
197                 STRIP_NONDWO,
198                 STRIP_UNNEEDED
199         } strip;
200
201 #define EXECUTABLE      0x00000001U
202 #define DYNAMIC         0x00000002U
203 #define RELOCATABLE     0x00000004U
204 #define SYMTAB_EXIST    0x00000010U
205 #define SYMTAB_INTACT   0x00000020U
206 #define KEEP_GLOBAL     0x00000040U
207 #define DISCARD_LOCAL   0x00000080U
208 #define WEAKEN_ALL      0x00000100U
209 #define PRESERVE_DATE   0x00001000U
210 #define SREC_FORCE_S3   0x00002000U
211 #define SREC_FORCE_LEN  0x00004000U
212 #define SET_START       0x00008000U
213 #define GAP_FILL        0x00010000U
214 #define WILDCARD        0x00020000U
215 #define NO_CHANGE_WARN  0x00040000U
216 #define SEC_ADD         0x00080000U
217 #define SEC_APPEND      0x00100000U
218 #define SEC_COMPRESS    0x00200000U
219 #define SEC_PRINT       0x00400000U
220 #define SEC_REMOVE      0x00800000U
221 #define SEC_COPY        0x01000000U
222 #define DISCARD_LLABEL  0x02000000U
223 #define LOCALIZE_HIDDEN 0x04000000U
224
225         int              flags;         /* elfcopy run control flags. */
226         int64_t          change_addr;   /* Section address adjustment. */
227         int64_t          change_start;  /* Entry point adjustment. */
228         uint64_t         set_start;     /* Entry point value. */
229         unsigned long    srec_len;      /* S-Record length. */
230         uint64_t         pad_to;        /* load address padding. */
231         uint8_t          fill;          /* gap fill value. */
232         char            *prefix_sec;    /* section prefix. */
233         char            *prefix_alloc;  /* alloc section prefix. */
234         char            *prefix_sym;    /* symbol prefix. */
235         char            *debuglink;     /* GNU debuglink file. */
236         struct section  *symtab;        /* .symtab section. */
237         struct section  *strtab;        /* .strtab section. */
238         struct section  *shstrtab;      /* .shstrtab section. */
239         uint64_t        *secndx;        /* section index map. */
240         uint64_t        *symndx;        /* symbol index map. */
241         unsigned char   *v_rel;         /* symbols needed by relocation. */
242         unsigned char   *v_grp;         /* symbols referred by section group. */
243         unsigned char   *v_secsym;      /* sections with section symbol. */
244         STAILQ_HEAD(, segment) v_seg;   /* list of segments. */
245         STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */
246         STAILQ_HEAD(, sec_add) v_sadd;  /* list of sections to add. */
247         STAILQ_HEAD(, symop) v_symop;   /* list of symbols operations. */
248         STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */
249         TAILQ_HEAD(, section) v_sec;    /* list of sections. */
250
251         /*
252          * Fields for the ar(1) archive.
253          */
254         char            *as;            /* buffer for archive string table. */
255         size_t           as_sz;         /* current size of as table. */
256         size_t           as_cap;        /* capacity of as table buffer. */
257         uint32_t         s_cnt;         /* current number of symbols. */
258         uint32_t        *s_so;          /* symbol offset table. */
259         size_t           s_so_cap;      /* capacity of so table buffer. */
260         char            *s_sn;          /* symbol name table */
261         size_t           s_sn_cap;      /* capacity of sn table buffer. */
262         size_t           s_sn_sz;       /* current size of sn table. */
263         off_t            rela_off;      /* offset relative to pseudo members. */
264         STAILQ_HEAD(, ar_obj) v_arobj;  /* archive object(member) list. */
265 };
266
267 void    add_section(struct elfcopy *_ecp, const char *_optarg);
268 void    add_to_shstrtab(struct elfcopy *_ecp, const char *_name);
269 void    add_to_symop_list(struct elfcopy *_ecp, const char *_name,
270     const char *_newname, unsigned int _op);
271 void    add_to_symtab(struct elfcopy *_ecp, const char *_name,
272     uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx,
273     unsigned char _st_info, unsigned char _st_other, int _ndx_known);
274 int     add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec);
275 void    adjust_addr(struct elfcopy *_ecp);
276 void    copy_content(struct elfcopy *_ecp);
277 void    copy_data(struct section *_s);
278 void    copy_phdr(struct elfcopy *_ecp);
279 void    copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name,
280     int _copy, int _sec_flags);
281 void    create_binary(int _ifd, int _ofd);
282 void    create_elf(struct elfcopy *_ecp);
283 void    create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn);
284 void    create_elf_from_ihex(struct elfcopy *_ecp, int _ifd);
285 void    create_elf_from_srec(struct elfcopy *_ecp, int _ifd);
286 struct section *create_external_section(struct elfcopy *_ecp, const char *_name,
287     char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype,
288     Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma,
289     int _loadable);
290 void    create_external_symtab(struct elfcopy *_ecp);
291 void    create_ihex(int _ifd, int _ofd);
292 void    create_pe(struct elfcopy *_ecp, int _ifd, int _ofd);
293 void    create_scn(struct elfcopy *_ecp);
294 void    create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);
295 void    create_symtab(struct elfcopy *_ecp);
296 void    create_symtab_data(struct elfcopy *_ecp);
297 void    create_tempfile(char **_fn, int *_fd);
298 void    finalize_external_symtab(struct elfcopy *_ecp);
299 void    free_elf(struct elfcopy *_ecp);
300 void    free_sec_act(struct elfcopy *_ecp);
301 void    free_sec_add(struct elfcopy *_ecp);
302 void    free_symtab(struct elfcopy *_ecp);
303 void    init_shstrtab(struct elfcopy *_ecp);
304 void    insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec,
305     int _tail);
306 struct section *insert_shtab(struct elfcopy *_ecp, int tail);
307 int     is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info);
308 int     is_remove_section(struct elfcopy *_ecp, const char *_name);
309 struct sec_action *lookup_sec_act(struct elfcopy *_ecp,
310     const char *_name, int _add);
311 struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,
312     unsigned int _op);
313 void    resync_sections(struct elfcopy *_ecp);
314 void    set_shstrtab(struct elfcopy *_ecp);
315 void    setup_phdr(struct elfcopy *_ecp);
316 void    update_shdr(struct elfcopy *_ecp, int _update_link);
317
318 #ifndef LIBELF_AR
319 int     ac_detect_ar(int _ifd);
320 void    ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd);
321 #endif  /* ! LIBELF_AR */