1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  *      Copyright (c) 1988 AT&T
  24  *        All Rights Reserved
  25  *
  26  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  27  * Copyright 2016 RackTop Systems.
  28  */
  29 
  30 #ifndef _LIBLD_H
  31 #define _LIBLD_H
  32 
  33 #include <stdlib.h>
  34 #include <libelf.h>
  35 #include <sgs.h>
  36 #include <_machelf.h>
  37 #include <string_table.h>
  38 #include <sys/avl.h>
  39 #include <alist.h>
  40 #include <elfcap.h>
  41 
  42 #ifdef  __cplusplus
  43 extern "C" {
  44 #endif
  45 
  46 /*
  47  * Default directory search path manipulation for the link-editor.  YLDIR
  48  * indicates which directory in LIBPATH is replaced by the -YL option to cc
  49  * and ld.  YUDIR indicates which directory is replaced by -YU.
  50  */
  51 #define YLDIR   1
  52 #define YUDIR   2
  53 
  54 /*
  55  * Define a hash value that can never be returned from elf_hash().
  56  */
  57 #define SYM_NOHASH      (~(Word)0)
  58 
  59 /*
  60  * Macro that can be used to represent both ORDER flags
  61  * in a section header.
  62  */
  63 #define ALL_SHF_ORDER   (SHF_ORDERED | SHF_LINK_ORDER)
  64 
  65 /*
  66  * The linker merges (concatenates) sections with the same name and
  67  * compatible section header flags. When comparing these flags,
  68  * there are some that should not be included in the decision.
  69  * The ALL_SHF_IGNORE constant defines these flags.
  70  *
  71  * NOTE: SHF_MERGE|SHF_STRINGS:
  72  * The compiler is allowed to set the SHF_MERGE|SHF_STRINGS flags in
  73  * order to tell the linker that:
  74  *
  75  *      1) There is nothing in the section except null terminated strings.
  76  *      2) Those strings do not contain NULL bytes, except as termination.
  77  *      3) All references to these strings occur via standard relocation
  78  *              records.
  79  *
  80  * As a result, if two compatible sections both have these flags set, it is
  81  * OK to combine the strings they contain into a single merged string table
  82  * with duplicates removed and tail strings merged.
  83  *
  84  * This is a different meaning than the simple concatenating of sections
  85  * that the linker always does. It is a hint that an additional optimization
  86  * is possible, but not required. This means that sections that do not
  87  * share the same SHF_MERGE|SHF_STRINGS values can be concatenated,
  88  * but cannot have their duplicate strings combined. Hence, the
  89  * SHF_MERGE|SHF_STRINGS flags should be ignored when deciding whether
  90  * two sections can be concatenated.
  91  */
  92 #define ALL_SHF_IGNORE  (ALL_SHF_ORDER | SHF_GROUP | SHF_MERGE | SHF_STRINGS)
  93 
  94 /*
  95  * Define symbol reference types for use in symbol resolution.
  96  */
  97 typedef enum {
  98         REF_DYN_SEEN,                   /* a .so symbol has been seen */
  99         REF_DYN_NEED,                   /* a .so symbol satisfies a .o symbol */
 100         REF_REL_NEED,                   /* a .o symbol */
 101         REF_NUM                         /* the number of symbol references */
 102 } Symref;
 103 
 104 /*
 105  * Relocation descriptor cache
 106  */
 107 struct rel_cache {
 108         APlist          *rc_list;       /* list of Rel_cachebuf */
 109         Word            rc_cnt;         /*      and count */
 110 };
 111 
 112 /*
 113  * GOT reference models
 114  */
 115 typedef enum {
 116         GOT_REF_GENERIC,        /* generic symbol reference */
 117         GOT_REF_TLSIE,          /* TLS initial exec (gnu) reference */
 118         GOT_REF_TLSLD,          /* TLS local dynamic reference */
 119         GOT_REF_TLSGD           /* TLS general dynamic reference */
 120 } Gotref;
 121 
 122 typedef struct {
 123         Xword           gn_addend;      /* addend associated with GOT entry */
 124         Sword           gn_gotndx;      /* GOT table index */
 125         Gotref          gn_gotref;
 126 } Gotndx;
 127 
 128 /*
 129  * Got debugging structure.  The got index is defined as a signed value as we
 130  * do so much mucking around with negative and positive gots on SPARC, and sign
 131  * extension is necessary when building 64-bit objects.  On intel we explicitly
 132  * cast this variable to an unsigned value.
 133  */
 134 typedef struct {
 135         Sym_desc        *gt_sym;
 136         Gotndx          gt_gndx;
 137 } Gottable;
 138 
 139 /*
 140  * The link-editor caches the results of sloppy relocation processing
 141  * in a variable of type Rlxrel_cache. Symbols come for processing in sorted
 142  * order, so a single item cache suffices to eliminate duplicate lookups.
 143  *
 144  * When sloppy relocation processing fails, the Rlxrel_rej enum reports
 145  * the underlying reason.
 146  */
 147 typedef enum {
 148         RLXREL_REJ_NONE = 0,    /* Replacement symbol was found */
 149         RLXREL_REJ_TARGET,      /* Target sec disallows relaxed relocations */
 150         RLXREL_REJ_SECTION,     /* Either there is no replacement section, */
 151                                 /*      or its attributes are incompatible */
 152         RLXREL_REJ_SYMBOL,      /* Replacement symbol not found */
 153 } Rlxrel_rej;
 154 
 155 typedef struct sreloc_cache {
 156         Sym_desc        *sr_osdp;       /* Original symbol */
 157         Sym_desc        *sr_rsdp;       /* Replacement symbol */
 158         Rlxrel_rej      sr_rej;         /* Reason for failure if NULL sr_rsdp */
 159 } Rlxrel_cache;
 160 
 161 /*
 162  * Nodes in an ofl_wrap AVL tree
 163  *
 164  * wsn_name is the name of the symbol to be wrapped. wsn_wrapname is used
 165  * when we need to refer to the wrap symbol, and consists of the symbol
 166  * name with a __wrap_ prefix.
 167  */
 168 typedef struct wrap_sym_node {
 169         avl_node_t      wsn_avlnode;    /* AVL book-keeping */
 170         const char      *wsn_name;      /* Symbol name: XXX */
 171         const char      *wsn_wrapname;  /* Wrap symbol name: __wrap_XXX */
 172 } WrapSymNode;
 173 
 174 /*
 175  * Capabilities structures, used to maintain a capabilities set.
 176  *
 177  * Capabilities can be defined within input relocatable objects, and can be
 178  * augmented or replaced by mapfile directives.  In addition, mapfile directives
 179  * can be used to exclude capabilities that would otherwise be carried over to
 180  * the output object.
 181  *
 182  * CA_SUNW_HW_1, CA_SUNW_SF_1 and CA_SUNW_HW_2 values are bitmasks.  A current
 183  * value, and an exclude value are maintained for each capability.
 184  *
 185  * There can be multiple CA_SUNW_PLAT and CA_SUNW_MACH entries and thus Alists
 186  * are used to collect these entries.  A current list for each capability is
 187  * maintained as Capstr entries, which provide for maintaining the strings
 188  * eventual index into a string table.  An exclude list is maintained as a
 189  * list of string pointers.
 190  */
 191 typedef struct {
 192         elfcap_mask_t   cm_val;         /* bitmask value */
 193         elfcap_mask_t   cm_exc;         /* bits to exclude from final object */
 194 } Capmask;
 195 
 196 typedef struct {
 197         Alist           *cl_val;        /* string (Capstr) value */
 198         APlist          *cl_exc;        /* strings to exclude from final */
 199 } Caplist;                              /*      object */
 200 
 201 typedef struct {
 202         char            *cs_str;        /* platform or machine name */
 203         Word            cs_ndx;         /* the entries output Cap index */
 204 } Capstr;
 205 
 206 typedef uint_t          oc_flag_t;
 207 typedef struct {
 208         Capmask         oc_hw_1;        /* CA_SUNW_HW_1 capabilities */
 209         Capmask         oc_sf_1;        /* CA_SUNW_SF_1 capabilities */
 210         Capmask         oc_hw_2;        /* CA_SUNW_HW_2 capabilities */
 211         Caplist         oc_plat;        /* CA_SUNW_PLAT capabilities */
 212         Caplist         oc_mach;        /* CA_SUNW_MACH capabilities */
 213         Capstr          oc_id;          /* CA_SUNW_ID capability */
 214         oc_flag_t       oc_flags;
 215 } Objcapset;
 216 
 217 #define FLG_OCS_USRDEFID        0x1     /* user defined CA_SUNW_ID */
 218 
 219 /*
 220  * Bitmasks for a single capability. Capabilities come from input objects,
 221  * augmented or replaced by mapfile directives. In addition, mapfile directives
 222  * can be used to exclude bits that would otherwise be set in the output object.
 223  */
 224 typedef struct {
 225         elfcap_mask_t   cm_value;       /* Bitmask value */
 226         elfcap_mask_t   cm_exclude;     /* Bits to remove from final object */
 227 } CapMask;
 228 
 229 /*
 230  * Combine the bitmask in a CapMask with the exclusion mask and
 231  * return the resulting final value.
 232  */
 233 #define CAPMASK_VALUE(_cbmp) ((_cbmp)->cm_value & ~(_cbmp)->cm_exclude)
 234 
 235 typedef struct {
 236         CapMask         c_hw_1;         /* CA_SUNW_HW_1 capabilities */
 237         CapMask         c_sf_1;         /* CA_SUNW_SF_1 capabilities */
 238         CapMask         c_hw_2;         /* CA_SUNW_HW_2 capabilities */
 239 } Outcapset;
 240 
 241 
 242 /*
 243  * Output file processing structure
 244  */
 245 typedef Lword   ofl_flag_t;
 246 typedef Word    ofl_guideflag_t;
 247 struct ofl_desc {
 248         char            *ofl_sgsid;     /* link-editor identification */
 249         const char      *ofl_name;      /* full file name */
 250         Elf             *ofl_elf;       /* elf_memory() elf descriptor */
 251         Elf             *ofl_welf;      /* ELF_C_WRITE elf descriptor */
 252         Ehdr            *ofl_dehdr;     /* default elf header, and new elf */
 253         Ehdr            *ofl_nehdr;     /*      header describing this file */
 254         Phdr            *ofl_phdr;      /* program header descriptor */
 255         Phdr            *ofl_tlsphdr;   /* TLS phdr */
 256         int             ofl_fd;         /* file descriptor */
 257         size_t          ofl_size;       /* image size */
 258         APlist          *ofl_maps;      /* list of input mapfiles */
 259         APlist          *ofl_segs;      /* list of segments */
 260         APlist          *ofl_segs_order; /* SEGMENT_ORDER segments */
 261         avl_tree_t      ofl_segs_avl;   /* O(log N) access to named segments */
 262         APlist          *ofl_ents;      /* list of entrance descriptors */
 263         avl_tree_t      ofl_ents_avl;   /* O(log N) access to named ent. desc */
 264         APlist          *ofl_objs;      /* relocatable object file list */
 265         Word            ofl_objscnt;    /*      and count */
 266         APlist          *ofl_ars;       /* archive library list */
 267         Word            ofl_arscnt;     /*      and count */
 268         int             ofl_ars_gsandx; /* archive group argv index. 0 means */
 269                                         /*      no current group, < 0 means */
 270                                         /*      error reported. >0 is cur ndx */
 271         Word            ofl_ars_gsndx;  /* current -zrescan-start ofl_ars ndx */
 272         APlist          *ofl_sos;       /* shared object list */
 273         Word            ofl_soscnt;     /*      and count */
 274         APlist          *ofl_soneed;    /* list of implicitly required .so's */
 275         APlist          *ofl_socntl;    /* list of .so control definitions */
 276         Rel_cache       ofl_outrels;    /* list of output relocations */
 277         Rel_cache       ofl_actrels;    /* list of relocations to perform */
 278         APlist          *ofl_relaux;    /* Rel_aux cache for outrels/actrels */
 279         Word            ofl_entrelscnt; /* no of relocations entered */
 280         Alist           *ofl_copyrels;  /* list of copy relocations */
 281         APlist          *ofl_ordered;   /* list of shf_ordered sections */
 282         APlist          *ofl_symdtent;  /* list of syminfo symbols that need */
 283                                         /*      to reference .dynamic entries */
 284         APlist          *ofl_ismove;    /* list of .SUNW_move sections */
 285         APlist          *ofl_ismoverel; /* list of relocation input section */
 286                                         /* targeting to expanded area */
 287         APlist          *ofl_parsyms;   /* list of partially initialized */
 288                                         /*      symbols (ie. move symbols) */
 289         APlist          *ofl_extrarels; /* relocation sections which have */
 290                                         /*    a NULL sh_info */
 291         avl_tree_t      *ofl_groups;    /* pointer to head of Groups AVL tree */
 292         APlist          *ofl_initarray; /* list of init array func names */
 293         APlist          *ofl_finiarray; /* list of fini array func names */
 294         APlist          *ofl_preiarray; /* list of preinit array func names */
 295         APlist          *ofl_rtldinfo;  /* list of rtldinfo syms */
 296         APlist          *ofl_osgroups;  /* list of output GROUP sections */
 297         APlist          *ofl_ostlsseg;  /* pointer to sections in TLS segment */
 298         APlist          *ofl_unwind;    /* list of unwind output sections */
 299         Os_desc         *ofl_unwindhdr; /* Unwind hdr */
 300         avl_tree_t      ofl_symavl;     /* pointer to head of Syms AVL tree */
 301         Sym_desc        **ofl_regsyms;  /* array of potential register */
 302         Word            ofl_regsymsno;  /*    symbols and array count */
 303         Word            ofl_regsymcnt;  /* no. of output register symbols */
 304         Word            ofl_lregsymcnt; /* no. of local register symbols */
 305         Sym_desc        *ofl_dtracesym; /* ld -zdtrace= */
 306         ofl_flag_t      ofl_flags;      /* various state bits, args etc. */
 307         ofl_flag_t      ofl_flags1;     /*      more flags */
 308         void            *ofl_entry;     /* entry point (-e and Sym_desc *) */
 309         char            *ofl_filtees;   /* shared objects we are a filter for */
 310         const char      *ofl_soname;    /* (-h option) output file name for */
 311                                         /*      dynamic structure */
 312         const char      *ofl_interp;    /* interpreter name used by exec() */
 313         char            *ofl_rpath;     /* run path to store in .dynamic */
 314         char            *ofl_config;    /* config path to store in .dynamic */
 315         APlist          *ofl_ulibdirs;  /* user supplied library search list */
 316         APlist          *ofl_dlibdirs;  /* default library search list */
 317         Word            ofl_vercnt;     /* number of versions to generate */
 318         APlist          *ofl_verdesc;   /* list of version descriptors */
 319         size_t          ofl_verdefsz;   /* size of version definition section */
 320         size_t          ofl_verneedsz;  /* size of version needed section */
 321         Word            ofl_entercnt;   /* no. of global symbols entered */
 322         Word            ofl_globcnt;    /* no. of global symbols to output */
 323         Word            ofl_scopecnt;   /* no. of scoped symbols to output */
 324         Word            ofl_dynscopecnt; /* no. scoped syms in .SUNW_ldynsym */
 325         Word            ofl_elimcnt;    /* no. of eliminated symbols */
 326         Word            ofl_locscnt;    /* no. of local symbols in .symtab */
 327         Word            ofl_dynlocscnt; /* no. local symbols in .SUNW_ldynsym */
 328         Word            ofl_dynsymsortcnt; /* no. ndx in .SUNW_dynsymsort */
 329         Word            ofl_dyntlssortcnt; /* no. ndx in .SUNW_dyntlssort */
 330         Word            ofl_dynshdrcnt; /* no. of output section in .dynsym */
 331         Word            ofl_shdrcnt;    /* no. of output sections */
 332         Word            ofl_caploclcnt; /* no. of local capabilities symbols */
 333         Word            ofl_capsymcnt;  /* no. of symbol capabilities entries */
 334                                         /*      required */
 335         Word            ofl_capchaincnt; /* no. of Capchain symbols */
 336         APlist          *ofl_capgroups; /* list of capabilities groups */
 337         avl_tree_t      *ofl_capfamilies; /* capability family AVL tree */
 338         Str_tbl         *ofl_shdrsttab; /* Str_tbl for shdr strtab */
 339         Str_tbl         *ofl_strtab;    /* Str_tbl for symtab strtab */
 340         Str_tbl         *ofl_dynstrtab; /* Str_tbl for dymsym strtab */
 341         Gotndx          *ofl_tlsldgotndx; /* index to LD TLS_index structure */
 342         Xword           ofl_relocsz;    /* size of output relocations */
 343         Xword           ofl_relocgotsz; /* size of .got relocations */
 344         Xword           ofl_relocpltsz; /* size of .plt relocations */
 345         Xword           ofl_relocbsssz; /* size of .bss (copy) relocations */
 346         Xword           ofl_relocrelsz; /* size of .rel[a] relocations */
 347         Word            ofl_relocincnt; /* no. of input relocations */
 348         Word            ofl_reloccnt;   /* tot number of output relocations */
 349         Word            ofl_reloccntsub; /* tot numb of output relocations to */
 350                                         /*      skip (-zignore) */
 351         Word            ofl_relocrelcnt; /* tot number of relative */
 352                                         /*      relocations */
 353         Word            ofl_gotcnt;     /* no. of .got entries */
 354         Word            ofl_pltcnt;     /* no. of .plt entries */
 355         Word            ofl_pltpad;     /* no. of .plt padd entries */
 356         Word            ofl_hashbkts;   /* no. of hash buckets required */
 357         Is_desc         *ofl_isbss;     /* .bss input section (globals) */
 358         Is_desc         *ofl_islbss;    /* .lbss input section (globals) */
 359         Is_desc         *ofl_istlsbss;  /* .tlsbss input section (globals) */
 360         Is_desc         *ofl_isparexpn; /* -z nopartial .data input section */
 361         Os_desc         *ofl_osdynamic; /* .dynamic output section */
 362         Os_desc         *ofl_osdynsym;  /* .dynsym output section */
 363         Os_desc         *ofl_osldynsym; /* .SUNW_ldynsym output section */
 364         Os_desc         *ofl_osdynstr;  /* .dynstr output section */
 365         Os_desc         *ofl_osdynsymsort; /* .SUNW_dynsymsort output section */
 366         Os_desc         *ofl_osdyntlssort; /* .SUNW_dyntlssort output section */
 367         Os_desc         *ofl_osgot;     /* .got output section */
 368         Os_desc         *ofl_oshash;    /* .hash output section */
 369         Os_desc         *ofl_osinitarray; /* .init_array output section */
 370         Os_desc         *ofl_osfiniarray; /* .fini_array output section */
 371         Os_desc         *ofl_ospreinitarray; /* .preinit_array output section */
 372         Os_desc         *ofl_osinterp;  /* .interp output section */
 373         Os_desc         *ofl_oscap;     /* .SUNW_cap output section */
 374         Os_desc         *ofl_oscapinfo; /* .SUNW_capinfo output section */
 375         Os_desc         *ofl_oscapchain; /* .SUNW_capchain output section */
 376         Os_desc         *ofl_osplt;     /* .plt output section */
 377         Os_desc         *ofl_osmove;    /* .SUNW_move output section */
 378         Os_desc         *ofl_osrelhead; /* first relocation section */
 379         Os_desc         *ofl_osrel;     /* .rel[a] relocation section */
 380         Os_desc         *ofl_osshstrtab; /* .shstrtab output section */
 381         Os_desc         *ofl_osstrtab;  /* .strtab output section */
 382         Os_desc         *ofl_ossymtab;  /* .symtab output section */
 383         Os_desc         *ofl_ossymshndx; /* .symtab_shndx output section */
 384         Os_desc         *ofl_osdynshndx; /* .dynsym_shndx output section */
 385         Os_desc         *ofl_osldynshndx; /* .SUNW_ldynsym_shndx output sec */
 386         Os_desc         *ofl_osverdef;  /* .version definition output section */
 387         Os_desc         *ofl_osverneed; /* .version needed output section */
 388         Os_desc         *ofl_osversym;  /* .version symbol ndx output section */
 389         Word            ofl_dtflags_1;  /* DT_FLAGS_1 entries */
 390         Word            ofl_dtflags;    /* DT_FLAGS entries */
 391         Os_desc         *ofl_ossyminfo; /* .SUNW_syminfo output section */
 392         Half            ofl_parexpnndx; /* -z nopartial section index */
 393                                         /* Ref. at perform_outreloc() in */
 394                                         /* libld/{mach}/machrel.c */
 395         Xword           *ofl_checksum;  /* DT_CHECKSUM value address */
 396         char            *ofl_depaudit;  /* dependency auditing required (-P) */
 397         char            *ofl_audit;     /* object auditing required (-p) */
 398         Alist           *ofl_symfltrs;  /* per-symbol filtees and their */
 399         Alist           *ofl_dtsfltrs;  /*      associated .dynamic/.dynstrs */
 400         Objcapset       ofl_ocapset;    /* object capabilities */
 401         Lm_list         *ofl_lml;       /* runtime link-map list */
 402         Gottable        *ofl_gottable;  /* debugging got information */
 403         Rlxrel_cache    ofl_sr_cache;   /* Cache last result from */
 404                                         /*      sloppy_comdat_reloc() */
 405         APlist          *ofl_maptext;   /* mapfile added text sections */
 406         APlist          *ofl_mapdata;   /* mapfile added data sections */
 407         avl_tree_t      *ofl_wrap;      /* -z wrap symbols */
 408         ofl_guideflag_t ofl_guideflags; /* -z guide flags */
 409         APlist          *ofl_assdeflib; /* -z assert-deflib exceptions */
 410 };
 411 
 412 #define FLG_OF_DYNAMIC  0x00000001      /* generate dynamic output module */
 413 #define FLG_OF_STATIC   0x00000002      /* generate static output module */
 414 #define FLG_OF_EXEC     0x00000004      /* generate an executable */
 415 #define FLG_OF_RELOBJ   0x00000008      /* generate a relocatable object */
 416 #define FLG_OF_SHAROBJ  0x00000010      /* generate a shared object */
 417 #define FLG_OF_BFLAG    0x00000020      /* do no special plt building: -b */
 418 #define FLG_OF_IGNENV   0x00000040      /* ignore LD_LIBRARY_PATH: -i */
 419 #define FLG_OF_STRIP    0x00000080      /* strip output: -s */
 420 #define FLG_OF_NOWARN   0x00000100      /* disable symbol warnings: -t */
 421 #define FLG_OF_NOUNDEF  0x00000200      /* allow no undefined symbols: -zdefs */
 422 #define FLG_OF_PURETXT  0x00000400      /* allow no text relocations: -ztext */
 423 #define FLG_OF_GENMAP   0x00000800      /* generate a memory map: -m */
 424 #define FLG_OF_DYNLIBS  0x00001000      /* dynamic input allowed: -Bdynamic */
 425 #define FLG_OF_SYMBOLIC 0x00002000      /* bind global symbols: -Bsymbolic */
 426 #define FLG_OF_ADDVERS  0x00004000      /* add version stamp: -Qy */
 427 #define FLG_OF_NOLDYNSYM 0x00008000     /* -znoldynsym set */
 428 #define FLG_OF_IS_ORDER 0x00010000      /* input section ordering within a */
 429                                         /*      segment is required */
 430 #define FLG_OF_EC_FILES 0x00020000      /* Ent_desc exist w/non-NULL ec_files */
 431 #define FLG_OF_TEXTREL  0x00040000      /* text relocations have been found */
 432 #define FLG_OF_MULDEFS  0x00080000      /* multiple symbols are allowed */
 433 #define FLG_OF_TLSPHDR  0x00100000      /* a TLS program header is required */
 434 #define FLG_OF_BLDGOT   0x00200000      /* build GOT table */
 435 #define FLG_OF_VERDEF   0x00400000      /* record version definitions */
 436 #define FLG_OF_VERNEED  0x00800000      /* record version dependencies */
 437 #define FLG_OF_NOVERSEC 0x01000000      /* don't record version sections */
 438 #define FLG_OF_KEY      0x02000000      /* file requires sort keys */
 439 #define FLG_OF_PROCRED  0x04000000      /* process any symbol reductions by */
 440                                         /*      effecting the symbol table */
 441                                         /*      output and relocations */
 442 #define FLG_OF_SYMINFO  0x08000000      /* create a syminfo section */
 443 #define FLG_OF_AUX      0x10000000      /* ofl_filter is an auxiliary filter */
 444 #define FLG_OF_FATAL    0x20000000      /* fatal error during input */
 445 #define FLG_OF_WARN     0x40000000      /* warning during input processing. */
 446 #define FLG_OF_VERBOSE  0x80000000      /* -z verbose flag set */
 447 
 448 #define FLG_OF_MAPSYMB  0x000100000000  /* symbolic scope definition seen */
 449 #define FLG_OF_MAPGLOB  0x000200000000  /* global scope definition seen */
 450 #define FLG_OF_COMREL   0x000400000000  /* -z combreloc set, which enables */
 451                                         /*      DT_RELACNT tracking, */
 452 #define FLG_OF_NOCOMREL 0x000800000000  /* -z nocombreloc set */
 453 #define FLG_OF_AUTOLCL  0x001000000000  /* automatically reduce unspecified */
 454                                         /*      global symbols to locals */
 455 #define FLG_OF_AUTOELM  0x002000000000  /* automatically eliminate */
 456                                         /*      unspecified global symbols */
 457 #define FLG_OF_REDLSYM  0x004000000000  /* reduce local symbols */
 458 #define FLG_OF_OS_ORDER 0x008000000000  /* output section ordering required */
 459 #define FLG_OF_OSABI    0x010000000000  /* tag object as ELFOSABI_SOLARIS */
 460 #define FLG_OF_ADJOSCNT 0x020000000000  /* adjust ofl_shdrcnt to accommodate */
 461                                         /*      discarded sections */
 462 #define FLG_OF_OTOSCAP  0x040000000000  /* convert object capabilities to */
 463                                         /*      symbol capabilities */
 464 #define FLG_OF_PTCAP    0x080000000000  /* PT_SUNWCAP required */
 465 #define FLG_OF_CAPSTRS  0x100000000000  /* capability strings are required */
 466 #define FLG_OF_EHFRAME  0x200000000000  /* output contains .eh_frame section */
 467 #define FLG_OF_FATWARN  0x400000000000  /* make warnings fatal */
 468 #define FLG_OF_ADEFLIB  0x800000000000  /* no libraries in default path */
 469 #define FLG_OF_MULINCL  0x1000000000000 /* allow multiple inclusions */
 470 
 471 /*
 472  * In the flags1 arena, establish any options that are applicable to archive
 473  * extraction first, and associate a mask.  These values are recorded with any
 474  * archive descriptor so that they may be reset should the archive require a
 475  * rescan to try and resolve undefined symbols.
 476  */
 477 #define FLG_OF1_ALLEXRT 0x0000000001    /* extract all members from an */
 478                                         /*      archive file */
 479 #define FLG_OF1_WEAKEXT 0x0000000002    /* allow archive extraction to */
 480                                         /*      resolve weak references */
 481 #define MSK_OF1_ARCHIVE 0x0000000003    /* archive flags mask */
 482 
 483 #define FLG_OF1_NOINTRP 0x0000000008    /* -z nointerp flag set */
 484 #define FLG_OF1_ZDIRECT 0x0000000010    /* -z direct flag set */
 485 #define FLG_OF1_NDIRECT 0x0000000020    /* no-direct bindings specified */
 486 #define FLG_OF1_DEFERRED 0x0000000040   /* deferred dependency recording */
 487 
 488 #define FLG_OF1_RELDYN  0x0000000100    /* process .dynamic in rel obj */
 489 #define FLG_OF1_NRLXREL 0x0000000200    /* -z norelaxreloc flag set */
 490 #define FLG_OF1_RLXREL  0x0000000400    /* -z relaxreloc flag set */
 491 #define FLG_OF1_IGNORE  0x0000000800    /* ignore unused dependencies */
 492 #define FLG_OF1_NOSGHND 0x0000001000    /* -z nosighandler flag set */
 493 #define FLG_OF1_TEXTOFF 0x0000002000    /* text relocations are ok */
 494 #define FLG_OF1_ABSEXEC 0x0000004000    /* -zabsexec set */
 495 #define FLG_OF1_LAZYLD  0x0000008000    /* lazy loading of objects enabled */
 496 #define FLG_OF1_GRPPRM  0x0000010000    /* dependencies are to have */
 497                                         /*      GROUPPERM enabled */
 498 
 499 #define FLG_OF1_NOPARTI 0x0000040000    /* -znopartial set */
 500 #define FLG_OF1_BSSOREL 0x0000080000    /* output relocation against bss */
 501                                         /*      section */
 502 #define FLG_OF1_TLSOREL 0x0000100000    /* output relocation against .tlsbss */
 503                                         /*      section */
 504 #define FLG_OF1_MEMORY  0x0000200000    /* produce a memory model */
 505 #define FLG_OF1_NGLBDIR 0x0000400000    /* no DT_1_DIRECT flag allowed */
 506 #define FLG_OF1_ENCDIFF 0x0000800000    /* host running linker has different */
 507                                         /*      byte order than output object */
 508 #define FLG_OF1_VADDR   0x0001000000    /* a segment defines explicit vaddr */
 509 #define FLG_OF1_EXTRACT 0x0002000000    /* archive member has been extracted */
 510 #define FLG_OF1_RESCAN  0x0004000000    /* any archives should be rescanned */
 511 #define FLG_OF1_IGNPRC  0x0008000000    /* ignore processing required */
 512 #define FLG_OF1_NCSTTAB 0x0010000000    /* -znocompstrtab set */
 513 #define FLG_OF1_DONE    0x0020000000    /* link-editor processing complete */
 514 #define FLG_OF1_NONREG  0x0040000000    /* non-regular file specified as */
 515                                         /*      the output file */
 516 #define FLG_OF1_ALNODIR 0x0080000000    /* establish NODIRECT for all */
 517                                         /*      exported interfaces. */
 518 #define FLG_OF1_OVHWCAP1 0x0100000000   /* override CA_SUNW_HW_1 capabilities */
 519 #define FLG_OF1_OVSFCAP1 0x0200000000   /* override CA_SUNW_SF_1 capabilities */
 520 #define FLG_OF1_OVHWCAP2 0x0400000000   /* override CA_SUNW_HW_2 capabilities */
 521 #define FLG_OF1_OVMACHCAP 0x0800000000  /* override CA_SUNW_MACH capability */
 522 #define FLG_OF1_OVPLATCAP 0x1000000000  /* override CA_SUNW_PLAT capability */
 523 #define FLG_OF1_OVIDCAP 0x2000000000    /* override CA_SUNW_ID capability */
 524 
 525 /*
 526  * Guidance flags. The flags with the FLG_OFG_NO_ prefix are used to suppress
 527  * messages for a given category, and use the lower 28 bits of the word,
 528  * The upper nibble is reserved for other guidance status.
 529  */
 530 #define FLG_OFG_ENABLE          0x10000000      /* -z guidance option active */
 531 #define FLG_OFG_ISSUED          0x20000000      /* -z guidance message issued */
 532 
 533 #define FLG_OFG_NO_ALL          0x0fffffff      /* disable all guidance */
 534 #define FLG_OFG_NO_DEFS         0x00000001      /* specify all dependencies */
 535 #define FLG_OFG_NO_DB           0x00000002      /* use direct bindings */
 536 #define FLG_OFG_NO_LAZY         0x00000004      /* be explicit about lazyload */
 537 #define FLG_OFG_NO_MF           0x00000008      /* use v2 mapfile syntax */
 538 #define FLG_OFG_NO_TEXT         0x00000010      /* verify pure text segment */
 539 #define FLG_OFG_NO_UNUSED       0x00000020      /* remove unused dependency */
 540 
 541 /*
 542  * Test to see if a guidance should be given for a given category
 543  * or not. _no_flag is one of the FLG_OFG_NO_xxx flags. Returns TRUE
 544  * if the guidance should be issued, and FALSE to remain silent.
 545  */
 546 #define OFL_GUIDANCE(_ofl, _no_flag) (((_ofl)->ofl_guideflags & \
 547         (FLG_OFG_ENABLE | (_no_flag))) == FLG_OFG_ENABLE)
 548 
 549 /*
 550  * Test to see if the output file would allow the presence of
 551  * a .dynsym section.
 552  */
 553 #define OFL_ALLOW_DYNSYM(_ofl) (((_ofl)->ofl_flags & \
 554         (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC)
 555 
 556 /*
 557  * Test to see if the output file would allow the presence of
 558  * a .SUNW_ldynsym section. The requirements are that a .dynsym
 559  * is allowed, and -znoldynsym has not been specified. Note that
 560  * even if the answer is True (1), we will only generate one if there
 561  * are local symbols that require it.
 562  */
 563 #define OFL_ALLOW_LDYNSYM(_ofl) (((_ofl)->ofl_flags & \
 564         (FLG_OF_DYNAMIC | FLG_OF_RELOBJ | FLG_OF_NOLDYNSYM)) == FLG_OF_DYNAMIC)
 565 
 566 /*
 567  * Test to see if relocation processing should be done. This is normally
 568  * true, but can be disabled via the '-z noreloc' option. Note that
 569  * relocatable objects are still relocated even if '-z noreloc' is present.
 570  */
 571 #define OFL_DO_RELOC(_ofl) (((_ofl)->ofl_flags & FLG_OF_RELOBJ) || \
 572         !((_ofl)->ofl_dtflags_1 & DF_1_NORELOC))
 573 
 574 /*
 575  * Determine whether a static executable is being built.
 576  */
 577 #define OFL_IS_STATIC_EXEC(_ofl) (((_ofl)->ofl_flags & \
 578         (FLG_OF_STATIC | FLG_OF_EXEC)) == (FLG_OF_STATIC | FLG_OF_EXEC))
 579 
 580 /*
 581  * Determine whether a static object is being built.  This macro is used
 582  * to select the appropriate string table, and symbol table that other
 583  * sections need to reference.
 584  */
 585 #define OFL_IS_STATIC_OBJ(_ofl) ((_ofl)->ofl_flags & \
 586         (FLG_OF_RELOBJ | FLG_OF_STATIC))
 587 
 588 /*
 589  * Macros for counting symbol table entries.  These are used to size symbol
 590  * tables and associated sections (.syminfo, SUNW_capinfo, .hash, etc.) and
 591  * set required sh_info entries (the offset to the first global symbol).
 592  */
 593 #define SYMTAB_LOC_CNT(_ofl)            /* local .symtab entries */     \
 594         (2 +                            /*    NULL and STT_FILE */      \
 595         (_ofl)->ofl_shdrcnt +                /*    section symbol */         \
 596         (_ofl)->ofl_caploclcnt +     /*    local capabilities */     \
 597         (_ofl)->ofl_scopecnt +               /*    scoped symbols */         \
 598         (_ofl)->ofl_locscnt)         /*    standard locals */
 599 #define SYMTAB_ALL_CNT(_ofl)            /* all .symtab entries */       \
 600         (SYMTAB_LOC_CNT(_ofl) +         /*    .symtab locals */         \
 601         (_ofl)->ofl_globcnt)         /*    standard globals */
 602 
 603 #define DYNSYM_LOC_CNT(_ofl)            /* local .dynsym entries */     \
 604         (1 +                            /*    NULL */                   \
 605         (_ofl)->ofl_dynshdrcnt +     /*    section symbols */        \
 606         (_ofl)->ofl_caploclcnt +     /*    local capabilities */     \
 607         (_ofl)->ofl_lregsymcnt)              /*    local register symbols */
 608 #define DYNSYM_ALL_CNT(_ofl)            /* all .dynsym entries */       \
 609         (DYNSYM_LOC_CNT(_ofl) +         /*    .dynsym locals */         \
 610         (_ofl)->ofl_globcnt)         /*    standard globals */
 611 
 612 /*
 613  * Define a move descriptor used within relocation structures.
 614  */
 615 typedef struct {
 616         Move            *mr_move;
 617         Sym_desc        *mr_sym;
 618 } Mv_reloc;
 619 
 620 /*
 621  * Relocation (active & output) processing structure - transparent to common
 622  * code. There can be millions of these structures in a large link, so it
 623  * is important to keep it small. You should only add new items to Rel_desc
 624  * if they are critical, apply to most relocations, and cannot be easily
 625  * computed from the other information.
 626  *
 627  * Items that can be derived should be implemented as a function that accepts
 628  * a Rel_desc argument, and returns the desired data. ld_reloc_sym_name() is
 629  * an example of this.
 630  *
 631  * Lesser used relocation data is kept in an auxiliary block, Rel_aux,
 632  * that is only allocated as necessary. In exchange for adding one pointer
 633  * of overhead to Rel_desc (rel_aux), most relocations are reduced in size
 634  * by the size of Rel_aux. This strategy relies on the data in Rel_aux
 635  * being rarely needed --- otherwise it will backfire badly.
 636  *
 637  * Note that rel_raddend is primarily only of interest to RELA relocations,
 638  * and is set to 0 for REL. However, there is an exception: If FLG_REL_NADDEND
 639  * is set, then rel_raddend contains a replacement value for the implicit
 640  * addend found in the relocation target.
 641  *
 642  * Fields should be ordered from largest to smallest, to minimize packing
 643  * holes in the struct layout.
 644  */
 645 struct rel_desc {
 646         Is_desc         *rel_isdesc;    /* input section reloc is against */
 647         Sym_desc        *rel_sym;       /* sym relocation is against */
 648         Rel_aux         *rel_aux;       /* NULL, or auxiliary data */
 649         Xword           rel_roffset;    /* relocation offset */
 650         Sxword          rel_raddend;    /* addend from input relocation */
 651         Word            rel_flags;      /* misc. flags for relocations */
 652         Word            rel_rtype;      /* relocation type */
 653 };
 654 
 655 /*
 656  * Data that would be kept in Rel_desc if the size of that structure was
 657  * not an issue. This auxiliary block is only allocated as needed,
 658  * and must only contain rarely needed items. The goal is for the vast
 659  * majority of Rel_desc structs to not have an auxiliary block.
 660  *
 661  * When a Rel_desc does not have an auxiliary block, a default value
 662  * is assumed for each auxiliary item:
 663  *
 664  * -    ra_osdesc:
 665  *      Output section to which relocation applies. The default
 666  *      value for this is the output section associated with the
 667  *      input section (rel_isdesc->is_osdesc), or NULL if there
 668  *      is no associated input section.
 669  *
 670  * -    ra_usym:
 671  *      If the symbol associated with a relocation is part of a weak/strong
 672  *      pair, then ra_usym contains the strong symbol and rel_sym the weak.
 673  *      Otherwise, the default value is the same value as rel_sym.
 674  *
 675  * -    ra_move:
 676  *      Move table data. The default value is NULL.
 677  *
 678  * -    ra_typedata:
 679  *      ELF_R_TYPE_DATA(info). This value applies only to a small
 680  *      subset of 64-bit sparc relocations, and is otherwise 0. The
 681  *      default value is 0.
 682  *
 683  * If any value in Rel_aux is non-default, then an auxiliary block is
 684  * necessary, and each field contains its actual value. If all the auxiliary
 685  * values are default, no Rel_aux is needed, and the RELAUX_GET_xxx()
 686  * macros below are able to supply the proper default.
 687  *
 688  * To set a Rel_aux value, use the ld_reloc_set_aux_XXX() functions.
 689  * These functions are written to avoid unnecessary auxiliary allocations,
 690  * and know the rules for each item.
 691  */
 692 struct rel_aux {
 693         Os_desc         *ra_osdesc;     /* output section reloc is against */
 694         Sym_desc        *ra_usym;       /* strong sym if this is a weak pair */
 695         Mv_reloc        *ra_move;       /* move table information */
 696         Word            ra_typedata;    /* ELF_R_TYPE_DATA(info) */
 697 };
 698 
 699 /*
 700  * Test a given auxiliary value to determine if it has the default value
 701  * for that item, as described above. If all the auxiliary items have
 702  * their default values, no auxiliary place is necessary to represent them.
 703  * If any one of them is non-default, the auxiliary block is needed.
 704  */
 705 #define RELAUX_ISDEFAULT_MOVE(_rdesc, _mv) (_mv == NULL)
 706 #define RELAUX_ISDEFAULT_USYM(_rdesc, _usym) ((_rdesc)->rel_sym == _usym)
 707 #define RELAUX_ISDEFAULT_OSDESC(_rdesc, _osdesc) \
 708         ((((_rdesc)->rel_isdesc == NULL) && (_osdesc == NULL)) || \
 709         ((_rdesc)->rel_isdesc && ((_rdesc)->rel_isdesc->is_osdesc == _osdesc)))
 710 #define RELAUX_ISDEFAULT_TYPEDATA(_rdesc, _typedata) (_typedata == 0)
 711 
 712 /*
 713  * Retrieve the value of an auxiliary relocation item, preserving the illusion
 714  * that every relocation descriptor has an auxiliary block attached. The
 715  * real implementation is that an auxiliary block is only present if one or
 716  * more auxiliary items have non-default values. These macros return the true
 717  * value if an auxiliary block is present, and the default value for the
 718  * item otherwise.
 719  */
 720 #define RELAUX_GET_MOVE(_rdesc) \
 721         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_move : NULL)
 722 #define RELAUX_GET_USYM(_rdesc) \
 723         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_usym : (_rdesc)->rel_sym)
 724 #define RELAUX_GET_OSDESC(_rdesc) \
 725         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_osdesc : \
 726         ((_rdesc)->rel_isdesc ? (_rdesc)->rel_isdesc->is_osdesc : NULL))
 727 #define RELAUX_GET_TYPEDATA(_rdesc) \
 728         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_typedata : 0)
 729 
 730 /*
 731  * common flags used on the Rel_desc structure (defined in machrel.h).
 732  */
 733 #define FLG_REL_GOT     0x00000001      /* relocation against GOT */
 734 #define FLG_REL_PLT     0x00000002      /* relocation against PLT */
 735 #define FLG_REL_BSS     0x00000004      /* relocation against BSS */
 736 #define FLG_REL_LOAD    0x00000008      /* section loadable */
 737 #define FLG_REL_SCNNDX  0x00000010      /* use section index for symbol ndx */
 738 #define FLG_REL_CLVAL   0x00000020      /* clear VALUE for active relocation */
 739 #define FLG_REL_ADVAL   0x00000040      /* add VALUE for output relocation, */
 740                                         /*      only relevant to SPARC and */
 741                                         /*      R_SPARC_RELATIVE */
 742 #define FLG_REL_GOTCL   0x00000080      /* clear the GOT entry.  This is */
 743                                         /* relevant to RELA relocations, */
 744                                         /* not REL (i386) relocations */
 745 #define FLG_REL_MOVETAB 0x00000100      /* Relocation against .SUNW_move */
 746                                         /*      adjustments required before */
 747                                         /*      actual relocation */
 748 #define FLG_REL_NOINFO  0x00000200      /* Relocation comes from a section */
 749                                         /*      with a null sh_info field */
 750 #define FLG_REL_REG     0x00000400      /* Relocation target is reg sym */
 751 #define FLG_REL_FPTR    0x00000800      /* relocation against func. desc. */
 752 #define FLG_REL_RFPTR1  0x00001000      /* Relative relocation against */
 753                                         /*   1st part of FD */
 754 #define FLG_REL_RFPTR2  0x00002000      /* Relative relocation against */
 755                                         /*   2nd part of FD */
 756 #define FLG_REL_DISP    0x00004000      /* *disp* relocation */
 757 #define FLG_REL_STLS    0x00008000      /* IE TLS reference to */
 758                                         /*      static TLS GOT index */
 759 #define FLG_REL_DTLS    0x00010000      /* GD TLS reference relative to */
 760                                         /*      dynamic TLS GOT index */
 761 #define FLG_REL_MTLS    0x00020000      /* LD TLS reference against GOT */
 762 #define FLG_REL_STTLS   0x00040000      /* LE TLS reference directly */
 763                                         /*      to static tls index */
 764 #define FLG_REL_TLSFIX  0x00080000      /* relocation points to TLS instr. */
 765                                         /*      which needs updating */
 766 #define FLG_REL_RELA    0x00100000      /* descriptor captures a Rela */
 767 #define FLG_REL_GOTFIX  0x00200000      /* relocation points to GOTOP instr. */
 768                                         /*      which needs updating */
 769 #define FLG_REL_NADDEND 0x00400000      /* Replace implicit addend in dest */
 770                                         /*      with value in rel_raddend */
 771                                         /*      Relevant to REL (i386) */
 772                                         /*      relocations, not to RELA. */
 773 
 774 /*
 775  * We often need the name of the symbol contained in a relocation descriptor
 776  * for diagnostic or error output. This is usually the symbol name, but
 777  * we substitute a constructed name in some cases. Hence, the name is
 778  * generated on the fly by a private function within libld. This is the
 779  * prototype for that function.
 780  */
 781 typedef const char *(* rel_desc_sname_func_t)(Rel_desc *);
 782 
 783 /*
 784  * Header for a relocation descriptor cache buffer.
 785  */
 786 struct rel_cachebuf {
 787         Rel_desc        *rc_end;
 788         Rel_desc        *rc_free;
 789         Rel_desc        rc_arr[1];
 790 };
 791 
 792 /*
 793  * Header for a relocation auxiliary descriptor cache buffer.
 794  */
 795 struct rel_aux_cachebuf {
 796         Rel_aux         *rac_end;
 797         Rel_aux         *rac_free;
 798         Rel_aux         rac_arr[1];
 799 };
 800 
 801 /*
 802  * Convenience macro for traversing every relocation descriptor found within
 803  * a given relocation cache, transparently handling the cache buffers and
 804  * skipping any unallocated descriptors within the buffers.
 805  *
 806  * entry:
 807  *      _rel_cache - Relocate descriptor cache (Rel_cache) to traverse
 808  *      _idx - Aliste index variable for use by the macro
 809  *      _rcbp - Cache buffer pointer, for use by the macro
 810  *      _orsp - Rel_desc pointer, which will take on the value of a different
 811  *              relocation descriptor in the cache in each iteration.
 812  *
 813  * The caller must not assign new values to _idx, _rcbp, or _orsp within
 814  * the scope of REL_CACHE_TRAVERSE.
 815  */
 816 #define REL_CACHE_TRAVERSE(_rel_cache, _idx, _rcbp, _orsp) \
 817         for (APLIST_TRAVERSE((_rel_cache)->rc_list, _idx, _rcbp)) \
 818                 for (_orsp = _rcbp->rc_arr; _orsp < _rcbp->rc_free; _orsp++)
 819 
 820 /*
 821  * Symbol value descriptor.  For relocatable objects, each symbols value is
 822  * its offset within its associated section.  Therefore, to uniquely define
 823  * each symbol within a relocatable object, record and sort the sh_offset and
 824  * symbol value.  This information is used to search for displacement
 825  * relocations as part of copy relocation validation.
 826  */
 827 typedef struct {
 828         Addr            ssv_value;
 829         Sym_desc        *ssv_sdp;
 830 } Ssv_desc;
 831 
 832 /*
 833  * Input file processing structures.
 834  */
 835 struct ifl_desc {                       /* input file descriptor */
 836         const char      *ifl_name;      /* full file name */
 837         const char      *ifl_soname;    /* shared object name */
 838         dev_t           ifl_stdev;      /* device id and inode number for .so */
 839         ino_t           ifl_stino;      /*      multiple inclusion checks */
 840         Ehdr            *ifl_ehdr;      /* elf header describing this file */
 841         Elf             *ifl_elf;       /* elf descriptor for this file */
 842         Sym_desc        **ifl_oldndx;   /* original symbol table indices */
 843         Sym_desc        *ifl_locs;      /* symbol desc version of locals */
 844         Ssv_desc        *ifl_sortsyms;  /* sorted list of symbols by value */
 845         Word            ifl_locscnt;    /* no. of local symbols to process */
 846         Word            ifl_symscnt;    /* total no. of symbols to process */
 847         Word            ifl_sortcnt;    /* no. of sorted symbols to process */
 848         Word            ifl_shnum;      /* number of sections in file */
 849         Word            ifl_shstrndx;   /* index to .shstrtab */
 850         Word            ifl_vercnt;     /* number of versions in file */
 851         Half            ifl_neededndx;  /* index to NEEDED in .dyn section */
 852         Word            ifl_flags;      /* explicit/implicit reference */
 853         Is_desc         **ifl_isdesc;   /* isdesc[scn ndx] = Is_desc ptr */
 854         Sdf_desc        *ifl_sdfdesc;   /* control definition */
 855         Versym          *ifl_versym;    /* version symbol table array */
 856         Ver_index       *ifl_verndx;    /* verndx[ver ndx] = Ver_index */
 857         APlist          *ifl_verdesc;   /* version descriptor list */
 858         APlist          *ifl_relsect;   /* relocation section list */
 859         Alist           *ifl_groups;    /* SHT_GROUP section list */
 860         Cap_desc        *ifl_caps;      /* capabilities descriptor */
 861 };
 862 
 863 #define FLG_IF_CMDLINE  0x00000001      /* full filename specified from the */
 864                                         /*      command line (no -l) */
 865 #define FLG_IF_NEEDED   0x00000002      /* shared object should be recorded */
 866 #define FLG_IF_DIRECT   0x00000004      /* establish direct bindings to this */
 867                                         /*      object */
 868 #define FLG_IF_EXTRACT  0x00000008      /* file extracted from an archive */
 869 #define FLG_IF_VERNEED  0x00000010      /* version dependency information is */
 870                                         /*      required */
 871 #define FLG_IF_DEPREQD  0x00000020      /* dependency is required to satisfy */
 872                                         /*      symbol references */
 873 #define FLG_IF_NEEDSTR  0x00000040      /* dependency specified by -Nn */
 874                                         /*      flag */
 875 #define FLG_IF_IGNORE   0x00000080      /* ignore unused dependencies */
 876 #define FLG_IF_NODIRECT 0x00000100      /* object contains symbols that */
 877                                         /*      cannot be directly bound to */
 878 #define FLG_IF_LAZYLD   0x00000200      /* dependency should be lazy loaded */
 879 #define FLG_IF_GRPPRM   0x00000400      /* dependency establishes a group */
 880 #define FLG_IF_DISPPEND 0x00000800      /* displacement relocation done */
 881                                         /*      in the ld time. */
 882 #define FLG_IF_DISPDONE 0x00001000      /* displacement relocation done */
 883                                         /*      at the run time */
 884 #define FLG_IF_MAPFILE  0x00002000      /* file is a mapfile */
 885 #define FLG_IF_HSTRTAB  0x00004000      /* file has a string section */
 886 #define FLG_IF_FILEREF  0x00008000      /* file contains a section which */
 887                                         /*      is included in the output */
 888                                         /*      allocatable image */
 889 #define FLG_IF_GNUVER   0x00010000      /* file used GNU-style versioning */
 890 #define FLG_IF_ORDERED  0x00020000      /* ordered section processing */
 891                                         /*      required */
 892 #define FLG_IF_OTOSCAP  0x00040000      /* convert object capabilities to */
 893                                         /*      symbol capabilities */
 894 #define FLG_IF_DEFERRED 0x00080000      /* dependency is deferred */
 895 #define FLG_IF_RTLDINF  0x00100000      /* dependency has DT_SUNW_RTLTINF set */
 896 #define FLG_IF_GROUPS   0x00200000      /* input file has groups to process */
 897 
 898 /*
 899  * Symbol states that require the generation of a DT_POSFLAG_1 .dynamic entry.
 900  */
 901 #define MSK_IF_POSFLAG1 (FLG_IF_LAZYLD | FLG_IF_GRPPRM | FLG_IF_DEFERRED)
 902 
 903 /*
 904  * Symbol states that require an associated Syminfo entry.
 905  */
 906 #define MSK_IF_SYMINFO  (FLG_IF_LAZYLD | FLG_IF_DIRECT | FLG_IF_DEFERRED)
 907 
 908 
 909 struct is_desc {                        /* input section descriptor */
 910         const char      *is_name;       /* original section name */
 911         const char      *is_sym_name;   /* NULL, or name string to use for */
 912                                         /*      related STT_SECTION symbols */
 913         Shdr            *is_shdr;       /* the elf section header */
 914         Ifl_desc        *is_file;       /* infile desc for this section */
 915         Os_desc         *is_osdesc;     /* new output section for this */
 916                                         /*      input section */
 917         Elf_Data        *is_indata;     /* input sections raw data */
 918         Is_desc         *is_symshndx;   /* related SHT_SYM_SHNDX section */
 919         Is_desc         *is_comdatkeep; /* If COMDAT section is discarded, */
 920                                         /*      this is section that was kept */
 921         Word            is_scnndx;      /* original section index in file */
 922         Word            is_ordndx;      /* index for section.  Used to decide */
 923                                         /*      where to insert section when */
 924                                         /*      reordering sections */
 925         Word            is_keyident;    /* key for SHF_{ORDERED|LINK_ORDER} */
 926                                         /*      processing and ident used for */
 927                                         /*       placing/ordering sections */
 928         Word            is_flags;       /* Various flags */
 929 };
 930 
 931 #define FLG_IS_ORDERED  0x0001          /* this is a SHF_ORDERED section */
 932 #define FLG_IS_KEY      0x0002          /* section requires sort keys */
 933 #define FLG_IS_DISCARD  0x0004          /* section is to be discarded */
 934 #define FLG_IS_RELUPD   0x0008          /* symbol defined here may have moved */
 935 #define FLG_IS_SECTREF  0x0010          /* section has been referenced */
 936 #define FLG_IS_GDATADEF 0x0020          /* section contains global data sym */
 937 #define FLG_IS_EXTERNAL 0x0040          /* isp from a user file */
 938 #define FLG_IS_INSTRMRG 0x0080          /* Usable SHF_MERGE|SHF_STRINGS sec */
 939 #define FLG_IS_GNSTRMRG 0x0100          /* Generated mergeable string section */
 940 
 941 #define FLG_IS_PLACE    0x0400          /* section requires to be placed */
 942 #define FLG_IS_COMDAT   0x0800          /* section is COMDAT */
 943 #define FLG_IS_EHFRAME  0x1000          /* section is .eh_frame */
 944 
 945 /*
 946  * Output sections contain lists of input sections that are assigned to them.
 947  * These items fall into 4 categories:
 948  *      BEFORE - Ordered sections that specify SHN_BEFORE, in input order.
 949  *      ORDERED - Ordered sections that are sorted using unsorted sections
 950  *              as the sort key.
 951  *      DEFAULT - Sections that are placed into the output section
 952  *              in input order.
 953  *      AFTER - Ordered sections that specify SHN_AFTER, in input order.
 954  */
 955 #define OS_ISD_BEFORE   0
 956 #define OS_ISD_ORDERED  1
 957 #define OS_ISD_DEFAULT  2
 958 #define OS_ISD_AFTER    3
 959 #define OS_ISD_NUM      4
 960 typedef APlist *os_isdecs_arr[OS_ISD_NUM];
 961 
 962 /*
 963  * Convenience macro for traversing every input section associated
 964  * with a given output section. The primary benefit of this macro
 965  * is that it preserves a precious level of code indentation in the
 966  * code that uses it.
 967  */
 968 #define OS_ISDESCS_TRAVERSE(_list_idx, _osp, _idx, _isp) \
 969         for (_list_idx = 0; _list_idx < OS_ISD_NUM; _list_idx++) \
 970                 for (APLIST_TRAVERSE(_osp->os_isdescs[_list_idx], _idx, _isp))
 971 
 972 
 973 /*
 974  * Map file and output file processing structures
 975  */
 976 struct os_desc {                        /* Output section descriptor */
 977         const char      *os_name;       /* the section name */
 978         Elf_Scn         *os_scn;        /* the elf section descriptor */
 979         Shdr            *os_shdr;       /* the elf section header */
 980         Os_desc         *os_relosdesc;  /* the output relocation section */
 981         APlist          *os_relisdescs; /* reloc input section descriptors */
 982                                         /*      for this output section */
 983         os_isdecs_arr   os_isdescs;     /* lists of input sections in output */
 984         APlist          *os_mstrisdescs; /* FLG_IS_INSTRMRG input sections */
 985         Sg_desc         *os_sgdesc;     /* segment os_desc is placed on */
 986         Elf_Data        *os_outdata;    /* output sections raw data */
 987         avl_tree_t      *os_comdats;    /* AVL tree of COMDAT input sections */
 988                                         /*      associated to output section */
 989         Word            os_identndx;    /* section identifier for input */
 990                                         /*      section processing, followed */
 991                                         /*      by section symbol index */
 992         Word            os_ordndx;      /* index for section.  Used to decide */
 993                                         /*      where to insert section when */
 994                                         /*      reordering sections */
 995         Xword           os_szoutrels;   /* size of output relocation section */
 996         uint_t          os_namehash;    /* hash on section name */
 997         uchar_t         os_flags;       /* various flags */
 998 };
 999 
1000 #define FLG_OS_KEY              0x01    /* section requires sort keys */
1001 #define FLG_OS_OUTREL           0x02    /* output rel against this section */
1002 #define FLG_OS_SECTREF          0x04    /* isps are not affected by -zignore */
1003 #define FLG_OS_EHFRAME          0x08    /* section is .eh_frame */
1004 
1005 /*
1006  * The sg_id field of the segment descriptor is used to establish the default
1007  * order for program headers and segments in the output object. Segments are
1008  * ordered according to the following SGID values that classify them based on
1009  * their attributes. The initial set of built in segments are in this order,
1010  * and new mapfile defined segments are inserted into these groups. Within a
1011  * given SGID group, the position of new segments depends on the syntax
1012  * version of the mapfile that creates them. Version 1 (original sysv)
1013  * mapfiles place the new segment at the head of their group (reverse creation
1014  * order). The newer syntax places them at the end, following the others
1015  * (creation order).
1016  *
1017  * Note that any new segments must always be added after PT_PHDR and
1018  * PT_INTERP (refer Generic ABI, Page 5-4).
1019  */
1020 #define SGID_PHDR       0       /* PT_PHDR */
1021 #define SGID_INTERP     1       /* PT_INTERP */
1022 #define SGID_SUNWCAP    2       /* PT_SUNWCAP */
1023 #define SGID_TEXT       3       /* PT_LOAD */
1024 #define SGID_DATA       4       /* PT_LOAD */
1025 #define SGID_BSS        5       /* PT_LOAD */
1026 #if     defined(_ELF64)
1027 #define SGID_LRODATA    6       /* PT_LOAD (amd64-only) */
1028 #define SGID_LDATA      7       /* PT_LOAD (amd64-only) */
1029 #endif
1030 #define SGID_TEXT_EMPTY 8       /* PT_LOAD, reserved (?E in version 1 syntax) */
1031 #define SGID_NULL_EMPTY 9       /* PT_NULL, reserved (?E in version 1 syntax) */
1032 #define SGID_DYN        10      /* PT_DYNAMIC */
1033 #define SGID_DTRACE     11      /* PT_SUNWDTRACE */
1034 #define SGID_TLS        12      /* PT_TLS */
1035 #define SGID_UNWIND     13      /* PT_SUNW_UNWIND */
1036 #define SGID_SUNWSTACK  14      /* PT_SUNWSTACK */
1037 #define SGID_NOTE       15      /* PT_NOTE */
1038 #define SGID_NULL       16      /* PT_NULL,  mapfile defined empty phdr slots */
1039                                 /*      for use by post processors */
1040 #define SGID_EXTRA      17      /* PT_NULL (final catchall) */
1041 
1042 typedef Half sg_flags_t;
1043 struct sg_desc {                        /* output segment descriptor */
1044         Word            sg_id;          /* segment identifier (for sorting) */
1045         Phdr            sg_phdr;        /* segment header for output file */
1046         const char      *sg_name;       /* segment name for PT_LOAD, PT_NOTE, */
1047                                         /*      and PT_NULL, otherwise NULL */
1048         Xword           sg_round;       /* data rounding required (mapfile) */
1049         Xword           sg_length;      /* maximum segment length; if 0 */
1050                                         /*      segment is not specified */
1051         APlist          *sg_osdescs;    /* list of output section descriptors */
1052         APlist          *sg_is_order;   /* list of entry criteria */
1053                                         /*      giving input section order */
1054         Alist           *sg_os_order;   /* list specifying output section */
1055                                         /*      ordering for the segment */
1056         sg_flags_t      sg_flags;
1057         APlist          *sg_sizesym;    /* size symbols for this segment */
1058         Xword           sg_align;       /* LCM of sh_addralign */
1059         Elf_Scn         *sg_fscn;       /* the SCN of the first section. */
1060         avl_node_t      sg_avlnode;     /* AVL book-keeping */
1061 };
1062 
1063 #define FLG_SG_P_VADDR          0x0001  /* p_vaddr segment attribute set */
1064 #define FLG_SG_P_PADDR          0x0002  /* p_paddr segment attribute set */
1065 #define FLG_SG_LENGTH           0x0004  /* length segment attribute set */
1066 #define FLG_SG_P_ALIGN          0x0008  /* p_align segment attribute set */
1067 #define FLG_SG_ROUND            0x0010  /* round segment attribute set */
1068 #define FLG_SG_P_FLAGS          0x0020  /* p_flags segment attribute set */
1069 #define FLG_SG_P_TYPE           0x0040  /* p_type segment attribute set */
1070 #define FLG_SG_IS_ORDER         0x0080  /* input section ordering is required */
1071                                         /*      for this segment. */
1072 #define FLG_SG_NOHDR            0x0100  /* don't map ELF or phdrs into */
1073                                         /*      this segment */
1074 #define FLG_SG_EMPTY            0x0200  /* an empty segment specification */
1075                                         /*      no input sections will be */
1076                                         /*      associated to this section */
1077 #define FLG_SG_KEY              0x0400  /* segment requires sort keys */
1078 #define FLG_SG_NODISABLE        0x0800  /* FLG_SG_DISABLED is not allowed on */
1079                                         /*      this segment */
1080 #define FLG_SG_DISABLED         0x1000  /* this segment is disabled */
1081 #define FLG_SG_PHREQ            0x2000  /* this segment requires a program */
1082                                         /* header */
1083 #define FLG_SG_ORDERED          0x4000  /* SEGMENT_ORDER segment */
1084 
1085 struct sec_order {
1086         const char      *sco_secname;   /* section name to be ordered */
1087         Half            sco_flags;
1088 };
1089 
1090 #define FLG_SGO_USED    0x0001          /* was ordering used? */
1091 
1092 typedef Half ec_flags_t;
1093 struct ent_desc {                       /* input section entrance criteria */
1094         const char      *ec_name;       /* entrace criteria name, or NULL */
1095         Alist           *ec_files;      /* files from which to accept */
1096                                         /*      sections */
1097         const char      *ec_is_name;    /* input section name to match */
1098                                         /*      (NULL if none) */
1099         Word            ec_type;        /* section type */
1100         Word            ec_attrmask;    /* section attribute mask (AWX) */
1101         Word            ec_attrbits;    /* sections attribute bits */
1102         Sg_desc         *ec_segment;    /* output segment to enter if matched */
1103         Word            ec_ordndx;      /* index to determine where section */
1104                                         /*      meeting this criteria should */
1105                                         /*      inserted. Used for reordering */
1106                                         /*      of sections. */
1107         ec_flags_t      ec_flags;
1108         avl_node_t      ec_avlnode;     /* AVL book-keeping */
1109 };
1110 
1111 #define FLG_EC_BUILTIN  0x0001          /* built in descriptor */
1112 #define FLG_EC_USED     0x0002          /* entrance criteria met? */
1113 #define FLG_EC_CATCHALL 0x0004          /* Catches any section */
1114 
1115 /*
1116  * Ent_desc_file is the type of element maintained in the ec_files Alist
1117  * of an entrance criteria descriptor. Each item maintains one file
1118  * path, and a set of flags that specify the type of comparison it implies,
1119  * and other information about it. The comparison type is maintained in
1120  * the bottom byte of the flags.
1121  */
1122 #define TYP_ECF_MASK            0x00ff  /* Comparison type mask */
1123 #define TYP_ECF_PATH            0       /* Compare to file path */
1124 #define TYP_ECF_BASENAME        1       /* Compare to file basename */
1125 #define TYP_ECF_OBJNAME         2       /* Compare to regular file basename, */
1126                                         /*       or to archive member name */
1127 #define TYP_ECF_NUM             3
1128 
1129 #define FLG_ECF_ARMEMBER        0x0100  /* name includes archive member */
1130 
1131 typedef struct {
1132         Word            edf_flags;      /* Type of comparison */
1133         const char      *edf_name;      /* String to compare to */
1134         size_t          edf_name_len;   /* strlen(edf_name) */
1135 } Ent_desc_file;
1136 
1137 /*
1138  * One structure is allocated for a move entry, and associated to the symbol
1139  * against which a move is targeted.
1140  */
1141 typedef struct {
1142         Move            *md_move;       /* original Move entry */
1143         Xword           md_start;       /* start position */
1144         Xword           md_len;         /* length of initialization */
1145         Word            md_oidx;        /* output Move entry index */
1146 } Mv_desc;
1147 
1148 /*
1149  * Symbol descriptor.
1150  */
1151 typedef Lword           sd_flag_t;
1152 struct sym_desc {
1153         Alist           *sd_GOTndxs;    /* list of associated GOT entries */
1154         Sym             *sd_sym;        /* pointer to symbol table entry */
1155         Sym             *sd_osym;       /* copy of the original symbol entry */
1156                                         /*      used only for local partial */
1157         Alist           *sd_move;       /* move information associated with a */
1158                                         /*      partially initialized symbol */
1159         const char      *sd_name;       /* symbols name */
1160         Ifl_desc        *sd_file;       /* file where symbol is taken */
1161         Is_desc         *sd_isc;        /* input section of symbol definition */
1162         Sym_aux         *sd_aux;        /* auxiliary global symbol info. */
1163         Word            sd_symndx;      /* index in output symbol table */
1164         Word            sd_shndx;       /* sect. index sym is associated w/ */
1165         sd_flag_t       sd_flags;       /* state flags */
1166         Half            sd_ref;         /* reference definition of symbol */
1167 };
1168 
1169 /*
1170  * The auxiliary symbol descriptor contains the additional information (beyond
1171  * the symbol descriptor) required to process global symbols.  These symbols are
1172  * accessed via an internal symbol hash table where locality of reference is
1173  * important for performance.
1174  */
1175 struct sym_aux {
1176         APlist          *sa_dfiles;     /* files where symbol is defined */
1177         Sym             sa_sym;         /* copy of symtab entry */
1178         const char      *sa_vfile;      /* first unavailable definition */
1179         const char      *sa_rfile;      /* file with first symbol referenced */
1180         Word            sa_hash;        /* the pure hash value of symbol */
1181         Word            sa_PLTndx;      /* index into PLT for symbol */
1182         Word            sa_PLTGOTndx;   /* GOT entry indx for PLT indirection */
1183         Word            sa_linkndx;     /* index of associated symbol from */
1184                                         /*      ET_DYN file */
1185         Half            sa_symspec;     /* special symbol ids */
1186         Half            sa_overndx;     /* output file versioning index */
1187         Half            sa_dverndx;     /* dependency versioning index */
1188 };
1189 
1190 /*
1191  * Nodes used to track symbols in the global AVL symbol dictionary.
1192  */
1193 struct sym_avlnode {
1194         avl_node_t      sav_node;       /* AVL node */
1195         Word            sav_hash;       /* symbol hash value */
1196         const char      *sav_name;      /* symbol name */
1197         Sym_desc        *sav_sdp;       /* symbol descriptor */
1198 };
1199 
1200 /*
1201  * These are the ids for processing of `Special symbols'.  They are used
1202  * to set the sym->sd_aux->sa_symspec field.
1203  */
1204 #define SDAUX_ID_ETEXT  1               /* etext && _etext symbol */
1205 #define SDAUX_ID_EDATA  2               /* edata && _edata symbol */
1206 #define SDAUX_ID_END    3               /* end, _end, && _END_ symbol */
1207 #define SDAUX_ID_DYN    4               /* DYNAMIC && _DYNAMIC symbol */
1208 #define SDAUX_ID_PLT    5               /* _PROCEDURE_LINKAGE_TABLE_ symbol */
1209 #define SDAUX_ID_GOT    6               /* _GLOBAL_OFFSET_TABLE_ symbol */
1210 #define SDAUX_ID_START  7               /* START_ && _START_ symbol */
1211 
1212 /*
1213  * Flags for sym_desc.sd_flags
1214  */
1215 #define FLG_SY_MVTOCOMM 0x00000001      /* assign symbol to common (.bss) */
1216                                         /*      this is a result of a */
1217                                         /*      copy reloc against sym */
1218 #define FLG_SY_GLOBREF  0x00000002      /* a global reference has been seen */
1219 #define FLG_SY_WEAKDEF  0x00000004      /* a weak definition has been used */
1220 #define FLG_SY_CLEAN    0x00000008      /* `Sym' entry points to original */
1221                                         /*      input file (read-only). */
1222 #define FLG_SY_UPREQD   0x00000010      /* symbol value update is required, */
1223                                         /*      either it's used as an entry */
1224                                         /*      point or for relocation, but */
1225                                         /*      it must be updated even if */
1226                                         /*      the -s flag is in effect */
1227 #define FLG_SY_NOTAVAIL 0x00000020      /* symbol is not available to the */
1228                                         /*      application either because it */
1229                                         /*      originates from an implicitly */
1230                                         /*      referenced shared object, or */
1231                                         /*      because it is not part of a */
1232                                         /*      specified version. */
1233 #define FLG_SY_REDUCED  0x00000040      /* a global is reduced to local */
1234 #define FLG_SY_VERSPROM 0x00000080      /* version definition has been */
1235                                         /*      promoted to output file */
1236 #define FLG_SY_PROT     0x00000100      /* stv_protected visibility seen */
1237 #define FLG_SY_MAPREF   0x00000200      /* symbol reference generated by user */
1238                                         /*      from mapfile */
1239 #define FLG_SY_REFRSD   0x00000400      /* symbols sd_ref has been raised */
1240                                         /*      due to a copy-relocs */
1241                                         /*      weak-strong pairing */
1242 #define FLG_SY_INTPOSE  0x00000800      /* symbol defines an interposer */
1243 #define FLG_SY_INVALID  0x00001000      /* unwanted/erroneous symbol */
1244 #define FLG_SY_SMGOT    0x00002000      /* small got index assigned to symbol */
1245                                         /*      sparc only */
1246 #define FLG_SY_PARENT   0x00004000      /* symbol to be found in parent */
1247                                         /*    only used with direct bindings */
1248 #define FLG_SY_LAZYLD   0x00008000      /* symbol to cause lazyloading of */
1249                                         /*      parent object */
1250 #define FLG_SY_ISDISC   0x00010000      /* symbol is a member of a DISCARDED */
1251                                         /*      section (COMDAT) */
1252 #define FLG_SY_PAREXPN  0x00020000      /* partially init. symbol to be */
1253                                         /*      expanded */
1254 #define FLG_SY_PLTPAD   0x00040000      /* pltpadding has been allocated for */
1255                                         /*      this symbol */
1256 #define FLG_SY_REGSYM   0x00080000      /* REGISTER symbol (sparc only) */
1257 #define FLG_SY_SOFOUND  0x00100000      /* compared against an SO definition */
1258 #define FLG_SY_EXTERN   0x00200000      /* symbol is external, allows -zdefs */
1259                                         /*    error suppression */
1260 #define FLG_SY_MAPUSED  0x00400000      /* mapfile symbol used (occurred */
1261                                         /*    within a relocatable object) */
1262 #define FLG_SY_COMMEXP  0x00800000      /* COMMON symbol which has been */
1263                                         /*      allocated */
1264 #define FLG_SY_CMDREF   0x01000000      /* symbol was referenced from the */
1265                                         /*      command line.  (ld -u <>, */
1266                                         /*      ld -zrtldinfo=<>, ...) */
1267 #define FLG_SY_SPECSEC  0x02000000      /* section index is reserved value */
1268                                         /*      ABS, COMMON, ... */
1269 #define FLG_SY_TENTSYM  0x04000000      /* tentative symbol */
1270 #define FLG_SY_VISIBLE  0x08000000      /* symbols visibility determined */
1271 #define FLG_SY_STDFLTR  0x10000000      /* symbol is a standard filter */
1272 #define FLG_SY_AUXFLTR  0x20000000      /* symbol is an auxiliary filter */
1273 #define FLG_SY_DYNSORT  0x40000000      /* req. in dyn[sym|tls]sort section */
1274 #define FLG_SY_NODYNSORT 0x80000000     /* excluded from dyn[sym_tls]sort sec */
1275 
1276 #define FLG_SY_DEFAULT  0x0000100000000 /* global symbol, default */
1277 #define FLG_SY_SINGLE   0x0000200000000 /* global symbol, singleton defined */
1278 #define FLG_SY_PROTECT  0x0000400000000 /* global symbol, protected defined */
1279 #define FLG_SY_EXPORT   0x0000800000000 /* global symbol, exported defined */
1280 
1281 #define MSK_SY_GLOBAL \
1282         (FLG_SY_DEFAULT | FLG_SY_SINGLE | FLG_SY_PROTECT | FLG_SY_EXPORT)
1283                                         /* this mask indicates that the */
1284                                         /*    symbol has been explicitly */
1285                                         /*    defined within a mapfile */
1286                                         /*    definition, and is a candidate */
1287                                         /*    for versioning */
1288 
1289 #define FLG_SY_HIDDEN   0x0001000000000 /* global symbol, reduce to local */
1290 #define FLG_SY_ELIM     0x0002000000000 /* global symbol, eliminate */
1291 #define FLG_SY_IGNORE   0x0004000000000 /* global symbol, ignored */
1292 
1293 #define MSK_SY_LOCAL    (FLG_SY_HIDDEN | FLG_SY_ELIM | FLG_SY_IGNORE)
1294                                         /* this mask allows all local state */
1295                                         /*    flags to be removed when the */
1296                                         /*    symbol is copy relocated */
1297 
1298 #define FLG_SY_EXPDEF   0x0008000000000 /* symbol visibility defined */
1299                                         /*    explicitly */
1300 
1301 #define MSK_SY_NOAUTO   (FLG_SY_SINGLE | FLG_SY_EXPORT | FLG_SY_EXPDEF)
1302                                         /* this mask indicates that the */
1303                                         /*    symbol is not a candidate for */
1304                                         /*    auto-reduction/elimination */
1305 
1306 #define FLG_SY_MAPFILE  0x0010000000000 /* symbol attribute defined in a */
1307                                         /*    mapfile */
1308 #define FLG_SY_DIR      0x0020000000000 /* global symbol, direct bindings */
1309 #define FLG_SY_NDIR     0x0040000000000 /* global symbol, nondirect bindings */
1310 #define FLG_SY_OVERLAP  0x0080000000000 /* move entry overlap detected */
1311 #define FLG_SY_CAP      0x0100000000000 /* symbol is associated with */
1312                                         /*    capabilities */
1313 #define FLG_SY_DEFERRED 0x0200000000000 /* symbol should not be bound to */
1314                                         /*      during BIND_NOW relocations */
1315 
1316 /*
1317  * A symbol can only be truly hidden if it is not a capabilities symbol.
1318  */
1319 #define SYM_IS_HIDDEN(_sdp) \
1320         (((_sdp)->sd_flags & (FLG_SY_HIDDEN | FLG_SY_CAP)) == FLG_SY_HIDDEN)
1321 
1322 /*
1323  * Create a mask for (sym.st_other & visibility) since the gABI does not yet
1324  * define a ELF*_ST_OTHER macro.
1325  */
1326 #define MSK_SYM_VISIBILITY      0x7
1327 
1328 /*
1329  * Structure to manage the shared object definition lists.  There are two lists
1330  * that use this structure:
1331  *
1332  *  -   ofl_soneed; maintain the list of implicitly required dependencies
1333  *      (ie. shared objects needed by other shared objects).  These definitions
1334  *      may include RPATH's required to locate the dependencies, and any
1335  *      version requirements.
1336  *
1337  *  -   ofl_socntl; maintains the shared object control definitions.  These are
1338  *      provided by the user (via a mapfile) and are used to indicate any
1339  *      version control requirements.
1340  */
1341 struct  sdf_desc {
1342         const char      *sdf_name;      /* the shared objects file name */
1343         char            *sdf_rpath;     /* library search path DT_RPATH */
1344         const char      *sdf_rfile;     /* referencing file for diagnostics */
1345         Ifl_desc        *sdf_file;      /* the final input file descriptor */
1346         Alist           *sdf_vers;      /* list of versions that are required */
1347                                         /*      from this object */
1348         Alist           *sdf_verneed;   /* list of VERNEEDS to create for */
1349                                         /*      object via mapfile ADDVERS */
1350         Word            sdf_flags;
1351 };
1352 
1353 #define FLG_SDF_SELECT  0x01            /* version control selection required */
1354 #define FLG_SDF_VERIFY  0x02            /* version definition verification */
1355                                         /*      required */
1356 #define FLG_SDF_ADDVER  0x04            /* add VERNEED references */
1357 
1358 /*
1359  * Structure to manage shared object version usage requirements.
1360  */
1361 struct  sdv_desc {
1362         const char      *sdv_name;      /* version name */
1363         const char      *sdv_ref;       /* versions reference */
1364         Word            sdv_flags;      /* flags */
1365 };
1366 
1367 #define FLG_SDV_MATCHED 0x01            /* VERDEF found and matched */
1368 
1369 /*
1370  * Structures to manage versioning information.  Two versioning structures are
1371  * defined:
1372  *
1373  *   -  a version descriptor maintains a linked list of versions and their
1374  *      associated dependencies.  This is used to build the version definitions
1375  *      for an image being created (see map_symbol), and to determine the
1376  *      version dependency graph for any input files that are versioned.
1377  *
1378  *   -  a version index array contains each version of an input file that is
1379  *      being processed.  It informs us which versions are available for
1380  *      binding, and is used to generate any version dependency information.
1381  */
1382 struct  ver_desc {
1383         const char      *vd_name;       /* version name */
1384         Ifl_desc        *vd_file;       /* file that defined version */
1385         Word            vd_hash;        /* hash value of name */
1386         Half            vd_ndx;         /* coordinates with symbol index */
1387         Half            vd_flags;       /* version information */
1388         APlist          *vd_deps;       /* version dependencies */
1389         Ver_desc        *vd_ref;        /* dependency's first reference */
1390 };
1391 
1392 struct  ver_index {
1393         const char      *vi_name;       /* dependency version name */
1394         Half            vi_flags;       /* communicates availability */
1395         Half            vi_overndx;     /* index assigned to this version in */
1396                                         /*      output object Verneed section */
1397         Ver_desc        *vi_desc;       /* cross reference to descriptor */
1398 };
1399 
1400 /*
1401  * Define any internal version descriptor flags ([vd|vi]_flags).  Note that the
1402  * first byte is reserved for user visible flags (refer VER_FLG's in link.h).
1403  */
1404 #define MSK_VER_USER    0x0f            /* mask for user visible flags */
1405 
1406 #define FLG_VER_AVAIL   0x10            /* version is available for binding */
1407 #define FLG_VER_REFER   0x20            /* version has been referenced */
1408 #define FLG_VER_CYCLIC  0x40            /* a member of cyclic dependency */
1409 
1410 /*
1411  * isalist(1) descriptor - used to break an isalist string into its component
1412  * options.
1413  */
1414 struct  isa_opt {
1415         char            *isa_name;      /* individual isa option name */
1416         size_t          isa_namesz;     /*      and associated size */
1417 };
1418 
1419 struct  isa_desc {
1420         char            *isa_list;      /* sysinfo(SI_ISALIST) list */
1421         size_t          isa_listsz;     /*      and associated size */
1422         Isa_opt         *isa_opt;       /* table of individual isa options */
1423         size_t          isa_optno;      /*      and associated number */
1424 };
1425 
1426 /*
1427  * uname(2) descriptor - used to break a utsname structure into its component
1428  * options (at least those that we're interested in).
1429  */
1430 struct  uts_desc {
1431         char            *uts_osname;    /* operating system name */
1432         size_t          uts_osnamesz;   /*      and associated size */
1433         char            *uts_osrel;     /* operating system release */
1434         size_t          uts_osrelsz;    /*      and associated size */
1435 };
1436 
1437 /*
1438  * SHT_GROUP descriptor - used to track group sections at the global
1439  * level to resolve conflicts and determine which to keep.
1440  */
1441 struct group_desc {
1442         Is_desc         *gd_isc;        /* input section descriptor */
1443         Is_desc         *gd_oisc;       /* overriding input section */
1444                                         /*      descriptor when discarded */
1445         const char      *gd_name;       /* group name (signature symbol) */
1446         Word            *gd_data;       /* data for group section */
1447         size_t          gd_cnt;         /* number of entries in group data */
1448 };
1449 
1450 /*
1451  * Indexes into the ld_support_funcs[] table.
1452  */
1453 typedef enum {
1454         LDS_VERSION = 0,        /* Must be first and have value 0 */
1455         LDS_INPUT_DONE,
1456         LDS_START,
1457         LDS_ATEXIT,
1458         LDS_OPEN,
1459         LDS_FILE,
1460         LDS_INSEC,
1461         LDS_SEC,
1462         LDS_NUM
1463 } Support_ndx;
1464 
1465 /*
1466  * Structure to manage archive member caching.  Each archive has an archive
1467  * descriptor (Ar_desc) associated with it.  This contains pointers to the
1468  * archive symbol table (obtained by elf_getarsyms(3e)) and an auxiliary
1469  * structure (Ar_uax[]) that parallels this symbol table.  The member element
1470  * of this auxiliary table indicates whether the archive member associated with
1471  * the symbol offset has already been extracted (AREXTRACTED) or partially
1472  * processed (refer process_member()).
1473  */
1474 typedef struct ar_mem {
1475         Elf             *am_elf;        /* elf descriptor for this member */
1476         const char      *am_name;       /* members name */
1477         const char      *am_path;       /* path (ie. lib(foo.o)) */
1478         Sym             *am_syms;       /* start of global symbols */
1479         char            *am_strs;       /* associated string table start */
1480         Xword           am_symn;        /* no. of global symbols */
1481 } Ar_mem;
1482 
1483 typedef struct ar_aux {
1484         Sym_desc        *au_syms;       /* internal symbol descriptor */
1485         Ar_mem          *au_mem;        /* associated member */
1486 } Ar_aux;
1487 
1488 #define FLG_ARMEM_PROC  (Ar_mem *)-1
1489 
1490 typedef struct ar_desc {
1491         const char      *ad_name;       /* archive file name */
1492         Elf             *ad_elf;        /* elf descriptor for the archive */
1493         Elf_Arsym       *ad_start;      /* archive symbol table start */
1494         Ar_aux          *ad_aux;        /* auxiliary symbol information */
1495         dev_t           ad_stdev;       /* device id and inode number for */
1496         ino_t           ad_stino;       /*      multiple inclusion checks */
1497         ofl_flag_t      ad_flags;       /* archive specific cmd line flags */
1498 } Ar_desc;
1499 
1500 /*
1501  * Define any archive descriptor flags.  NOTE, make sure they do not clash with
1502  * any output file descriptor archive extraction flags, as these are saved in
1503  * the same entry (see MSK_OF1_ARCHIVE).
1504  */
1505 #define FLG_ARD_EXTRACT 0x00010000      /* archive member has been extracted */
1506 
1507 /* Mapfile versions supported by libld */
1508 #define MFV_NONE        0       /* Not a valid version */
1509 #define MFV_SYSV        1       /* Original System V syntax */
1510 #define MFV_SOLARIS     2       /* Solaris mapfile syntax */
1511 #define MFV_NUM         3       /* # of mapfile versions */
1512 
1513 
1514 /*
1515  * Function Declarations.
1516  */
1517 #if     defined(_ELF64)
1518 
1519 #define ld_create_outfile       ld64_create_outfile
1520 #define ld_ent_setup            ld64_ent_setup
1521 #define ld_init_strings         ld64_init_strings
1522 #define ld_init_target          ld64_init_target
1523 #define ld_make_sections        ld64_make_sections
1524 #define ld_main                 ld64_main
1525 #define ld_ofl_cleanup          ld64_ofl_cleanup
1526 #define ld_process_mem          ld64_process_mem
1527 #define ld_reloc_init           ld64_reloc_init
1528 #define ld_reloc_process        ld64_reloc_process
1529 #define ld_sym_validate         ld64_sym_validate
1530 #define ld_update_outfile       ld64_update_outfile
1531 
1532 #else
1533 
1534 #define ld_create_outfile       ld32_create_outfile
1535 #define ld_ent_setup            ld32_ent_setup
1536 #define ld_init_strings         ld32_init_strings
1537 #define ld_init_target          ld32_init_target
1538 #define ld_make_sections        ld32_make_sections
1539 #define ld_main                 ld32_main
1540 #define ld_ofl_cleanup          ld32_ofl_cleanup
1541 #define ld_process_mem          ld32_process_mem
1542 #define ld_reloc_init           ld32_reloc_init
1543 #define ld_reloc_process        ld32_reloc_process
1544 #define ld_sym_validate         ld32_sym_validate
1545 #define ld_update_outfile       ld32_update_outfile
1546 
1547 #endif
1548 
1549 extern int              ld_getopt(Lm_list *, int, int, char **);
1550 
1551 extern int              ld32_main(int, char **, Half);
1552 extern int              ld64_main(int, char **, Half);
1553 
1554 extern uintptr_t        ld_create_outfile(Ofl_desc *);
1555 extern uintptr_t        ld_ent_setup(Ofl_desc *, Xword);
1556 extern uintptr_t        ld_init_strings(Ofl_desc *);
1557 extern int              ld_init_target(Lm_list *, Half mach);
1558 extern uintptr_t        ld_make_sections(Ofl_desc *);
1559 extern void             ld_ofl_cleanup(Ofl_desc *);
1560 extern Ifl_desc         *ld_process_mem(const char *, const char *, char *,
1561                             size_t, Ofl_desc *, Rej_desc *);
1562 extern uintptr_t        ld_reloc_init(Ofl_desc *);
1563 extern uintptr_t        ld_reloc_process(Ofl_desc *);
1564 extern uintptr_t        ld_sym_validate(Ofl_desc *);
1565 extern uintptr_t        ld_update_outfile(Ofl_desc *);
1566 
1567 #ifdef  __cplusplus
1568 }
1569 #endif
1570 
1571 #endif  /* _LIBLD_H */