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 };
 410 
 411 #define FLG_OF_DYNAMIC  0x00000001      /* generate dynamic output module */
 412 #define FLG_OF_STATIC   0x00000002      /* generate static output module */
 413 #define FLG_OF_EXEC     0x00000004      /* generate an executable */
 414 #define FLG_OF_RELOBJ   0x00000008      /* generate a relocatable object */
 415 #define FLG_OF_SHAROBJ  0x00000010      /* generate a shared object */
 416 #define FLG_OF_BFLAG    0x00000020      /* do no special plt building: -b */
 417 #define FLG_OF_IGNENV   0x00000040      /* ignore LD_LIBRARY_PATH: -i */
 418 #define FLG_OF_STRIP    0x00000080      /* strip output: -s */
 419 #define FLG_OF_NOWARN   0x00000100      /* disable symbol warnings: -t */
 420 #define FLG_OF_NOUNDEF  0x00000200      /* allow no undefined symbols: -zdefs */
 421 #define FLG_OF_PURETXT  0x00000400      /* allow no text relocations: -ztext */
 422 #define FLG_OF_GENMAP   0x00000800      /* generate a memory map: -m */
 423 #define FLG_OF_DYNLIBS  0x00001000      /* dynamic input allowed: -Bdynamic */
 424 #define FLG_OF_SYMBOLIC 0x00002000      /* bind global symbols: -Bsymbolic */
 425 #define FLG_OF_ADDVERS  0x00004000      /* add version stamp: -Qy */
 426 #define FLG_OF_NOLDYNSYM 0x00008000     /* -znoldynsym set */
 427 #define FLG_OF_IS_ORDER 0x00010000      /* input section ordering within a */
 428                                         /*      segment is required */
 429 #define FLG_OF_EC_FILES 0x00020000      /* Ent_desc exist w/non-NULL ec_files */
 430 #define FLG_OF_TEXTREL  0x00040000      /* text relocations have been found */
 431 #define FLG_OF_MULDEFS  0x00080000      /* multiple symbols are allowed */
 432 #define FLG_OF_TLSPHDR  0x00100000      /* a TLS program header is required */
 433 #define FLG_OF_BLDGOT   0x00200000      /* build GOT table */
 434 #define FLG_OF_VERDEF   0x00400000      /* record version definitions */
 435 #define FLG_OF_VERNEED  0x00800000      /* record version dependencies */
 436 #define FLG_OF_NOVERSEC 0x01000000      /* don't record version sections */
 437 #define FLG_OF_KEY      0x02000000      /* file requires sort keys */
 438 #define FLG_OF_PROCRED  0x04000000      /* process any symbol reductions by */
 439                                         /*      effecting the symbol table */
 440                                         /*      output and relocations */
 441 #define FLG_OF_SYMINFO  0x08000000      /* create a syminfo section */
 442 #define FLG_OF_AUX      0x10000000      /* ofl_filter is an auxiliary filter */
 443 #define FLG_OF_FATAL    0x20000000      /* fatal error during input */
 444 #define FLG_OF_WARN     0x40000000      /* warning during input processing. */
 445 #define FLG_OF_VERBOSE  0x80000000      /* -z verbose flag set */
 446 
 447 #define FLG_OF_MAPSYMB  0x000100000000  /* symbolic scope definition seen */
 448 #define FLG_OF_MAPGLOB  0x000200000000  /* global scope definition seen */
 449 #define FLG_OF_COMREL   0x000400000000  /* -z combreloc set, which enables */
 450                                         /*      DT_RELACNT tracking, */
 451 #define FLG_OF_NOCOMREL 0x000800000000  /* -z nocombreloc set */
 452 #define FLG_OF_AUTOLCL  0x001000000000  /* automatically reduce unspecified */
 453                                         /*      global symbols to locals */
 454 #define FLG_OF_AUTOELM  0x002000000000  /* automatically eliminate */
 455                                         /*      unspecified global symbols */
 456 #define FLG_OF_REDLSYM  0x004000000000  /* reduce local symbols */
 457 #define FLG_OF_OS_ORDER 0x008000000000  /* output section ordering required */
 458 #define FLG_OF_OSABI    0x010000000000  /* tag object as ELFOSABI_SOLARIS */
 459 #define FLG_OF_ADJOSCNT 0x020000000000  /* adjust ofl_shdrcnt to accommodate */
 460                                         /*      discarded sections */
 461 #define FLG_OF_OTOSCAP  0x040000000000  /* convert object capabilities to */
 462                                         /*      symbol capabilities */
 463 #define FLG_OF_PTCAP    0x080000000000  /* PT_SUNWCAP required */
 464 #define FLG_OF_CAPSTRS  0x100000000000  /* capability strings are required */
 465 #define FLG_OF_EHFRAME  0x200000000000  /* output contains .eh_frame section */
 466 #define FLG_OF_FATWARN  0x400000000000  /* make warnings fatal */
 467 #define FLG_OF_ADEFLIB  0x800000000000  /* no libraries in default path */
 468 
 469 /*
 470  * In the flags1 arena, establish any options that are applicable to archive
 471  * extraction first, and associate a mask.  These values are recorded with any
 472  * archive descriptor so that they may be reset should the archive require a
 473  * rescan to try and resolve undefined symbols.
 474  */
 475 #define FLG_OF1_ALLEXRT 0x0000000001    /* extract all members from an */
 476                                         /*      archive file */
 477 #define FLG_OF1_WEAKEXT 0x0000000002    /* allow archive extraction to */
 478                                         /*      resolve weak references */
 479 #define MSK_OF1_ARCHIVE 0x0000000003    /* archive flags mask */
 480 
 481 #define FLG_OF1_NOINTRP 0x0000000008    /* -z nointerp flag set */
 482 #define FLG_OF1_ZDIRECT 0x0000000010    /* -z direct flag set */
 483 #define FLG_OF1_NDIRECT 0x0000000020    /* no-direct bindings specified */
 484 #define FLG_OF1_DEFERRED 0x0000000040   /* deferred dependency recording */
 485 
 486 #define FLG_OF1_RELDYN  0x0000000100    /* process .dynamic in rel obj */
 487 #define FLG_OF1_NRLXREL 0x0000000200    /* -z norelaxreloc flag set */
 488 #define FLG_OF1_RLXREL  0x0000000400    /* -z relaxreloc flag set */
 489 #define FLG_OF1_IGNORE  0x0000000800    /* ignore unused dependencies */
 490 #define FLG_OF1_NOSGHND 0x0000001000    /* -z nosighandler flag set */
 491 #define FLG_OF1_TEXTOFF 0x0000002000    /* text relocations are ok */
 492 #define FLG_OF1_ABSEXEC 0x0000004000    /* -zabsexec set */
 493 #define FLG_OF1_LAZYLD  0x0000008000    /* lazy loading of objects enabled */
 494 #define FLG_OF1_GRPPRM  0x0000010000    /* dependencies are to have */
 495                                         /*      GROUPPERM enabled */
 496 
 497 #define FLG_OF1_NOPARTI 0x0000040000    /* -znopartial set */
 498 #define FLG_OF1_BSSOREL 0x0000080000    /* output relocation against bss */
 499                                         /*      section */
 500 #define FLG_OF1_TLSOREL 0x0000100000    /* output relocation against .tlsbss */
 501                                         /*      section */
 502 #define FLG_OF1_MEMORY  0x0000200000    /* produce a memory model */
 503 #define FLG_OF1_NGLBDIR 0x0000400000    /* no DT_1_DIRECT flag allowed */
 504 #define FLG_OF1_ENCDIFF 0x0000800000    /* host running linker has different */
 505                                         /*      byte order than output object */
 506 #define FLG_OF1_VADDR   0x0001000000    /* a segment defines explicit vaddr */
 507 #define FLG_OF1_EXTRACT 0x0002000000    /* archive member has been extracted */
 508 #define FLG_OF1_RESCAN  0x0004000000    /* any archives should be rescanned */
 509 #define FLG_OF1_IGNPRC  0x0008000000    /* ignore processing required */
 510 #define FLG_OF1_NCSTTAB 0x0010000000    /* -znocompstrtab set */
 511 #define FLG_OF1_DONE    0x0020000000    /* link-editor processing complete */
 512 #define FLG_OF1_NONREG  0x0040000000    /* non-regular file specified as */
 513                                         /*      the output file */
 514 #define FLG_OF1_ALNODIR 0x0080000000    /* establish NODIRECT for all */
 515                                         /*      exported interfaces. */
 516 #define FLG_OF1_OVHWCAP1 0x0100000000   /* override CA_SUNW_HW_1 capabilities */
 517 #define FLG_OF1_OVSFCAP1 0x0200000000   /* override CA_SUNW_SF_1 capabilities */
 518 #define FLG_OF1_OVHWCAP2 0x0400000000   /* override CA_SUNW_HW_2 capabilities */
 519 #define FLG_OF1_OVMACHCAP 0x0800000000  /* override CA_SUNW_MACH capability */
 520 #define FLG_OF1_OVPLATCAP 0x1000000000  /* override CA_SUNW_PLAT capability */
 521 #define FLG_OF1_OVIDCAP 0x2000000000    /* override CA_SUNW_ID capability */
 522 
 523 /*
 524  * Guidance flags. The flags with the FLG_OFG_NO_ prefix are used to suppress
 525  * messages for a given category, and use the lower 28 bits of the word,
 526  * The upper nibble is reserved for other guidance status.
 527  */
 528 #define FLG_OFG_ENABLE          0x10000000      /* -z guidance option active */
 529 #define FLG_OFG_ISSUED          0x20000000      /* -z guidance message issued */
 530 
 531 #define FLG_OFG_NO_ALL          0x0fffffff      /* disable all guidance */
 532 #define FLG_OFG_NO_DEFS         0x00000001      /* specify all dependencies */
 533 #define FLG_OFG_NO_DB           0x00000002      /* use direct bindings */
 534 #define FLG_OFG_NO_LAZY         0x00000004      /* be explicit about lazyload */
 535 #define FLG_OFG_NO_MF           0x00000008      /* use v2 mapfile syntax */
 536 #define FLG_OFG_NO_TEXT         0x00000010      /* verify pure text segment */
 537 #define FLG_OFG_NO_UNUSED       0x00000020      /* remove unused dependency */
 538 
 539 /*
 540  * Test to see if a guidance should be given for a given category
 541  * or not. _no_flag is one of the FLG_OFG_NO_xxx flags. Returns TRUE
 542  * if the guidance should be issued, and FALSE to remain silent.
 543  */
 544 #define OFL_GUIDANCE(_ofl, _no_flag) (((_ofl)->ofl_guideflags & \
 545         (FLG_OFG_ENABLE | (_no_flag))) == FLG_OFG_ENABLE)
 546 
 547 /*
 548  * Test to see if the output file would allow the presence of
 549  * a .dynsym section.
 550  */
 551 #define OFL_ALLOW_DYNSYM(_ofl) (((_ofl)->ofl_flags & \
 552         (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC)
 553 
 554 /*
 555  * Test to see if the output file would allow the presence of
 556  * a .SUNW_ldynsym section. The requirements are that a .dynsym
 557  * is allowed, and -znoldynsym has not been specified. Note that
 558  * even if the answer is True (1), we will only generate one if there
 559  * are local symbols that require it.
 560  */
 561 #define OFL_ALLOW_LDYNSYM(_ofl) (((_ofl)->ofl_flags & \
 562         (FLG_OF_DYNAMIC | FLG_OF_RELOBJ | FLG_OF_NOLDYNSYM)) == FLG_OF_DYNAMIC)
 563 
 564 /*
 565  * Test to see if relocation processing should be done. This is normally
 566  * true, but can be disabled via the '-z noreloc' option. Note that
 567  * relocatable objects are still relocated even if '-z noreloc' is present.
 568  */
 569 #define OFL_DO_RELOC(_ofl) (((_ofl)->ofl_flags & FLG_OF_RELOBJ) || \
 570         !((_ofl)->ofl_dtflags_1 & DF_1_NORELOC))
 571 
 572 /*
 573  * Determine whether a static executable is being built.
 574  */
 575 #define OFL_IS_STATIC_EXEC(_ofl) (((_ofl)->ofl_flags & \
 576         (FLG_OF_STATIC | FLG_OF_EXEC)) == (FLG_OF_STATIC | FLG_OF_EXEC))
 577 
 578 /*
 579  * Determine whether a static object is being built.  This macro is used
 580  * to select the appropriate string table, and symbol table that other
 581  * sections need to reference.
 582  */
 583 #define OFL_IS_STATIC_OBJ(_ofl) ((_ofl)->ofl_flags & \
 584         (FLG_OF_RELOBJ | FLG_OF_STATIC))
 585 
 586 /*
 587  * Macros for counting symbol table entries.  These are used to size symbol
 588  * tables and associated sections (.syminfo, SUNW_capinfo, .hash, etc.) and
 589  * set required sh_info entries (the offset to the first global symbol).
 590  */
 591 #define SYMTAB_LOC_CNT(_ofl)            /* local .symtab entries */     \
 592         (2 +                            /*    NULL and STT_FILE */      \
 593         (_ofl)->ofl_shdrcnt +                /*    section symbol */         \
 594         (_ofl)->ofl_caploclcnt +     /*    local capabilities */     \
 595         (_ofl)->ofl_scopecnt +               /*    scoped symbols */         \
 596         (_ofl)->ofl_locscnt)         /*    standard locals */
 597 #define SYMTAB_ALL_CNT(_ofl)            /* all .symtab entries */       \
 598         (SYMTAB_LOC_CNT(_ofl) +         /*    .symtab locals */         \
 599         (_ofl)->ofl_globcnt)         /*    standard globals */
 600 
 601 #define DYNSYM_LOC_CNT(_ofl)            /* local .dynsym entries */     \
 602         (1 +                            /*    NULL */                   \
 603         (_ofl)->ofl_dynshdrcnt +     /*    section symbols */        \
 604         (_ofl)->ofl_caploclcnt +     /*    local capabilities */     \
 605         (_ofl)->ofl_lregsymcnt)              /*    local register symbols */
 606 #define DYNSYM_ALL_CNT(_ofl)            /* all .dynsym entries */       \
 607         (DYNSYM_LOC_CNT(_ofl) +         /*    .dynsym locals */         \
 608         (_ofl)->ofl_globcnt)         /*    standard globals */
 609 
 610 /*
 611  * Define a move descriptor used within relocation structures.
 612  */
 613 typedef struct {
 614         Move            *mr_move;
 615         Sym_desc        *mr_sym;
 616 } Mv_reloc;
 617 
 618 /*
 619  * Relocation (active & output) processing structure - transparent to common
 620  * code. There can be millions of these structures in a large link, so it
 621  * is important to keep it small. You should only add new items to Rel_desc
 622  * if they are critical, apply to most relocations, and cannot be easily
 623  * computed from the other information.
 624  *
 625  * Items that can be derived should be implemented as a function that accepts
 626  * a Rel_desc argument, and returns the desired data. ld_reloc_sym_name() is
 627  * an example of this.
 628  *
 629  * Lesser used relocation data is kept in an auxiliary block, Rel_aux,
 630  * that is only allocated as necessary. In exchange for adding one pointer
 631  * of overhead to Rel_desc (rel_aux), most relocations are reduced in size
 632  * by the size of Rel_aux. This strategy relies on the data in Rel_aux
 633  * being rarely needed --- otherwise it will backfire badly.
 634  *
 635  * Note that rel_raddend is primarily only of interest to RELA relocations,
 636  * and is set to 0 for REL. However, there is an exception: If FLG_REL_NADDEND
 637  * is set, then rel_raddend contains a replacement value for the implicit
 638  * addend found in the relocation target.
 639  *
 640  * Fields should be ordered from largest to smallest, to minimize packing
 641  * holes in the struct layout.
 642  */
 643 struct rel_desc {
 644         Is_desc         *rel_isdesc;    /* input section reloc is against */
 645         Sym_desc        *rel_sym;       /* sym relocation is against */
 646         Rel_aux         *rel_aux;       /* NULL, or auxiliary data */
 647         Xword           rel_roffset;    /* relocation offset */
 648         Sxword          rel_raddend;    /* addend from input relocation */
 649         Word            rel_flags;      /* misc. flags for relocations */
 650         Word            rel_rtype;      /* relocation type */
 651 };
 652 
 653 /*
 654  * Data that would be kept in Rel_desc if the size of that structure was
 655  * not an issue. This auxiliary block is only allocated as needed,
 656  * and must only contain rarely needed items. The goal is for the vast
 657  * majority of Rel_desc structs to not have an auxiliary block.
 658  *
 659  * When a Rel_desc does not have an auxiliary block, a default value
 660  * is assumed for each auxiliary item:
 661  *
 662  * -    ra_osdesc:
 663  *      Output section to which relocation applies. The default
 664  *      value for this is the output section associated with the
 665  *      input section (rel_isdesc->is_osdesc), or NULL if there
 666  *      is no associated input section.
 667  *
 668  * -    ra_usym:
 669  *      If the symbol associated with a relocation is part of a weak/strong
 670  *      pair, then ra_usym contains the strong symbol and rel_sym the weak.
 671  *      Otherwise, the default value is the same value as rel_sym.
 672  *
 673  * -    ra_move:
 674  *      Move table data. The default value is NULL.
 675  *
 676  * -    ra_typedata:
 677  *      ELF_R_TYPE_DATA(info). This value applies only to a small
 678  *      subset of 64-bit sparc relocations, and is otherwise 0. The
 679  *      default value is 0.
 680  *
 681  * If any value in Rel_aux is non-default, then an auxiliary block is
 682  * necessary, and each field contains its actual value. If all the auxiliary
 683  * values are default, no Rel_aux is needed, and the RELAUX_GET_xxx()
 684  * macros below are able to supply the proper default.
 685  *
 686  * To set a Rel_aux value, use the ld_reloc_set_aux_XXX() functions.
 687  * These functions are written to avoid unnecessary auxiliary allocations,
 688  * and know the rules for each item.
 689  */
 690 struct rel_aux {
 691         Os_desc         *ra_osdesc;     /* output section reloc is against */
 692         Sym_desc        *ra_usym;       /* strong sym if this is a weak pair */
 693         Mv_reloc        *ra_move;       /* move table information */
 694         Word            ra_typedata;    /* ELF_R_TYPE_DATA(info) */
 695 };
 696 
 697 /*
 698  * Test a given auxiliary value to determine if it has the default value
 699  * for that item, as described above. If all the auxiliary items have
 700  * their default values, no auxiliary place is necessary to represent them.
 701  * If any one of them is non-default, the auxiliary block is needed.
 702  */
 703 #define RELAUX_ISDEFAULT_MOVE(_rdesc, _mv) (_mv == NULL)
 704 #define RELAUX_ISDEFAULT_USYM(_rdesc, _usym) ((_rdesc)->rel_sym == _usym)
 705 #define RELAUX_ISDEFAULT_OSDESC(_rdesc, _osdesc) \
 706         ((((_rdesc)->rel_isdesc == NULL) && (_osdesc == NULL)) || \
 707         ((_rdesc)->rel_isdesc && ((_rdesc)->rel_isdesc->is_osdesc == _osdesc)))
 708 #define RELAUX_ISDEFAULT_TYPEDATA(_rdesc, _typedata) (_typedata == 0)
 709 
 710 /*
 711  * Retrieve the value of an auxiliary relocation item, preserving the illusion
 712  * that every relocation descriptor has an auxiliary block attached. The
 713  * real implementation is that an auxiliary block is only present if one or
 714  * more auxiliary items have non-default values. These macros return the true
 715  * value if an auxiliary block is present, and the default value for the
 716  * item otherwise.
 717  */
 718 #define RELAUX_GET_MOVE(_rdesc) \
 719         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_move : NULL)
 720 #define RELAUX_GET_USYM(_rdesc) \
 721         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_usym : (_rdesc)->rel_sym)
 722 #define RELAUX_GET_OSDESC(_rdesc) \
 723         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_osdesc : \
 724         ((_rdesc)->rel_isdesc ? (_rdesc)->rel_isdesc->is_osdesc : NULL))
 725 #define RELAUX_GET_TYPEDATA(_rdesc) \
 726         ((_rdesc)->rel_aux ? (_rdesc)->rel_aux->ra_typedata : 0)
 727 
 728 /*
 729  * common flags used on the Rel_desc structure (defined in machrel.h).
 730  */
 731 #define FLG_REL_GOT     0x00000001      /* relocation against GOT */
 732 #define FLG_REL_PLT     0x00000002      /* relocation against PLT */
 733 #define FLG_REL_BSS     0x00000004      /* relocation against BSS */
 734 #define FLG_REL_LOAD    0x00000008      /* section loadable */
 735 #define FLG_REL_SCNNDX  0x00000010      /* use section index for symbol ndx */
 736 #define FLG_REL_CLVAL   0x00000020      /* clear VALUE for active relocation */
 737 #define FLG_REL_ADVAL   0x00000040      /* add VALUE for output relocation, */
 738                                         /*      only relevant to SPARC and */
 739                                         /*      R_SPARC_RELATIVE */
 740 #define FLG_REL_GOTCL   0x00000080      /* clear the GOT entry.  This is */
 741                                         /* relevant to RELA relocations, */
 742                                         /* not REL (i386) relocations */
 743 #define FLG_REL_MOVETAB 0x00000100      /* Relocation against .SUNW_move */
 744                                         /*      adjustments required before */
 745                                         /*      actual relocation */
 746 #define FLG_REL_NOINFO  0x00000200      /* Relocation comes from a section */
 747                                         /*      with a null sh_info field */
 748 #define FLG_REL_REG     0x00000400      /* Relocation target is reg sym */
 749 #define FLG_REL_FPTR    0x00000800      /* relocation against func. desc. */
 750 #define FLG_REL_RFPTR1  0x00001000      /* Relative relocation against */
 751                                         /*   1st part of FD */
 752 #define FLG_REL_RFPTR2  0x00002000      /* Relative relocation against */
 753                                         /*   2nd part of FD */
 754 #define FLG_REL_DISP    0x00004000      /* *disp* relocation */
 755 #define FLG_REL_STLS    0x00008000      /* IE TLS reference to */
 756                                         /*      static TLS GOT index */
 757 #define FLG_REL_DTLS    0x00010000      /* GD TLS reference relative to */
 758                                         /*      dynamic TLS GOT index */
 759 #define FLG_REL_MTLS    0x00020000      /* LD TLS reference against GOT */
 760 #define FLG_REL_STTLS   0x00040000      /* LE TLS reference directly */
 761                                         /*      to static tls index */
 762 #define FLG_REL_TLSFIX  0x00080000      /* relocation points to TLS instr. */
 763                                         /*      which needs updating */
 764 #define FLG_REL_RELA    0x00100000      /* descriptor captures a Rela */
 765 #define FLG_REL_GOTFIX  0x00200000      /* relocation points to GOTOP instr. */
 766                                         /*      which needs updating */
 767 #define FLG_REL_NADDEND 0x00400000      /* Replace implicit addend in dest */
 768                                         /*      with value in rel_raddend */
 769                                         /*      Relevant to REL (i386) */
 770                                         /*      relocations, not to RELA. */
 771 
 772 /*
 773  * We often need the name of the symbol contained in a relocation descriptor
 774  * for diagnostic or error output. This is usually the symbol name, but
 775  * we substitute a constructed name in some cases. Hence, the name is
 776  * generated on the fly by a private function within libld. This is the
 777  * prototype for that function.
 778  */
 779 typedef const char *(* rel_desc_sname_func_t)(Rel_desc *);
 780 
 781 /*
 782  * Header for a relocation descriptor cache buffer.
 783  */
 784 struct rel_cachebuf {
 785         Rel_desc        *rc_end;
 786         Rel_desc        *rc_free;
 787         Rel_desc        rc_arr[1];
 788 };
 789 
 790 /*
 791  * Header for a relocation auxiliary descriptor cache buffer.
 792  */
 793 struct rel_aux_cachebuf {
 794         Rel_aux         *rac_end;
 795         Rel_aux         *rac_free;
 796         Rel_aux         rac_arr[1];
 797 };
 798 
 799 /*
 800  * Convenience macro for traversing every relocation descriptor found within
 801  * a given relocation cache, transparently handling the cache buffers and
 802  * skipping any unallocated descriptors within the buffers.
 803  *
 804  * entry:
 805  *      _rel_cache - Relocate descriptor cache (Rel_cache) to traverse
 806  *      _idx - Aliste index variable for use by the macro
 807  *      _rcbp - Cache buffer pointer, for use by the macro
 808  *      _orsp - Rel_desc pointer, which will take on the value of a different
 809  *              relocation descriptor in the cache in each iteration.
 810  *
 811  * The caller must not assign new values to _idx, _rcbp, or _orsp within
 812  * the scope of REL_CACHE_TRAVERSE.
 813  */
 814 #define REL_CACHE_TRAVERSE(_rel_cache, _idx, _rcbp, _orsp) \
 815         for (APLIST_TRAVERSE((_rel_cache)->rc_list, _idx, _rcbp)) \
 816                 for (_orsp = _rcbp->rc_arr; _orsp < _rcbp->rc_free; _orsp++)
 817 
 818 /*
 819  * Symbol value descriptor.  For relocatable objects, each symbols value is
 820  * its offset within its associated section.  Therefore, to uniquely define
 821  * each symbol within a relocatable object, record and sort the sh_offset and
 822  * symbol value.  This information is used to search for displacement
 823  * relocations as part of copy relocation validation.
 824  */
 825 typedef struct {
 826         Addr            ssv_value;
 827         Sym_desc        *ssv_sdp;
 828 } Ssv_desc;
 829 
 830 /*
 831  * Input file processing structures.
 832  */
 833 struct ifl_desc {                       /* input file descriptor */
 834         const char      *ifl_name;      /* full file name */
 835         const char      *ifl_soname;    /* shared object name */
 836         dev_t           ifl_stdev;      /* device id and inode number for .so */
 837         ino_t           ifl_stino;      /*      multiple inclusion checks */
 838         Ehdr            *ifl_ehdr;      /* elf header describing this file */
 839         Elf             *ifl_elf;       /* elf descriptor for this file */
 840         Sym_desc        **ifl_oldndx;   /* original symbol table indices */
 841         Sym_desc        *ifl_locs;      /* symbol desc version of locals */
 842         Ssv_desc        *ifl_sortsyms;  /* sorted list of symbols by value */
 843         Word            ifl_locscnt;    /* no. of local symbols to process */
 844         Word            ifl_symscnt;    /* total no. of symbols to process */
 845         Word            ifl_sortcnt;    /* no. of sorted symbols to process */
 846         Word            ifl_shnum;      /* number of sections in file */
 847         Word            ifl_shstrndx;   /* index to .shstrtab */
 848         Word            ifl_vercnt;     /* number of versions in file */
 849         Half            ifl_neededndx;  /* index to NEEDED in .dyn section */
 850         Word            ifl_flags;      /* explicit/implicit reference */
 851         Is_desc         **ifl_isdesc;   /* isdesc[scn ndx] = Is_desc ptr */
 852         Sdf_desc        *ifl_sdfdesc;   /* control definition */
 853         Versym          *ifl_versym;    /* version symbol table array */
 854         Ver_index       *ifl_verndx;    /* verndx[ver ndx] = Ver_index */
 855         APlist          *ifl_verdesc;   /* version descriptor list */
 856         APlist          *ifl_relsect;   /* relocation section list */
 857         Alist           *ifl_groups;    /* SHT_GROUP section list */
 858         Cap_desc        *ifl_caps;      /* capabilities descriptor */
 859 };
 860 
 861 #define FLG_IF_CMDLINE  0x00000001      /* full filename specified from the */
 862                                         /*      command line (no -l) */
 863 #define FLG_IF_NEEDED   0x00000002      /* shared object should be recorded */
 864 #define FLG_IF_DIRECT   0x00000004      /* establish direct bindings to this */
 865                                         /*      object */
 866 #define FLG_IF_EXTRACT  0x00000008      /* file extracted from an archive */
 867 #define FLG_IF_VERNEED  0x00000010      /* version dependency information is */
 868                                         /*      required */
 869 #define FLG_IF_DEPREQD  0x00000020      /* dependency is required to satisfy */
 870                                         /*      symbol references */
 871 #define FLG_IF_NEEDSTR  0x00000040      /* dependency specified by -Nn */
 872                                         /*      flag */
 873 #define FLG_IF_IGNORE   0x00000080      /* ignore unused dependencies */
 874 #define FLG_IF_NODIRECT 0x00000100      /* object contains symbols that */
 875                                         /*      cannot be directly bound to */
 876 #define FLG_IF_LAZYLD   0x00000200      /* dependency should be lazy loaded */
 877 #define FLG_IF_GRPPRM   0x00000400      /* dependency establishes a group */
 878 #define FLG_IF_DISPPEND 0x00000800      /* displacement relocation done */
 879                                         /*      in the ld time. */
 880 #define FLG_IF_DISPDONE 0x00001000      /* displacement relocation done */
 881                                         /*      at the run time */
 882 #define FLG_IF_MAPFILE  0x00002000      /* file is a mapfile */
 883 #define FLG_IF_HSTRTAB  0x00004000      /* file has a string section */
 884 #define FLG_IF_FILEREF  0x00008000      /* file contains a section which */
 885                                         /*      is included in the output */
 886                                         /*      allocatable image */
 887 #define FLG_IF_GNUVER   0x00010000      /* file used GNU-style versioning */
 888 #define FLG_IF_ORDERED  0x00020000      /* ordered section processing */
 889                                         /*      required */
 890 #define FLG_IF_OTOSCAP  0x00040000      /* convert object capabilities to */
 891                                         /*      symbol capabilities */
 892 #define FLG_IF_DEFERRED 0x00080000      /* dependency is deferred */
 893 #define FLG_IF_RTLDINF  0x00100000      /* dependency has DT_SUNW_RTLTINF set */
 894 #define FLG_IF_GROUPS   0x00200000      /* input file has groups to process */
 895 
 896 /*
 897  * Symbol states that require the generation of a DT_POSFLAG_1 .dynamic entry.
 898  */
 899 #define MSK_IF_POSFLAG1 (FLG_IF_LAZYLD | FLG_IF_GRPPRM | FLG_IF_DEFERRED)
 900 
 901 /*
 902  * Symbol states that require an associated Syminfo entry.
 903  */
 904 #define MSK_IF_SYMINFO  (FLG_IF_LAZYLD | FLG_IF_DIRECT | FLG_IF_DEFERRED)
 905 
 906 
 907 struct is_desc {                        /* input section descriptor */
 908         const char      *is_name;       /* original section name */
 909         const char      *is_sym_name;   /* NULL, or name string to use for */
 910                                         /*      related STT_SECTION symbols */
 911         Shdr            *is_shdr;       /* the elf section header */
 912         Ifl_desc        *is_file;       /* infile desc for this section */
 913         Os_desc         *is_osdesc;     /* new output section for this */
 914                                         /*      input section */
 915         Elf_Data        *is_indata;     /* input sections raw data */
 916         Is_desc         *is_symshndx;   /* related SHT_SYM_SHNDX section */
 917         Is_desc         *is_comdatkeep; /* If COMDAT section is discarded, */
 918                                         /*      this is section that was kept */
 919         Word            is_scnndx;      /* original section index in file */
 920         Word            is_ordndx;      /* index for section.  Used to decide */
 921                                         /*      where to insert section when */
 922                                         /*      reordering sections */
 923         Word            is_keyident;    /* key for SHF_{ORDERED|LINK_ORDER} */
 924                                         /*      processing and ident used for */
 925                                         /*       placing/ordering sections */
 926         Word            is_flags;       /* Various flags */
 927 };
 928 
 929 #define FLG_IS_ORDERED  0x0001          /* this is a SHF_ORDERED section */
 930 #define FLG_IS_KEY      0x0002          /* section requires sort keys */
 931 #define FLG_IS_DISCARD  0x0004          /* section is to be discarded */
 932 #define FLG_IS_RELUPD   0x0008          /* symbol defined here may have moved */
 933 #define FLG_IS_SECTREF  0x0010          /* section has been referenced */
 934 #define FLG_IS_GDATADEF 0x0020          /* section contains global data sym */
 935 #define FLG_IS_EXTERNAL 0x0040          /* isp from a user file */
 936 #define FLG_IS_INSTRMRG 0x0080          /* Usable SHF_MERGE|SHF_STRINGS sec */
 937 #define FLG_IS_GNSTRMRG 0x0100          /* Generated mergeable string section */
 938 
 939 #define FLG_IS_PLACE    0x0400          /* section requires to be placed */
 940 #define FLG_IS_COMDAT   0x0800          /* section is COMDAT */
 941 #define FLG_IS_EHFRAME  0x1000          /* section is .eh_frame */
 942 
 943 /*
 944  * Output sections contain lists of input sections that are assigned to them.
 945  * These items fall into 4 categories:
 946  *      BEFORE - Ordered sections that specify SHN_BEFORE, in input order.
 947  *      ORDERED - Ordered sections that are sorted using unsorted sections
 948  *              as the sort key.
 949  *      DEFAULT - Sections that are placed into the output section
 950  *              in input order.
 951  *      AFTER - Ordered sections that specify SHN_AFTER, in input order.
 952  */
 953 #define OS_ISD_BEFORE   0
 954 #define OS_ISD_ORDERED  1
 955 #define OS_ISD_DEFAULT  2
 956 #define OS_ISD_AFTER    3
 957 #define OS_ISD_NUM      4
 958 typedef APlist *os_isdecs_arr[OS_ISD_NUM];
 959 
 960 /*
 961  * Convenience macro for traversing every input section associated
 962  * with a given output section. The primary benefit of this macro
 963  * is that it preserves a precious level of code indentation in the
 964  * code that uses it.
 965  */
 966 #define OS_ISDESCS_TRAVERSE(_list_idx, _osp, _idx, _isp) \
 967         for (_list_idx = 0; _list_idx < OS_ISD_NUM; _list_idx++) \
 968                 for (APLIST_TRAVERSE(_osp->os_isdescs[_list_idx], _idx, _isp))
 969 
 970 
 971 /*
 972  * Map file and output file processing structures
 973  */
 974 struct os_desc {                        /* Output section descriptor */
 975         const char      *os_name;       /* the section name */
 976         Elf_Scn         *os_scn;        /* the elf section descriptor */
 977         Shdr            *os_shdr;       /* the elf section header */
 978         Os_desc         *os_relosdesc;  /* the output relocation section */
 979         APlist          *os_relisdescs; /* reloc input section descriptors */
 980                                         /*      for this output section */
 981         os_isdecs_arr   os_isdescs;     /* lists of input sections in output */
 982         APlist          *os_mstrisdescs; /* FLG_IS_INSTRMRG input sections */
 983         Sg_desc         *os_sgdesc;     /* segment os_desc is placed on */
 984         Elf_Data        *os_outdata;    /* output sections raw data */
 985         avl_tree_t      *os_comdats;    /* AVL tree of COMDAT input sections */
 986                                         /*      associated to output section */
 987         Word            os_identndx;    /* section identifier for input */
 988                                         /*      section processing, followed */
 989                                         /*      by section symbol index */
 990         Word            os_ordndx;      /* index for section.  Used to decide */
 991                                         /*      where to insert section when */
 992                                         /*      reordering sections */
 993         Xword           os_szoutrels;   /* size of output relocation section */
 994         uint_t          os_namehash;    /* hash on section name */
 995         uchar_t         os_flags;       /* various flags */
 996 };
 997 
 998 #define FLG_OS_KEY              0x01    /* section requires sort keys */
 999 #define FLG_OS_OUTREL           0x02    /* output rel against this section */
1000 #define FLG_OS_SECTREF          0x04    /* isps are not affected by -zignore */
1001 #define FLG_OS_EHFRAME          0x08    /* section is .eh_frame */
1002 
1003 /*
1004  * The sg_id field of the segment descriptor is used to establish the default
1005  * order for program headers and segments in the output object. Segments are
1006  * ordered according to the following SGID values that classify them based on
1007  * their attributes. The initial set of built in segments are in this order,
1008  * and new mapfile defined segments are inserted into these groups. Within a
1009  * given SGID group, the position of new segments depends on the syntax
1010  * version of the mapfile that creates them. Version 1 (original sysv)
1011  * mapfiles place the new segment at the head of their group (reverse creation
1012  * order). The newer syntax places them at the end, following the others
1013  * (creation order).
1014  *
1015  * Note that any new segments must always be added after PT_PHDR and
1016  * PT_INTERP (refer Generic ABI, Page 5-4).
1017  */
1018 #define SGID_PHDR       0       /* PT_PHDR */
1019 #define SGID_INTERP     1       /* PT_INTERP */
1020 #define SGID_SUNWCAP    2       /* PT_SUNWCAP */
1021 #define SGID_TEXT       3       /* PT_LOAD */
1022 #define SGID_DATA       4       /* PT_LOAD */
1023 #define SGID_BSS        5       /* PT_LOAD */
1024 #if     defined(_ELF64)
1025 #define SGID_LRODATA    6       /* PT_LOAD (amd64-only) */
1026 #define SGID_LDATA      7       /* PT_LOAD (amd64-only) */
1027 #endif
1028 #define SGID_TEXT_EMPTY 8       /* PT_LOAD, reserved (?E in version 1 syntax) */
1029 #define SGID_NULL_EMPTY 9       /* PT_NULL, reserved (?E in version 1 syntax) */
1030 #define SGID_DYN        10      /* PT_DYNAMIC */
1031 #define SGID_DTRACE     11      /* PT_SUNWDTRACE */
1032 #define SGID_TLS        12      /* PT_TLS */
1033 #define SGID_UNWIND     13      /* PT_SUNW_UNWIND */
1034 #define SGID_SUNWSTACK  14      /* PT_SUNWSTACK */
1035 #define SGID_NOTE       15      /* PT_NOTE */
1036 #define SGID_NULL       16      /* PT_NULL,  mapfile defined empty phdr slots */
1037                                 /*      for use by post processors */
1038 #define SGID_EXTRA      17      /* PT_NULL (final catchall) */
1039 
1040 typedef Half sg_flags_t;
1041 struct sg_desc {                        /* output segment descriptor */
1042         Word            sg_id;          /* segment identifier (for sorting) */
1043         Phdr            sg_phdr;        /* segment header for output file */
1044         const char      *sg_name;       /* segment name for PT_LOAD, PT_NOTE, */
1045                                         /*      and PT_NULL, otherwise NULL */
1046         Xword           sg_round;       /* data rounding required (mapfile) */
1047         Xword           sg_length;      /* maximum segment length; if 0 */
1048                                         /*      segment is not specified */
1049         APlist          *sg_osdescs;    /* list of output section descriptors */
1050         APlist          *sg_is_order;   /* list of entry criteria */
1051                                         /*      giving input section order */
1052         Alist           *sg_os_order;   /* list specifying output section */
1053                                         /*      ordering for the segment */
1054         sg_flags_t      sg_flags;
1055         APlist          *sg_sizesym;    /* size symbols for this segment */
1056         Xword           sg_align;       /* LCM of sh_addralign */
1057         Elf_Scn         *sg_fscn;       /* the SCN of the first section. */
1058         avl_node_t      sg_avlnode;     /* AVL book-keeping */
1059 };
1060 
1061 #define FLG_SG_P_VADDR          0x0001  /* p_vaddr segment attribute set */
1062 #define FLG_SG_P_PADDR          0x0002  /* p_paddr segment attribute set */
1063 #define FLG_SG_LENGTH           0x0004  /* length segment attribute set */
1064 #define FLG_SG_P_ALIGN          0x0008  /* p_align segment attribute set */
1065 #define FLG_SG_ROUND            0x0010  /* round segment attribute set */
1066 #define FLG_SG_P_FLAGS          0x0020  /* p_flags segment attribute set */
1067 #define FLG_SG_P_TYPE           0x0040  /* p_type segment attribute set */
1068 #define FLG_SG_IS_ORDER         0x0080  /* input section ordering is required */
1069                                         /*      for this segment. */
1070 #define FLG_SG_NOHDR            0x0100  /* don't map ELF or phdrs into */
1071                                         /*      this segment */
1072 #define FLG_SG_EMPTY            0x0200  /* an empty segment specification */
1073                                         /*      no input sections will be */
1074                                         /*      associated to this section */
1075 #define FLG_SG_KEY              0x0400  /* segment requires sort keys */
1076 #define FLG_SG_NODISABLE        0x0800  /* FLG_SG_DISABLED is not allowed on */
1077                                         /*      this segment */
1078 #define FLG_SG_DISABLED         0x1000  /* this segment is disabled */
1079 #define FLG_SG_PHREQ            0x2000  /* this segment requires a program */
1080                                         /* header */
1081 #define FLG_SG_ORDERED          0x4000  /* SEGMENT_ORDER segment */
1082 
1083 struct sec_order {
1084         const char      *sco_secname;   /* section name to be ordered */
1085         Half            sco_flags;
1086 };
1087 
1088 #define FLG_SGO_USED    0x0001          /* was ordering used? */
1089 
1090 typedef Half ec_flags_t;
1091 struct ent_desc {                       /* input section entrance criteria */
1092         const char      *ec_name;       /* entrace criteria name, or NULL */
1093         Alist           *ec_files;      /* files from which to accept */
1094                                         /*      sections */
1095         const char      *ec_is_name;    /* input section name to match */
1096                                         /*      (NULL if none) */
1097         Word            ec_type;        /* section type */
1098         Word            ec_attrmask;    /* section attribute mask (AWX) */
1099         Word            ec_attrbits;    /* sections attribute bits */
1100         Sg_desc         *ec_segment;    /* output segment to enter if matched */
1101         Word            ec_ordndx;      /* index to determine where section */
1102                                         /*      meeting this criteria should */
1103                                         /*      inserted. Used for reordering */
1104                                         /*      of sections. */
1105         ec_flags_t      ec_flags;
1106         avl_node_t      ec_avlnode;     /* AVL book-keeping */
1107 };
1108 
1109 #define FLG_EC_BUILTIN  0x0001          /* built in descriptor */
1110 #define FLG_EC_USED     0x0002          /* entrance criteria met? */
1111 #define FLG_EC_CATCHALL 0x0004          /* Catches any section */
1112 
1113 /*
1114  * Ent_desc_file is the type of element maintained in the ec_files Alist
1115  * of an entrance criteria descriptor. Each item maintains one file
1116  * path, and a set of flags that specify the type of comparison it implies,
1117  * and other information about it. The comparison type is maintained in
1118  * the bottom byte of the flags.
1119  */
1120 #define TYP_ECF_MASK            0x00ff  /* Comparison type mask */
1121 #define TYP_ECF_PATH            0       /* Compare to file path */
1122 #define TYP_ECF_BASENAME        1       /* Compare to file basename */
1123 #define TYP_ECF_OBJNAME         2       /* Compare to regular file basename, */
1124                                         /*       or to archive member name */
1125 #define TYP_ECF_NUM             3
1126 
1127 #define FLG_ECF_ARMEMBER        0x0100  /* name includes archive member */
1128 
1129 typedef struct {
1130         Word            edf_flags;      /* Type of comparison */
1131         const char      *edf_name;      /* String to compare to */
1132         size_t          edf_name_len;   /* strlen(edf_name) */
1133 } Ent_desc_file;
1134 
1135 /*
1136  * One structure is allocated for a move entry, and associated to the symbol
1137  * against which a move is targeted.
1138  */
1139 typedef struct {
1140         Move            *md_move;       /* original Move entry */
1141         Xword           md_start;       /* start position */
1142         Xword           md_len;         /* length of initialization */
1143         Word            md_oidx;        /* output Move entry index */
1144 } Mv_desc;
1145 
1146 /*
1147  * Symbol descriptor.
1148  */
1149 typedef Lword           sd_flag_t;
1150 struct sym_desc {
1151         Alist           *sd_GOTndxs;    /* list of associated GOT entries */
1152         Sym             *sd_sym;        /* pointer to symbol table entry */
1153         Sym             *sd_osym;       /* copy of the original symbol entry */
1154                                         /*      used only for local partial */
1155         Alist           *sd_move;       /* move information associated with a */
1156                                         /*      partially initialized symbol */
1157         const char      *sd_name;       /* symbols name */
1158         Ifl_desc        *sd_file;       /* file where symbol is taken */
1159         Is_desc         *sd_isc;        /* input section of symbol definition */
1160         Sym_aux         *sd_aux;        /* auxiliary global symbol info. */
1161         Word            sd_symndx;      /* index in output symbol table */
1162         Word            sd_shndx;       /* sect. index sym is associated w/ */
1163         sd_flag_t       sd_flags;       /* state flags */
1164         Half            sd_ref;         /* reference definition of symbol */
1165 };
1166 
1167 /*
1168  * The auxiliary symbol descriptor contains the additional information (beyond
1169  * the symbol descriptor) required to process global symbols.  These symbols are
1170  * accessed via an internal symbol hash table where locality of reference is
1171  * important for performance.
1172  */
1173 struct sym_aux {
1174         APlist          *sa_dfiles;     /* files where symbol is defined */
1175         Sym             sa_sym;         /* copy of symtab entry */
1176         const char      *sa_vfile;      /* first unavailable definition */
1177         const char      *sa_rfile;      /* file with first symbol referenced */
1178         Word            sa_hash;        /* the pure hash value of symbol */
1179         Word            sa_PLTndx;      /* index into PLT for symbol */
1180         Word            sa_PLTGOTndx;   /* GOT entry indx for PLT indirection */
1181         Word            sa_linkndx;     /* index of associated symbol from */
1182                                         /*      ET_DYN file */
1183         Half            sa_symspec;     /* special symbol ids */
1184         Half            sa_overndx;     /* output file versioning index */
1185         Half            sa_dverndx;     /* dependency versioning index */
1186 };
1187 
1188 /*
1189  * Nodes used to track symbols in the global AVL symbol dictionary.
1190  */
1191 struct sym_avlnode {
1192         avl_node_t      sav_node;       /* AVL node */
1193         Word            sav_hash;       /* symbol hash value */
1194         const char      *sav_name;      /* symbol name */
1195         Sym_desc        *sav_sdp;       /* symbol descriptor */
1196 };
1197 
1198 /*
1199  * These are the ids for processing of `Special symbols'.  They are used
1200  * to set the sym->sd_aux->sa_symspec field.
1201  */
1202 #define SDAUX_ID_ETEXT  1               /* etext && _etext symbol */
1203 #define SDAUX_ID_EDATA  2               /* edata && _edata symbol */
1204 #define SDAUX_ID_END    3               /* end, _end, && _END_ symbol */
1205 #define SDAUX_ID_DYN    4               /* DYNAMIC && _DYNAMIC symbol */
1206 #define SDAUX_ID_PLT    5               /* _PROCEDURE_LINKAGE_TABLE_ symbol */
1207 #define SDAUX_ID_GOT    6               /* _GLOBAL_OFFSET_TABLE_ symbol */
1208 #define SDAUX_ID_START  7               /* START_ && _START_ symbol */
1209 
1210 /*
1211  * Flags for sym_desc.sd_flags
1212  */
1213 #define FLG_SY_MVTOCOMM 0x00000001      /* assign symbol to common (.bss) */
1214                                         /*      this is a result of a */
1215                                         /*      copy reloc against sym */
1216 #define FLG_SY_GLOBREF  0x00000002      /* a global reference has been seen */
1217 #define FLG_SY_WEAKDEF  0x00000004      /* a weak definition has been used */
1218 #define FLG_SY_CLEAN    0x00000008      /* `Sym' entry points to original */
1219                                         /*      input file (read-only). */
1220 #define FLG_SY_UPREQD   0x00000010      /* symbol value update is required, */
1221                                         /*      either it's used as an entry */
1222                                         /*      point or for relocation, but */
1223                                         /*      it must be updated even if */
1224                                         /*      the -s flag is in effect */
1225 #define FLG_SY_NOTAVAIL 0x00000020      /* symbol is not available to the */
1226                                         /*      application either because it */
1227                                         /*      originates from an implicitly */
1228                                         /*      referenced shared object, or */
1229                                         /*      because it is not part of a */
1230                                         /*      specified version. */
1231 #define FLG_SY_REDUCED  0x00000040      /* a global is reduced to local */
1232 #define FLG_SY_VERSPROM 0x00000080      /* version definition has been */
1233                                         /*      promoted to output file */
1234 #define FLG_SY_PROT     0x00000100      /* stv_protected visibility seen */
1235 #define FLG_SY_MAPREF   0x00000200      /* symbol reference generated by user */
1236                                         /*      from mapfile */
1237 #define FLG_SY_REFRSD   0x00000400      /* symbols sd_ref has been raised */
1238                                         /*      due to a copy-relocs */
1239                                         /*      weak-strong pairing */
1240 #define FLG_SY_INTPOSE  0x00000800      /* symbol defines an interposer */
1241 #define FLG_SY_INVALID  0x00001000      /* unwanted/erroneous symbol */
1242 #define FLG_SY_SMGOT    0x00002000      /* small got index assigned to symbol */
1243                                         /*      sparc only */
1244 #define FLG_SY_PARENT   0x00004000      /* symbol to be found in parent */
1245                                         /*    only used with direct bindings */
1246 #define FLG_SY_LAZYLD   0x00008000      /* symbol to cause lazyloading of */
1247                                         /*      parent object */
1248 #define FLG_SY_ISDISC   0x00010000      /* symbol is a member of a DISCARDED */
1249                                         /*      section (COMDAT) */
1250 #define FLG_SY_PAREXPN  0x00020000      /* partially init. symbol to be */
1251                                         /*      expanded */
1252 #define FLG_SY_PLTPAD   0x00040000      /* pltpadding has been allocated for */
1253                                         /*      this symbol */
1254 #define FLG_SY_REGSYM   0x00080000      /* REGISTER symbol (sparc only) */
1255 #define FLG_SY_SOFOUND  0x00100000      /* compared against an SO definition */
1256 #define FLG_SY_EXTERN   0x00200000      /* symbol is external, allows -zdefs */
1257                                         /*    error suppression */
1258 #define FLG_SY_MAPUSED  0x00400000      /* mapfile symbol used (occurred */
1259                                         /*    within a relocatable object) */
1260 #define FLG_SY_COMMEXP  0x00800000      /* COMMON symbol which has been */
1261                                         /*      allocated */
1262 #define FLG_SY_CMDREF   0x01000000      /* symbol was referenced from the */
1263                                         /*      command line.  (ld -u <>, */
1264                                         /*      ld -zrtldinfo=<>, ...) */
1265 #define FLG_SY_SPECSEC  0x02000000      /* section index is reserved value */
1266                                         /*      ABS, COMMON, ... */
1267 #define FLG_SY_TENTSYM  0x04000000      /* tentative symbol */
1268 #define FLG_SY_VISIBLE  0x08000000      /* symbols visibility determined */
1269 #define FLG_SY_STDFLTR  0x10000000      /* symbol is a standard filter */
1270 #define FLG_SY_AUXFLTR  0x20000000      /* symbol is an auxiliary filter */
1271 #define FLG_SY_DYNSORT  0x40000000      /* req. in dyn[sym|tls]sort section */
1272 #define FLG_SY_NODYNSORT 0x80000000     /* excluded from dyn[sym_tls]sort sec */
1273 
1274 #define FLG_SY_DEFAULT  0x0000100000000 /* global symbol, default */
1275 #define FLG_SY_SINGLE   0x0000200000000 /* global symbol, singleton defined */
1276 #define FLG_SY_PROTECT  0x0000400000000 /* global symbol, protected defined */
1277 #define FLG_SY_EXPORT   0x0000800000000 /* global symbol, exported defined */
1278 
1279 #define MSK_SY_GLOBAL \
1280         (FLG_SY_DEFAULT | FLG_SY_SINGLE | FLG_SY_PROTECT | FLG_SY_EXPORT)
1281                                         /* this mask indicates that the */
1282                                         /*    symbol has been explicitly */
1283                                         /*    defined within a mapfile */
1284                                         /*    definition, and is a candidate */
1285                                         /*    for versioning */
1286 
1287 #define FLG_SY_HIDDEN   0x0001000000000 /* global symbol, reduce to local */
1288 #define FLG_SY_ELIM     0x0002000000000 /* global symbol, eliminate */
1289 #define FLG_SY_IGNORE   0x0004000000000 /* global symbol, ignored */
1290 
1291 #define MSK_SY_LOCAL    (FLG_SY_HIDDEN | FLG_SY_ELIM | FLG_SY_IGNORE)
1292                                         /* this mask allows all local state */
1293                                         /*    flags to be removed when the */
1294                                         /*    symbol is copy relocated */
1295 
1296 #define FLG_SY_EXPDEF   0x0008000000000 /* symbol visibility defined */
1297                                         /*    explicitly */
1298 
1299 #define MSK_SY_NOAUTO   (FLG_SY_SINGLE | FLG_SY_EXPORT | FLG_SY_EXPDEF)
1300                                         /* this mask indicates that the */
1301                                         /*    symbol is not a candidate for */
1302                                         /*    auto-reduction/elimination */
1303 
1304 #define FLG_SY_MAPFILE  0x0010000000000 /* symbol attribute defined in a */
1305                                         /*    mapfile */
1306 #define FLG_SY_DIR      0x0020000000000 /* global symbol, direct bindings */
1307 #define FLG_SY_NDIR     0x0040000000000 /* global symbol, nondirect bindings */
1308 #define FLG_SY_OVERLAP  0x0080000000000 /* move entry overlap detected */
1309 #define FLG_SY_CAP      0x0100000000000 /* symbol is associated with */
1310                                         /*    capabilities */
1311 #define FLG_SY_DEFERRED 0x0200000000000 /* symbol should not be bound to */
1312                                         /*      during BIND_NOW relocations */
1313 
1314 /*
1315  * A symbol can only be truly hidden if it is not a capabilities symbol.
1316  */
1317 #define SYM_IS_HIDDEN(_sdp) \
1318         (((_sdp)->sd_flags & (FLG_SY_HIDDEN | FLG_SY_CAP)) == FLG_SY_HIDDEN)
1319 
1320 /*
1321  * Create a mask for (sym.st_other & visibility) since the gABI does not yet
1322  * define a ELF*_ST_OTHER macro.
1323  */
1324 #define MSK_SYM_VISIBILITY      0x7
1325 
1326 /*
1327  * Structure to manage the shared object definition lists.  There are two lists
1328  * that use this structure:
1329  *
1330  *  -   ofl_soneed; maintain the list of implicitly required dependencies
1331  *      (ie. shared objects needed by other shared objects).  These definitions
1332  *      may include RPATH's required to locate the dependencies, and any
1333  *      version requirements.
1334  *
1335  *  -   ofl_socntl; maintains the shared object control definitions.  These are
1336  *      provided by the user (via a mapfile) and are used to indicate any
1337  *      version control requirements.
1338  */
1339 struct  sdf_desc {
1340         const char      *sdf_name;      /* the shared objects file name */
1341         char            *sdf_rpath;     /* library search path DT_RPATH */
1342         const char      *sdf_rfile;     /* referencing file for diagnostics */
1343         Ifl_desc        *sdf_file;      /* the final input file descriptor */
1344         Alist           *sdf_vers;      /* list of versions that are required */
1345                                         /*      from this object */
1346         Alist           *sdf_verneed;   /* list of VERNEEDS to create for */
1347                                         /*      object via mapfile ADDVERS */
1348         Word            sdf_flags;
1349 };
1350 
1351 #define FLG_SDF_SELECT  0x01            /* version control selection required */
1352 #define FLG_SDF_VERIFY  0x02            /* version definition verification */
1353                                         /*      required */
1354 #define FLG_SDF_ADDVER  0x04            /* add VERNEED references */
1355 
1356 /*
1357  * Structure to manage shared object version usage requirements.
1358  */
1359 struct  sdv_desc {
1360         const char      *sdv_name;      /* version name */
1361         const char      *sdv_ref;       /* versions reference */
1362         Word            sdv_flags;      /* flags */
1363 };
1364 
1365 #define FLG_SDV_MATCHED 0x01            /* VERDEF found and matched */
1366 
1367 /*
1368  * Structures to manage versioning information.  Two versioning structures are
1369  * defined:
1370  *
1371  *   -  a version descriptor maintains a linked list of versions and their
1372  *      associated dependencies.  This is used to build the version definitions
1373  *      for an image being created (see map_symbol), and to determine the
1374  *      version dependency graph for any input files that are versioned.
1375  *
1376  *   -  a version index array contains each version of an input file that is
1377  *      being processed.  It informs us which versions are available for
1378  *      binding, and is used to generate any version dependency information.
1379  */
1380 struct  ver_desc {
1381         const char      *vd_name;       /* version name */
1382         Ifl_desc        *vd_file;       /* file that defined version */
1383         Word            vd_hash;        /* hash value of name */
1384         Half            vd_ndx;         /* coordinates with symbol index */
1385         Half            vd_flags;       /* version information */
1386         APlist          *vd_deps;       /* version dependencies */
1387         Ver_desc        *vd_ref;        /* dependency's first reference */
1388 };
1389 
1390 struct  ver_index {
1391         const char      *vi_name;       /* dependency version name */
1392         Half            vi_flags;       /* communicates availability */
1393         Half            vi_overndx;     /* index assigned to this version in */
1394                                         /*      output object Verneed section */
1395         Ver_desc        *vi_desc;       /* cross reference to descriptor */
1396 };
1397 
1398 /*
1399  * Define any internal version descriptor flags ([vd|vi]_flags).  Note that the
1400  * first byte is reserved for user visible flags (refer VER_FLG's in link.h).
1401  */
1402 #define MSK_VER_USER    0x0f            /* mask for user visible flags */
1403 
1404 #define FLG_VER_AVAIL   0x10            /* version is available for binding */
1405 #define FLG_VER_REFER   0x20            /* version has been referenced */
1406 #define FLG_VER_CYCLIC  0x40            /* a member of cyclic dependency */
1407 
1408 /*
1409  * isalist(1) descriptor - used to break an isalist string into its component
1410  * options.
1411  */
1412 struct  isa_opt {
1413         char            *isa_name;      /* individual isa option name */
1414         size_t          isa_namesz;     /*      and associated size */
1415 };
1416 
1417 struct  isa_desc {
1418         char            *isa_list;      /* sysinfo(SI_ISALIST) list */
1419         size_t          isa_listsz;     /*      and associated size */
1420         Isa_opt         *isa_opt;       /* table of individual isa options */
1421         size_t          isa_optno;      /*      and associated number */
1422 };
1423 
1424 /*
1425  * uname(2) descriptor - used to break a utsname structure into its component
1426  * options (at least those that we're interested in).
1427  */
1428 struct  uts_desc {
1429         char            *uts_osname;    /* operating system name */
1430         size_t          uts_osnamesz;   /*      and associated size */
1431         char            *uts_osrel;     /* operating system release */
1432         size_t          uts_osrelsz;    /*      and associated size */
1433 };
1434 
1435 /*
1436  * SHT_GROUP descriptor - used to track group sections at the global
1437  * level to resolve conflicts and determine which to keep.
1438  */
1439 struct group_desc {
1440         Is_desc         *gd_isc;        /* input section descriptor */
1441         Is_desc         *gd_oisc;       /* overriding input section */
1442                                         /*      descriptor when discarded */
1443         const char      *gd_name;       /* group name (signature symbol) */
1444         Word            *gd_data;       /* data for group section */
1445         size_t          gd_cnt;         /* number of entries in group data */
1446 };
1447 
1448 /*
1449  * Indexes into the ld_support_funcs[] table.
1450  */
1451 typedef enum {
1452         LDS_VERSION = 0,        /* Must be first and have value 0 */
1453         LDS_INPUT_DONE,
1454         LDS_START,
1455         LDS_ATEXIT,
1456         LDS_OPEN,
1457         LDS_FILE,
1458         LDS_INSEC,
1459         LDS_SEC,
1460         LDS_NUM
1461 } Support_ndx;
1462 
1463 /*
1464  * Structure to manage archive member caching.  Each archive has an archive
1465  * descriptor (Ar_desc) associated with it.  This contains pointers to the
1466  * archive symbol table (obtained by elf_getarsyms(3e)) and an auxiliary
1467  * structure (Ar_uax[]) that parallels this symbol table.  The member element
1468  * of this auxiliary table indicates whether the archive member associated with
1469  * the symbol offset has already been extracted (AREXTRACTED) or partially
1470  * processed (refer process_member()).
1471  */
1472 typedef struct ar_mem {
1473         Elf             *am_elf;        /* elf descriptor for this member */
1474         const char      *am_name;       /* members name */
1475         const char      *am_path;       /* path (ie. lib(foo.o)) */
1476         Sym             *am_syms;       /* start of global symbols */
1477         char            *am_strs;       /* associated string table start */
1478         Xword           am_symn;        /* no. of global symbols */
1479 } Ar_mem;
1480 
1481 typedef struct ar_aux {
1482         Sym_desc        *au_syms;       /* internal symbol descriptor */
1483         Ar_mem          *au_mem;        /* associated member */
1484 } Ar_aux;
1485 
1486 #define FLG_ARMEM_PROC  (Ar_mem *)-1
1487 
1488 typedef struct ar_desc {
1489         const char      *ad_name;       /* archive file name */
1490         Elf             *ad_elf;        /* elf descriptor for the archive */
1491         Elf_Arsym       *ad_start;      /* archive symbol table start */
1492         Ar_aux          *ad_aux;        /* auxiliary symbol information */
1493         dev_t           ad_stdev;       /* device id and inode number for */
1494         ino_t           ad_stino;       /*      multiple inclusion checks */
1495         ofl_flag_t      ad_flags;       /* archive specific cmd line flags */
1496 } Ar_desc;
1497 
1498 /*
1499  * Define any archive descriptor flags.  NOTE, make sure they do not clash with
1500  * any output file descriptor archive extraction flags, as these are saved in
1501  * the same entry (see MSK_OF1_ARCHIVE).
1502  */
1503 #define FLG_ARD_EXTRACT 0x00010000      /* archive member has been extracted */
1504 
1505 /* Mapfile versions supported by libld */
1506 #define MFV_NONE        0       /* Not a valid version */
1507 #define MFV_SYSV        1       /* Original System V syntax */
1508 #define MFV_SOLARIS     2       /* Solaris mapfile syntax */
1509 #define MFV_NUM         3       /* # of mapfile versions */
1510 
1511 
1512 /*
1513  * Function Declarations.
1514  */
1515 #if     defined(_ELF64)
1516 
1517 #define ld_create_outfile       ld64_create_outfile
1518 #define ld_ent_setup            ld64_ent_setup
1519 #define ld_init_strings         ld64_init_strings
1520 #define ld_init_target          ld64_init_target
1521 #define ld_make_sections        ld64_make_sections
1522 #define ld_main                 ld64_main
1523 #define ld_ofl_cleanup          ld64_ofl_cleanup
1524 #define ld_process_mem          ld64_process_mem
1525 #define ld_reloc_init           ld64_reloc_init
1526 #define ld_reloc_process        ld64_reloc_process
1527 #define ld_sym_validate         ld64_sym_validate
1528 #define ld_update_outfile       ld64_update_outfile
1529 
1530 #else
1531 
1532 #define ld_create_outfile       ld32_create_outfile
1533 #define ld_ent_setup            ld32_ent_setup
1534 #define ld_init_strings         ld32_init_strings
1535 #define ld_init_target          ld32_init_target
1536 #define ld_make_sections        ld32_make_sections
1537 #define ld_main                 ld32_main
1538 #define ld_ofl_cleanup          ld32_ofl_cleanup
1539 #define ld_process_mem          ld32_process_mem
1540 #define ld_reloc_init           ld32_reloc_init
1541 #define ld_reloc_process        ld32_reloc_process
1542 #define ld_sym_validate         ld32_sym_validate
1543 #define ld_update_outfile       ld32_update_outfile
1544 
1545 #endif
1546 
1547 extern int              ld_getopt(Lm_list *, int, int, char **);
1548 
1549 extern int              ld32_main(int, char **, Half);
1550 extern int              ld64_main(int, char **, Half);
1551 
1552 extern uintptr_t        ld_create_outfile(Ofl_desc *);
1553 extern uintptr_t        ld_ent_setup(Ofl_desc *, Xword);
1554 extern uintptr_t        ld_init_strings(Ofl_desc *);
1555 extern int              ld_init_target(Lm_list *, Half mach);
1556 extern uintptr_t        ld_make_sections(Ofl_desc *);
1557 extern void             ld_ofl_cleanup(Ofl_desc *);
1558 extern Ifl_desc         *ld_process_mem(const char *, const char *, char *,
1559                             size_t, Ofl_desc *, Rej_desc *);
1560 extern uintptr_t        ld_reloc_init(Ofl_desc *);
1561 extern uintptr_t        ld_reloc_process(Ofl_desc *);
1562 extern uintptr_t        ld_sym_validate(Ofl_desc *);
1563 extern uintptr_t        ld_update_outfile(Ofl_desc *);
1564 
1565 #ifdef  __cplusplus
1566 }
1567 #endif
1568 
1569 #endif  /* _LIBLD_H */