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