Path: blob/main/contrib/elftoolchain/elfcopy/elfcopy.h
39481 views
/*-1* Copyright (c) 2007-2013 Kai Wang2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25* $Id: elfcopy.h 3757 2019-06-28 01:15:28Z emaste $26*/2728#include <sys/queue.h>29#include <gelf.h>30#include <libelftc.h>3132#include "_elftc.h"3334/*35* User specified symbol operation (strip, keep, localize, globalize,36* weaken, rename, etc).37*/38struct symop {39const char *name;40const char *newname;4142#define SYMOP_KEEP 0x0001U43#define SYMOP_STRIP 0x0002U44#define SYMOP_GLOBALIZE 0x0004U45#define SYMOP_LOCALIZE 0x0008U46#define SYMOP_KEEPG 0x0010U47#define SYMOP_WEAKEN 0x0020U48#define SYMOP_REDEF 0x0040U4950unsigned int op;5152STAILQ_ENTRY(symop) symop_list;53};5455/* File containing symbol list. */56struct symfile {57dev_t dev;58ino_t ino;59size_t size;60char *data;61unsigned int op;6263STAILQ_ENTRY(symfile) symfile_list;64};6566/* Sections to copy/remove/rename/... */67struct sec_action {68const char *name;69const char *addopt;70const char *newname;71const char *string;72uint64_t lma;73uint64_t vma;74int64_t lma_adjust;75int64_t vma_adjust;7677#define SF_ALLOC 0x0001U78#define SF_LOAD 0x0002U79#define SF_NOLOAD 0x0004U80#define SF_READONLY 0x0008U81#define SF_DEBUG 0x0010U82#define SF_CODE 0x0020U83#define SF_DATA 0x0040U84#define SF_ROM 0x0080U85#define SF_SHARED 0X0100U86#define SF_CONTENTS 0x0200U8788int flags;89int add;90int append;91int compress;92int copy;93int print;94int remove;95int rename;96int setflags;97int setlma;98int setvma;99100STAILQ_ENTRY(sec_action) sac_list;101};102103/* Sections to add from file. */104struct sec_add {105char *name;106char *content;107size_t size;108109STAILQ_ENTRY(sec_add) sadd_list;110};111112struct segment;113114/* Internal data structure for sections. */115struct section {116struct segment *seg; /* containing segment */117struct segment *seg_tls; /* tls segment */118const char *name; /* section name */119char *newname; /* new section name */120Elf_Scn *is; /* input scn */121Elf_Scn *os; /* output scn */122void *buf; /* section content */123uint8_t *pad; /* section padding */124uint64_t off; /* section offset */125uint64_t sz; /* section size */126uint64_t cap; /* section capacity */127uint64_t align; /* section alignment */128uint64_t type; /* section type */129uint64_t flags; /* section flags */130uint64_t vma; /* section virtual addr */131uint64_t lma; /* section load addr */132uint64_t pad_sz;/* section padding size */133int loadable; /* whether loadable */134int pseudo;135int nocopy;136137Elftc_String_Table *strtab;138139TAILQ_ENTRY(section) sec_list; /* next section */140};141142TAILQ_HEAD(sectionlist, section);143144/* Internal data structure for segments. */145struct segment {146uint64_t vaddr; /* virtual addr (VMA) */147uint64_t paddr; /* physical addr (LMA) */148uint64_t off; /* file offset */149uint64_t fsz; /* file size */150uint64_t msz; /* memory size */151uint64_t type; /* segment type */152int remove; /* whether remove */153int nsec; /* number of sections contained */154struct section **v_sec; /* list of sections contained */155156STAILQ_ENTRY(segment) seg_list; /* next segment */157};158159/*160* In-memory representation of ar(1) archive member(object).161*/162struct ar_obj {163char *name; /* member name */164char *buf; /* member content */165void *maddr; /* mmap start address */166uid_t uid; /* user id */167gid_t gid; /* group id */168mode_t md; /* octal file permissions */169size_t size; /* member size */170time_t mtime; /* modification time */171172STAILQ_ENTRY(ar_obj) objs;173};174175/*176* Structure encapsulates the "global" data for "elfcopy" program.177*/178struct elfcopy {179const char *progname; /* program name */180int iec; /* elfclass of input object */181Elftc_Bfd_Target_Flavor itf; /* flavour of input object */182Elftc_Bfd_Target_Flavor otf; /* flavour of output object */183const char *otgt; /* output target name */184int oec; /* elfclass of output object */185unsigned char oed; /* endianness of output object */186int oem; /* EM_XXX of output object */187int abi; /* OSABI of output object */188Elf *ein; /* ELF descriptor of input object */189Elf *eout; /* ELF descriptor of output object */190int iphnum; /* num. of input object phdr entries */191int ophnum; /* num. of output object phdr entries */192int nos; /* num. of output object sections */193194enum {195STRIP_NONE = 0,196STRIP_ALL,197STRIP_DEBUG,198STRIP_DWO,199STRIP_NONDEBUG,200STRIP_NONDWO,201STRIP_UNNEEDED202} strip;203204#define EXECUTABLE 0x00000001U205#define DYNAMIC 0x00000002U206#define RELOCATABLE 0x00000004U207#define SYMTAB_EXIST 0x00000010U208#define SYMTAB_INTACT 0x00000020U209#define KEEP_GLOBAL 0x00000040U210#define DISCARD_LOCAL 0x00000080U211#define WEAKEN_ALL 0x00000100U212#define PRESERVE_DATE 0x00001000U213#define SREC_FORCE_S3 0x00002000U214#define SREC_FORCE_LEN 0x00004000U215#define SET_START 0x00008000U216#define GAP_FILL 0x00010000U217#define WILDCARD 0x00020000U218#define NO_CHANGE_WARN 0x00040000U219#define SEC_ADD 0x00080000U220#define SEC_APPEND 0x00100000U221#define SEC_COMPRESS 0x00200000U222#define SEC_PRINT 0x00400000U223#define SEC_REMOVE 0x00800000U224#define SEC_COPY 0x01000000U225#define DISCARD_LLABEL 0x02000000U226#define LOCALIZE_HIDDEN 0x04000000U227228int flags; /* elfcopy run control flags. */229int64_t change_addr; /* Section address adjustment. */230int64_t change_start; /* Entry point adjustment. */231uint64_t set_start; /* Entry point value. */232unsigned long srec_len; /* S-Record length. */233uint64_t pad_to; /* load address padding. */234uint8_t fill; /* gap fill value. */235char *prefix_sec; /* section prefix. */236char *prefix_alloc; /* alloc section prefix. */237char *prefix_sym; /* symbol prefix. */238char *debuglink; /* GNU debuglink file. */239struct section *symtab; /* .symtab section. */240struct section *strtab; /* .strtab section. */241struct section *shstrtab; /* .shstrtab section. */242uint64_t *secndx; /* section index map. */243uint64_t *symndx; /* symbol index map. */244unsigned char *v_rel; /* symbols needed by relocation. */245unsigned char *v_grp; /* symbols referred by section group. */246unsigned char *v_secsym; /* sections with section symbol. */247STAILQ_HEAD(, segment) v_seg; /* list of segments. */248STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */249STAILQ_HEAD(, sec_add) v_sadd; /* list of sections to add. */250STAILQ_HEAD(, symop) v_symop; /* list of symbols operations. */251STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */252TAILQ_HEAD(, section) v_sec; /* list of sections. */253254/*255* Fields for the ar(1) archive.256*/257char *as; /* buffer for archive string table. */258size_t as_sz; /* current size of as table. */259size_t as_cap; /* capacity of as table buffer. */260uint32_t s_cnt; /* current number of symbols. */261uint32_t *s_so; /* symbol offset table. */262size_t s_so_cap; /* capacity of so table buffer. */263char *s_sn; /* symbol name table */264size_t s_sn_cap; /* capacity of sn table buffer. */265size_t s_sn_sz; /* current size of sn table. */266off_t rela_off; /* offset relative to pseudo members. */267STAILQ_HEAD(, ar_obj) v_arobj; /* archive object(member) list. */268};269270void add_section(struct elfcopy *_ecp, const char *_optarg);271void add_to_shstrtab(struct elfcopy *_ecp, const char *_name);272void add_to_symop_list(struct elfcopy *_ecp, const char *_name,273const char *_newname, unsigned int _op);274void add_to_symtab(struct elfcopy *_ecp, const char *_name,275uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx,276unsigned char _st_info, unsigned char _st_other, int _ndx_known);277int add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec);278void adjust_addr(struct elfcopy *_ecp);279int cleanup_tempfile(char *_fn);280void copy_content(struct elfcopy *_ecp);281void copy_data(struct section *_s);282void copy_phdr(struct elfcopy *_ecp);283void copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name,284int _copy, int _sec_flags);285void create_binary(int _ifd, int _ofd);286void create_elf(struct elfcopy *_ecp);287void create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn);288void create_elf_from_ihex(struct elfcopy *_ecp, int _ifd);289void create_elf_from_srec(struct elfcopy *_ecp, int _ifd);290struct section *create_external_section(struct elfcopy *_ecp, const char *_name,291char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype,292Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma,293int _loadable);294void create_external_symtab(struct elfcopy *_ecp);295void create_ihex(int _ifd, int _ofd);296void create_pe(struct elfcopy *_ecp, int _ifd, int _ofd);297void create_scn(struct elfcopy *_ecp);298void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn);299void create_symtab(struct elfcopy *_ecp);300void create_symtab_data(struct elfcopy *_ecp);301void create_tempfile(const char *_src, char **_fn, int *_fd);302void finalize_external_symtab(struct elfcopy *_ecp);303void free_elf(struct elfcopy *_ecp);304void free_sec_act(struct elfcopy *_ecp);305void free_sec_add(struct elfcopy *_ecp);306void free_symtab(struct elfcopy *_ecp);307void init_shstrtab(struct elfcopy *_ecp);308void insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec,309int _tail);310struct section *insert_shtab(struct elfcopy *_ecp, int tail);311int is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info);312int is_remove_section(struct elfcopy *_ecp, const char *_name);313struct sec_action *lookup_sec_act(struct elfcopy *_ecp,314const char *_name, int _add);315struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name,316unsigned int _op);317void resync_sections(struct elfcopy *_ecp);318void setup_phdr(struct elfcopy *_ecp);319void update_shdr(struct elfcopy *_ecp, int _update_link);320321#ifndef LIBELF_AR322int ac_detect_ar(int _ifd);323void ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd);324#endif /* ! LIBELF_AR */325326327