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