/*- * Copyright (c) 2010-2013 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: ld.h 3174 2015-03-27 17:13:41Z emaste $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dwarf.h" #define oom() ld_fatal(ld, "out of memory") #include "utarray.h" #define uthash_fatal(msg) ld_fatal(ld, msg) #include "uthash.h" #include "_elftc.h" struct ld_file; struct ld_input_section_head; struct ld_path; struct ld_symbol; struct ld_symbol_head; struct ld_output_data_buffer; struct ld_wildcard_match; struct ld_ehframe_cie_head; struct ld_ehframe_fde_head; struct ld_section_group; #define LD_MAX_NESTED_GROUP 16 struct ld_state { Elftc_Bfd_Target *ls_itgt; /* input bfd target set by -b */ struct ld_file *ls_file; /* current open file */ unsigned ls_static; /* use static library */ unsigned ls_whole_archive; /* include whole archive */ unsigned ls_as_needed; /* DT_NEEDED */ unsigned ls_group_level; /* archive group level */ unsigned ls_extracted[LD_MAX_NESTED_GROUP + 1]; /* extracted from archive group */ unsigned ls_search_dir; /* search library directories */ uint64_t ls_loc_counter; /* location counter */ uint64_t ls_offset; /* cur. output section file offset */ STAILQ_HEAD(, ld_path) ls_lplist; /* search path list */ STAILQ_HEAD(, ld_path) ls_rplist; /* rpath list */ STAILQ_HEAD(, ld_path) ls_rllist; /* rpath-link list */ unsigned ls_arch_conflict; /* input arch conflict with output */ unsigned ls_first_elf_object; /* first ELF object to process */ unsigned ls_rerun; /* ld(1) restarted */ unsigned ls_archive_mb_header; /* extracted list header printed */ unsigned ls_first_output_sec; /* flag indicates 1st output section */ unsigned ls_ignore_next_plt; /* ignore next PLT relocation */ unsigned ls_version_local; /* version entry is local */ uint64_t ls_relative_reloc; /* number of *_RELATIVE relocations */ struct ld_input_section_head *ls_gc; /* garbage collection search list */ }; struct ld { const char *ld_progname; /* ld(1) program name */ struct ld_arch *ld_arch; /* arch-specific callbacks */ struct ld_arch *ld_arch_list; /* list of supported archs */ Elftc_Bfd_Target *ld_otgt; /* default output format */ Elftc_Bfd_Target *ld_otgt_be; /* big-endian output format */ Elftc_Bfd_Target *ld_otgt_le; /* little-endian output format */ char *ld_otgt_name; /* output format name */ char *ld_otgt_be_name; /* big-endian output format name */ char *ld_otgt_le_name; /* little-endian output format name */ struct ld_output *ld_output; /* output object */ char *ld_output_file; /* output file name */ char *ld_entry; /* entry point set by -e */ char *ld_scp_entry; /* entry point set by linker script */ char *ld_interp; /* dynamic linker */ char *ld_soname; /* DT_SONAME */ struct ld_script *ld_scp; /* linker script */ struct ld_state ld_state; /* linker state */ struct ld_strtab *ld_shstrtab; /* section name table */ struct ld_symbol_head *ld_ext_symbols; /* -u/EXTERN symbols */ struct ld_symbol_head *ld_var_symbols; /* ldscript var symbols */ struct ld_symbol *ld_sym; /* internal symbol table */ struct ld_symbol *ld_symtab_import; /* hash for import symbols */ struct ld_symbol *ld_symtab_export; /* hash for export symbols */ struct ld_symbol_defver *ld_defver; /* default version table */ struct ld_symbol_table *ld_symtab; /* .symtab symbol table */ struct ld_strtab *ld_strtab; /* .strtab string table */ struct ld_symbol_table *ld_dynsym; /* .dynsym symbol table */ struct ld_strtab *ld_dynstr; /* .dynstr string table */ struct ld_symbol_head *ld_dyn_symbols; /* dynamic symbol list */ struct ld_wildcard_match *ld_wm; /* wildcard hash table */ struct ld_input_section *ld_dynbss; /* .dynbss section */ struct ld_input_section *ld_got; /* .got section */ struct ld_ehframe_cie_head *ld_cie; /* ehframe CIE list */ struct ld_ehframe_fde_head *ld_fde; /* ehframe FDE list */ struct ld_section_group *ld_sg; /* included section groups */ unsigned char ld_common_alloc; /* always alloc space for common sym */ unsigned char ld_common_no_alloc; /* never alloc space for common sym */ unsigned char ld_emit_reloc; /* emit relocations */ unsigned char ld_gen_gnustack; /* generate PT_GNUSTACK */ unsigned char ld_print_linkmap; /* print link map */ unsigned char ld_stack_exec; /* stack executable */ unsigned char ld_stack_exec_set; /* stack executable override */ unsigned char ld_exec; /* output normal executable */ unsigned char ld_pie; /* position-independent executable */ unsigned char ld_dso; /* output shared library */ unsigned char ld_reloc; /* output relocatable object */ unsigned char ld_dynamic_link; /* perform dynamic linking */ unsigned char ld_print_version; /* linker version printed */ unsigned char ld_gc; /* perform garbage collection */ unsigned char ld_gc_print; /* print removed sections */ unsigned char ld_ehframe_hdr; /* create .eh_frame_hdr section */ STAILQ_HEAD(ld_input_head, ld_input) ld_lilist; /* input object list */ TAILQ_HEAD(ld_file_head, ld_file) ld_lflist; /* input file list */ }; void ld_err(struct ld *, const char *, ...); void ld_fatal(struct ld *, const char *, ...); void ld_fatal_std(struct ld *, const char *, ...); void ld_warn(struct ld *, const char *, ...); void ld_info(struct ld *, const char *, ...);