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