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