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