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) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * String conversion routine for .dynamic tag entries.
  28  */
  29 #include        <stdio.h>
  30 #include        <string.h>
  31 #include        <sys/elf_SPARC.h>
  32 #include        "rtld.h"
  33 #include        "_conv.h"
  34 #include        "dynamic_msg.h"
  35 
  36 
  37 
  38 const Val_desc *
  39 conv_dyn_posflag1_strings(Conv_fmt_flags_t fmt_flags)
  40 {
  41 #define POSSZ   CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
  42         MSG_DF_P1_LAZYLOAD_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
  43         MSG_DF_P1_GROUPPERM_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
  44         MSG_DF_P1_DEFERRED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
  45         CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
  46 
  47         /*
  48          * Ensure that Conv_dyn_posflag1_buf_t is large enough:
  49          *
  50          * POSSZ is the real minimum size of the buffer required by
  51          * conv_dyn_posflag1(). However, Conv_dyn_posflag1_buf_t uses
  52          * CONV_DYN_POSFLAG1_BUFSIZE to set the buffer size. We do things
  53          * this way because the definition of POSSZ uses
  54          * information that is not available in the environment of other
  55          * programs that include the conv.h header file.
  56          */
  57 #if (CONV_DYN_POSFLAG1_BUFSIZE != POSSZ) && !defined(__lint)
  58 #define REPORT_BUFSIZE POSSZ
  59 #include "report_bufsize.h"
  60 #error "CONV_DYN_POSFLAG1_BUFSIZE does not match POSSZ"
  61 #endif
  62 
  63         static const Val_desc vda_def[] = {
  64                 { DF_P1_LAZYLOAD,       MSG_DF_P1_LAZYLOAD_DEF },
  65                 { DF_P1_GROUPPERM,      MSG_DF_P1_GROUPPERM_DEF },
  66                 { DF_P1_DEFERRED,       MSG_DF_P1_DEFERRED_DEF },
  67                 { 0,                    0 }
  68         };
  69         static const Val_desc vda_cf[] = {
  70                 { DF_P1_LAZYLOAD,       MSG_DF_P1_LAZYLOAD_CF },
  71                 { DF_P1_GROUPPERM,      MSG_DF_P1_GROUPPERM_CF },
  72                 { DF_P1_DEFERRED,       MSG_DF_P1_DEFERRED_CF },
  73                 { 0,                    0 }
  74         };
  75         static const Val_desc vda_cfnp[] = {
  76                 { DF_P1_LAZYLOAD,       MSG_DF_P1_LAZYLOAD_CFNP },
  77                 { DF_P1_GROUPPERM,      MSG_DF_P1_GROUPPERM_CFNP },
  78                 { DF_P1_DEFERRED,       MSG_DF_P1_DEFERRED_CFNP },
  79                 { 0,                    0 }
  80         };
  81         static const Val_desc vda_nf[] = {
  82                 { DF_P1_LAZYLOAD,       MSG_DF_P1_LAZYLOAD_NF },
  83                 { DF_P1_GROUPPERM,      MSG_DF_P1_GROUPPERM_NF },
  84                 { DF_P1_DEFERRED,       MSG_DF_P1_DEFERRED_NF },
  85                 { 0,                    0 }
  86         };
  87 
  88         switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
  89         case CONV_FMT_ALT_DUMP:
  90         case CONV_FMT_ALT_CFNP:
  91                 return (vda_cfnp);
  92         case CONV_FMT_ALT_CF:
  93                 return (vda_cf);
  94         case CONV_FMT_ALT_NF:
  95                 return (vda_nf);
  96         }
  97 
  98         return (vda_def);
  99 }
 100 
 101 conv_iter_ret_t
 102 conv_iter_dyn_posflag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
 103     void *uvalue)
 104 {
 105         return (conv_iter_vd(conv_dyn_posflag1_strings(fmt_flags),
 106             func, uvalue));
 107 }
 108 
 109 const Val_desc *
 110 conv_dyn_flag_strings(Conv_fmt_flags_t fmt_flags)
 111 {
 112 #define FLAGSZ  CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
 113         MSG_DF_ORIGIN_CF_SIZE           + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 114         MSG_DF_SYMBOLIC_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 115         MSG_DF_TEXTREL_CF_SIZE          + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 116         MSG_DF_BIND_NOW_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 117         MSG_DF_STATIC_TLS_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 118         CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 119 
 120         /*
 121          * Ensure that Conv_dyn_flag_buf_t is large enough:
 122          *
 123          * FLAGSZ is the real minimum size of the buffer required by
 124          * conv_dyn_flag(). However, Conv_dyn_flag_buf_t uses
 125          * CONV_DYN_FLAG_BUFSIZE to set the buffer size. We do things this
 126          * way because the definition of FLAGSZ uses information that is not
 127          * available in the environment of other programs that include the
 128          * conv.h header file.
 129          */
 130 #if (CONV_DYN_FLAG_BUFSIZE != FLAGSZ) && !defined(__lint)
 131 #define REPORT_BUFSIZE FLAGSZ
 132 #include "report_bufsize.h"
 133 #error "CONV_DYN_FLAG_BUFSIZE does not match FLAGSZ"
 134 #endif
 135 
 136         static const Val_desc vda_cf[] = {
 137                 { DF_ORIGIN,            MSG_DF_ORIGIN_CF },
 138                 { DF_SYMBOLIC,          MSG_DF_SYMBOLIC_CF },
 139                 { DF_TEXTREL,           MSG_DF_TEXTREL_CF },
 140                 { DF_BIND_NOW,          MSG_DF_BIND_NOW_CF },
 141                 { DF_STATIC_TLS,        MSG_DF_STATIC_TLS_CF },
 142                 { 0 }
 143         };
 144         static const Val_desc vda_cfnp[] = {
 145                 { DF_ORIGIN,            MSG_DF_ORIGIN_CFNP },
 146                 { DF_SYMBOLIC,          MSG_DF_SYMBOLIC_CFNP },
 147                 { DF_TEXTREL,           MSG_DF_TEXTREL_CFNP },
 148                 { DF_BIND_NOW,          MSG_DF_BIND_NOW_CFNP },
 149                 { DF_STATIC_TLS,        MSG_DF_STATIC_TLS_CFNP },
 150                 { 0 }
 151         };
 152         static const Val_desc vda_nf[] = {
 153                 { DF_ORIGIN,            MSG_DF_ORIGIN_NF },
 154                 { DF_SYMBOLIC,          MSG_DF_SYMBOLIC_NF },
 155                 { DF_TEXTREL,           MSG_DF_TEXTREL_NF },
 156                 { DF_BIND_NOW,          MSG_DF_BIND_NOW_NF },
 157                 { DF_STATIC_TLS,        MSG_DF_STATIC_TLS_NF },
 158                 { 0 }
 159         };
 160 
 161         switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
 162         case CONV_FMT_ALT_CF:
 163                 return (vda_cf);
 164         case CONV_FMT_ALT_NF:
 165                 return (vda_nf);
 166         }
 167 
 168         return (vda_cfnp);
 169 }
 170 
 171 conv_iter_ret_t
 172 conv_iter_dyn_flag(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
 173     void *uvalue)
 174 {
 175         return (conv_iter_vd(conv_dyn_flag_strings(fmt_flags), func, uvalue));
 176 }
 177 
 178 const Val_desc *
 179 conv_dyn_flag1_strings(Conv_fmt_flags_t fmt_flags)
 180 {
 181 #define FLAG1SZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
 182         MSG_DF_1_NOW_CF_SIZE            + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 183         MSG_DF_1_GLOBAL_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 184         MSG_DF_1_GROUP_CF_SIZE          + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 185         MSG_DF_1_NODELETE_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 186         MSG_DF_1_LOADFLTR_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 187         MSG_DF_1_INITFIRST_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 188         MSG_DF_1_NOOPEN_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 189         MSG_DF_1_ORIGIN_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 190         MSG_DF_1_DIRECT_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 191         MSG_DF_1_TRANS_CF_SIZE          + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 192         MSG_DF_1_INTERPOSE_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 193         MSG_DF_1_NODEFLIB_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 194         MSG_DF_1_NODUMP_CF_SIZE         + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 195         MSG_DF_1_CONFALT_CF_SIZE        + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 196         MSG_DF_1_ENDFILTEE_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 197         MSG_DF_1_DISPRELPND_CF_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 198         MSG_DF_1_DISPRELDNE_CF_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 199         MSG_DF_1_NODIRECT_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 200         MSG_DF_1_IGNMULDEF_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 201         MSG_DF_1_NOKSYMS_CF_SIZE        + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 202         MSG_DF_1_NOHDR_CF_SIZE          + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 203         MSG_DF_1_NORELOC_CF_SIZE        + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 204         MSG_DF_1_SYMINTPOSE_CF_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 205         MSG_DF_1_GLOBAUDIT_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 206         MSG_DF_1_SINGLETON_CF_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 207         CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 208 
 209         /*
 210          * Ensure that Conv_dyn_flag1_buf_t is large enough:
 211          *
 212          * FLAG1SZ is the real minimum size of the buffer required by
 213          * conv_dyn_flag1(). However, Conv_dyn_flag1_buf_t uses
 214          * CONV_DYN_FLAG1_BUFSIZE to set the buffer size. We do things this
 215          * way because the definition of FLAG1SZ uses information that is not
 216          * available in the environment of other programs that include the
 217          * conv.h header file.
 218          */
 219 #if (CONV_DYN_FLAG1_BUFSIZE != FLAG1SZ) && !defined(__lint)
 220 #define REPORT_BUFSIZE FLAG1SZ
 221 #include "report_bufsize.h"
 222 #error "CONV_DYN_FLAG1_BUFSIZE does not match FLAG1SZ"
 223 #endif
 224 
 225         static const Val_desc vda_def[] = {
 226                 { DF_1_NOW,             MSG_DF_1_NOW_CFNP },
 227                 { DF_1_GLOBAL,          MSG_DF_1_GLOBAL_CFNP },
 228                 { DF_1_GROUP,           MSG_DF_1_GROUP_CFNP },
 229                 { DF_1_NODELETE,        MSG_DF_1_NODELETE_CFNP },
 230                 { DF_1_LOADFLTR,        MSG_DF_1_LOADFLTR_CFNP },
 231                 { DF_1_INITFIRST,       MSG_DF_1_INITFIRST_CFNP },
 232                 { DF_1_NOOPEN,          MSG_DF_1_NOOPEN_CFNP },
 233                 { DF_1_ORIGIN,          MSG_DF_1_ORIGIN_CFNP },
 234                 { DF_1_DIRECT,          MSG_DF_1_DIRECT_CFNP },
 235                 { DF_1_TRANS,           MSG_DF_1_TRANS_CFNP },
 236                 { DF_1_INTERPOSE,       MSG_DF_1_INTERPOSE_DEF },
 237                 { DF_1_NODEFLIB,        MSG_DF_1_NODEFLIB_CFNP },
 238                 { DF_1_NODUMP,          MSG_DF_1_NODUMP_CFNP },
 239                 { DF_1_CONFALT,         MSG_DF_1_CONFALT_CFNP },
 240                 { DF_1_ENDFILTEE,       MSG_DF_1_ENDFILTEE_CFNP },
 241                 { DF_1_DISPRELDNE,      MSG_DF_1_DISPRELDNE_DEF },
 242                 { DF_1_DISPRELPND,      MSG_DF_1_DISPRELPND_DEF },
 243                 { DF_1_NODIRECT,        MSG_DF_1_NODIRECT_CFNP },
 244                 { DF_1_IGNMULDEF,       MSG_DF_1_IGNMULDEF_DEF },
 245                 { DF_1_NOKSYMS,         MSG_DF_1_NOKSYMS_CFNP },
 246                 { DF_1_NOHDR,           MSG_DF_1_NOHDR_CFNP },
 247                 { DF_1_EDITED,          MSG_DF_1_EDITED_CFNP },
 248                 { DF_1_NORELOC,         MSG_DF_1_NORELOC_CFNP },
 249                 { DF_1_SYMINTPOSE,      MSG_DF_1_SYMINTPOSE_DEF },
 250                 { DF_1_GLOBAUDIT,       MSG_DF_1_GLOBAUDIT_DEF },
 251                 { DF_1_SINGLETON,       MSG_DF_1_SINGLETON_DEF },
 252                 { 0,                    0 }
 253         };
 254         static const Val_desc vda_cf[] = {
 255                 { DF_1_NOW,             MSG_DF_1_NOW_CF },
 256                 { DF_1_GLOBAL,          MSG_DF_1_GLOBAL_CF },
 257                 { DF_1_GROUP,           MSG_DF_1_GROUP_CF },
 258                 { DF_1_NODELETE,        MSG_DF_1_NODELETE_CF },
 259                 { DF_1_LOADFLTR,        MSG_DF_1_LOADFLTR_CF },
 260                 { DF_1_INITFIRST,       MSG_DF_1_INITFIRST_CF },
 261                 { DF_1_NOOPEN,          MSG_DF_1_NOOPEN_CF },
 262                 { DF_1_ORIGIN,          MSG_DF_1_ORIGIN_CF },
 263                 { DF_1_DIRECT,          MSG_DF_1_DIRECT_CF },
 264                 { DF_1_TRANS,           MSG_DF_1_TRANS_CF },
 265                 { DF_1_INTERPOSE,       MSG_DF_1_INTERPOSE_CF },
 266                 { DF_1_NODEFLIB,        MSG_DF_1_NODEFLIB_CF },
 267                 { DF_1_NODUMP,          MSG_DF_1_NODUMP_CF },
 268                 { DF_1_CONFALT,         MSG_DF_1_CONFALT_CF },
 269                 { DF_1_ENDFILTEE,       MSG_DF_1_ENDFILTEE_CF },
 270                 { DF_1_DISPRELDNE,      MSG_DF_1_DISPRELDNE_CF },
 271                 { DF_1_DISPRELPND,      MSG_DF_1_DISPRELPND_CF },
 272                 { DF_1_NODIRECT,        MSG_DF_1_NODIRECT_CF },
 273                 { DF_1_IGNMULDEF,       MSG_DF_1_IGNMULDEF_CF },
 274                 { DF_1_NOKSYMS,         MSG_DF_1_NOKSYMS_CF },
 275                 { DF_1_NOHDR,           MSG_DF_1_NOHDR_CF },
 276                 { DF_1_EDITED,          MSG_DF_1_EDITED_CF },
 277                 { DF_1_NORELOC,         MSG_DF_1_NORELOC_CF },
 278                 { DF_1_SYMINTPOSE,      MSG_DF_1_SYMINTPOSE_CF },
 279                 { DF_1_GLOBAUDIT,       MSG_DF_1_GLOBAUDIT_CF },
 280                 { DF_1_SINGLETON,       MSG_DF_1_SINGLETON_CF },
 281                 { 0,                    0 }
 282         };
 283         static const Val_desc vda_cfnp[] = {
 284                 { DF_1_NOW,             MSG_DF_1_NOW_CFNP },
 285                 { DF_1_GLOBAL,          MSG_DF_1_GLOBAL_CFNP },
 286                 { DF_1_GROUP,           MSG_DF_1_GROUP_CFNP },
 287                 { DF_1_NODELETE,        MSG_DF_1_NODELETE_CFNP },
 288                 { DF_1_LOADFLTR,        MSG_DF_1_LOADFLTR_CFNP },
 289                 { DF_1_INITFIRST,       MSG_DF_1_INITFIRST_CFNP },
 290                 { DF_1_NOOPEN,          MSG_DF_1_NOOPEN_CFNP },
 291                 { DF_1_ORIGIN,          MSG_DF_1_ORIGIN_CFNP },
 292                 { DF_1_DIRECT,          MSG_DF_1_DIRECT_CFNP },
 293                 { DF_1_TRANS,           MSG_DF_1_TRANS_CFNP },
 294                 { DF_1_INTERPOSE,       MSG_DF_1_INTERPOSE_CFNP },
 295                 { DF_1_NODEFLIB,        MSG_DF_1_NODEFLIB_CFNP },
 296                 { DF_1_NODUMP,          MSG_DF_1_NODUMP_CFNP },
 297                 { DF_1_CONFALT,         MSG_DF_1_CONFALT_CFNP },
 298                 { DF_1_ENDFILTEE,       MSG_DF_1_ENDFILTEE_CFNP },
 299                 { DF_1_DISPRELDNE,      MSG_DF_1_DISPRELDNE_CFNP },
 300                 { DF_1_DISPRELPND,      MSG_DF_1_DISPRELPND_CFNP },
 301                 { DF_1_NODIRECT,        MSG_DF_1_NODIRECT_CFNP },
 302                 { DF_1_IGNMULDEF,       MSG_DF_1_IGNMULDEF_CFNP },
 303                 { DF_1_NOKSYMS,         MSG_DF_1_NOKSYMS_CFNP },
 304                 { DF_1_NOHDR,           MSG_DF_1_NOHDR_CFNP },
 305                 { DF_1_EDITED,          MSG_DF_1_EDITED_CFNP },
 306                 { DF_1_NORELOC,         MSG_DF_1_NORELOC_CFNP },
 307                 { DF_1_SYMINTPOSE,      MSG_DF_1_SYMINTPOSE_CFNP },
 308                 { DF_1_GLOBAUDIT,       MSG_DF_1_GLOBAUDIT_CFNP },
 309                 { DF_1_SINGLETON,       MSG_DF_1_SINGLETON_CFNP },
 310                 { 0,                    0 }
 311         };
 312         static const Val_desc vda_nf[] = {
 313                 { DF_1_NOW,             MSG_DF_1_NOW_NF },
 314                 { DF_1_GLOBAL,          MSG_DF_1_GLOBAL_NF },
 315                 { DF_1_GROUP,           MSG_DF_1_GROUP_NF },
 316                 { DF_1_NODELETE,        MSG_DF_1_NODELETE_NF },
 317                 { DF_1_LOADFLTR,        MSG_DF_1_LOADFLTR_NF },
 318                 { DF_1_INITFIRST,       MSG_DF_1_INITFIRST_NF },
 319                 { DF_1_NOOPEN,          MSG_DF_1_NOOPEN_NF },
 320                 { DF_1_ORIGIN,          MSG_DF_1_ORIGIN_NF },
 321                 { DF_1_DIRECT,          MSG_DF_1_DIRECT_NF },
 322                 { DF_1_TRANS,           MSG_DF_1_TRANS_NF },
 323                 { DF_1_INTERPOSE,       MSG_DF_1_INTERPOSE_NF },
 324                 { DF_1_NODEFLIB,        MSG_DF_1_NODEFLIB_NF },
 325                 { DF_1_NODUMP,          MSG_DF_1_NODUMP_NF },
 326                 { DF_1_CONFALT,         MSG_DF_1_CONFALT_NF },
 327                 { DF_1_ENDFILTEE,       MSG_DF_1_ENDFILTEE_NF },
 328                 { DF_1_DISPRELDNE,      MSG_DF_1_DISPRELDNE_NF },
 329                 { DF_1_DISPRELPND,      MSG_DF_1_DISPRELPND_NF },
 330                 { DF_1_NODIRECT,        MSG_DF_1_NODIRECT_NF },
 331                 { DF_1_IGNMULDEF,       MSG_DF_1_IGNMULDEF_NF },
 332                 { DF_1_NOKSYMS,         MSG_DF_1_NOKSYMS_NF },
 333                 { DF_1_NOHDR,           MSG_DF_1_NOHDR_NF },
 334                 { DF_1_EDITED,          MSG_DF_1_EDITED_NF },
 335                 { DF_1_NORELOC,         MSG_DF_1_NORELOC_NF },
 336                 { DF_1_SYMINTPOSE,      MSG_DF_1_SYMINTPOSE_NF },
 337                 { DF_1_GLOBAUDIT,       MSG_DF_1_GLOBAUDIT_NF },
 338                 { DF_1_SINGLETON,       MSG_DF_1_SINGLETON_NF },
 339                 { 0,                    0 }
 340         };
 341 
 342         switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
 343         case CONV_FMT_ALT_CF:
 344                 return (vda_cf);
 345         case CONV_FMT_ALT_CFNP:
 346                 return (vda_cfnp);
 347         case CONV_FMT_ALT_NF:
 348                 return (vda_nf);
 349         }
 350 
 351         return (vda_def);
 352 }
 353 
 354 conv_iter_ret_t
 355 conv_iter_dyn_flag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
 356     void *uvalue)
 357 {
 358         return (conv_iter_vd(conv_dyn_flag1_strings(fmt_flags), func, uvalue));
 359 }
 360 
 361 const Val_desc *
 362 conv_dyn_feature1_strings(Conv_fmt_flags_t fmt_flags)
 363 {
 364 #define FEATSZ  CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
 365         MSG_DTF_1_PARINIT_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 366         MSG_DTF_1_CONFEXP_CF_SIZE       + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 367         CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 368 
 369         /*
 370          * Ensure that Conv_dyn_feature1_buf_t is large enough:
 371          *
 372          * FEATSZ is the real min size of the buffer required by
 373          * conv_dyn_feature1(). However, Conv_dyn_feature1_buf_t uses
 374          * CONV_DYN_FEATURE1_BUFSIZE to set the buffer size. We do things
 375          * this way because the definition of FEATSZ uses information that
 376          * is not available in the environment of other programs that include
 377          * the conv.h header file.
 378          */
 379 #if (CONV_DYN_FEATURE1_BUFSIZE != FEATSZ) && !defined(__lint)
 380 #define REPORT_BUFSIZE FEATSZ
 381 #include "report_bufsize.h"
 382 #error "CONV_DYN_FEATURE1_BUFSIZE does not match FEATSZ"
 383 #endif
 384 
 385         static const Val_desc vda_cf[] = {
 386                 { DTF_1_PARINIT,        MSG_DTF_1_PARINIT_CF },
 387                 { DTF_1_CONFEXP,        MSG_DTF_1_CONFEXP_CF },
 388                 { 0,                    0 }
 389         };
 390         static const Val_desc vda_cfnp[] = {
 391                 { DTF_1_PARINIT,        MSG_DTF_1_PARINIT_CFNP },
 392                 { DTF_1_CONFEXP,        MSG_DTF_1_CONFEXP_CFNP },
 393                 { 0,                    0 }
 394         };
 395         static const Val_desc vda_nf[] = {
 396                 { DTF_1_PARINIT,        MSG_DTF_1_PARINIT_NF },
 397                 { DTF_1_CONFEXP,        MSG_DTF_1_CONFEXP_NF },
 398                 { 0,                    0 }
 399         };
 400 
 401         switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
 402         case CONV_FMT_ALT_CF:
 403                 return (vda_cf);
 404         case CONV_FMT_ALT_NF:
 405                 return (vda_nf);
 406         }
 407 
 408         return (vda_cfnp);
 409 }
 410 
 411 conv_iter_ret_t
 412 conv_iter_dyn_feature1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
 413     void *uvalue)
 414 {
 415         return (conv_iter_vd(conv_dyn_feature1_strings(fmt_flags),
 416             func, uvalue));
 417 }
 418 
 419 const conv_ds_t **
 420 conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
 421     Conv_fmt_flags_t fmt_flags)
 422 {
 423         /*
 424          * Maximum # of items that can be in the returned array. Size this
 425          * by counting the maximum depth in the switch statement that fills
 426          * retarr at the end of this function.
 427          */
 428 #define MAX_RET 12
 429 
 430         /*
 431          * Generic dynamic tags:
 432          * -    Note hole between DT_FLAGS and DT_PREINIT_ARRAY (tag 32).
 433          *      We use a 0, which is the signal for "not defined".
 434          * -    This range has alternative names for dump, requiring an
 435          *      additional array.
 436          */
 437         static const Msg        tags_null_cf[] = {
 438                 MSG_DT_NULL_CF,                 MSG_DT_NEEDED_CF,
 439                 MSG_DT_PLTRELSZ_CF,             MSG_DT_PLTGOT_CF,
 440                 MSG_DT_HASH_CF,                 MSG_DT_STRTAB_CF,
 441                 MSG_DT_SYMTAB_CF,               MSG_DT_RELA_CF,
 442                 MSG_DT_RELASZ_CF,               MSG_DT_RELAENT_CF,
 443                 MSG_DT_STRSZ_CF,                MSG_DT_SYMENT_CF,
 444                 MSG_DT_INIT_CF,                 MSG_DT_FINI_CF,
 445                 MSG_DT_SONAME_CF,               MSG_DT_RPATH_CF,
 446                 MSG_DT_SYMBOLIC_CF,             MSG_DT_REL_CF,
 447                 MSG_DT_RELSZ_CF,                MSG_DT_RELENT_CF,
 448                 MSG_DT_PLTREL_CF,               MSG_DT_DEBUG_CF,
 449                 MSG_DT_TEXTREL_CF,              MSG_DT_JMPREL_CF,
 450                 MSG_DT_BIND_NOW_CF,             MSG_DT_INIT_ARRAY_CF,
 451                 MSG_DT_FINI_ARRAY_CF,           MSG_DT_INIT_ARRAYSZ_CF,
 452                 MSG_DT_FINI_ARRAYSZ_CF,         MSG_DT_RUNPATH_CF,
 453                 MSG_DT_FLAGS_CF,                0,
 454                 MSG_DT_PREINIT_ARRAY_CF,        MSG_DT_PREINIT_ARRAYSZ_CF
 455         };
 456         static const Msg        tags_null_cfnp[] = {
 457                 MSG_DT_NULL_CFNP,               MSG_DT_NEEDED_CFNP,
 458                 MSG_DT_PLTRELSZ_CFNP,           MSG_DT_PLTGOT_CFNP,
 459                 MSG_DT_HASH_CFNP,               MSG_DT_STRTAB_CFNP,
 460                 MSG_DT_SYMTAB_CFNP,             MSG_DT_RELA_CFNP,
 461                 MSG_DT_RELASZ_CFNP,             MSG_DT_RELAENT_CFNP,
 462                 MSG_DT_STRSZ_CFNP,              MSG_DT_SYMENT_CFNP,
 463                 MSG_DT_INIT_CFNP,               MSG_DT_FINI_CFNP,
 464                 MSG_DT_SONAME_CFNP,             MSG_DT_RPATH_CFNP,
 465                 MSG_DT_SYMBOLIC_CFNP,           MSG_DT_REL_CFNP,
 466                 MSG_DT_RELSZ_CFNP,              MSG_DT_RELENT_CFNP,
 467                 MSG_DT_PLTREL_CFNP,             MSG_DT_DEBUG_CFNP,
 468                 MSG_DT_TEXTREL_CFNP,            MSG_DT_JMPREL_CFNP,
 469                 MSG_DT_BIND_NOW_CFNP,           MSG_DT_INIT_ARRAY_CFNP,
 470                 MSG_DT_FINI_ARRAY_CFNP,         MSG_DT_INIT_ARRAYSZ_CFNP,
 471                 MSG_DT_FINI_ARRAYSZ_CFNP,       MSG_DT_RUNPATH_CFNP,
 472                 MSG_DT_FLAGS_CFNP,              0,
 473                 MSG_DT_PREINIT_ARRAY_CFNP,      MSG_DT_PREINIT_ARRAYSZ_CFNP
 474         };
 475         static const Msg        tags_null_nf[] = {
 476                 MSG_DT_NULL_NF,                 MSG_DT_NEEDED_NF,
 477                 MSG_DT_PLTRELSZ_NF,             MSG_DT_PLTGOT_NF,
 478                 MSG_DT_HASH_NF,                 MSG_DT_STRTAB_NF,
 479                 MSG_DT_SYMTAB_NF,               MSG_DT_RELA_NF,
 480                 MSG_DT_RELASZ_NF,               MSG_DT_RELAENT_NF,
 481                 MSG_DT_STRSZ_NF,                MSG_DT_SYMENT_NF,
 482                 MSG_DT_INIT_NF,                 MSG_DT_FINI_NF,
 483                 MSG_DT_SONAME_NF,               MSG_DT_RPATH_NF,
 484                 MSG_DT_SYMBOLIC_NF,             MSG_DT_REL_NF,
 485                 MSG_DT_RELSZ_NF,                MSG_DT_RELENT_NF,
 486                 MSG_DT_PLTREL_NF,               MSG_DT_DEBUG_NF,
 487                 MSG_DT_TEXTREL_NF,              MSG_DT_JMPREL_NF,
 488                 MSG_DT_BIND_NOW_NF,             MSG_DT_INIT_ARRAY_NF,
 489                 MSG_DT_FINI_ARRAY_NF,           MSG_DT_INIT_ARRAYSZ_NF,
 490                 MSG_DT_FINI_ARRAYSZ_NF,         MSG_DT_RUNPATH_NF,
 491                 MSG_DT_FLAGS_NF,                0,
 492                 MSG_DT_PREINIT_ARRAY_NF,        MSG_DT_PREINIT_ARRAYSZ_NF
 493         };
 494         static const Msg        tags_null_dmp[] = {
 495                 MSG_DT_NULL_CFNP,               MSG_DT_NEEDED_CFNP,
 496                 MSG_DT_PLTRELSZ_DMP,            MSG_DT_PLTGOT_CFNP,
 497                 MSG_DT_HASH_CFNP,               MSG_DT_STRTAB_CFNP,
 498                 MSG_DT_SYMTAB_CFNP,             MSG_DT_RELA_CFNP,
 499                 MSG_DT_RELASZ_CFNP,             MSG_DT_RELAENT_CFNP,
 500                 MSG_DT_STRSZ_CFNP,              MSG_DT_SYMENT_CFNP,
 501                 MSG_DT_INIT_CFNP,               MSG_DT_FINI_CFNP,
 502                 MSG_DT_SONAME_CFNP,             MSG_DT_RPATH_CFNP,
 503                 MSG_DT_SYMBOLIC_DMP,            MSG_DT_REL_CFNP,
 504                 MSG_DT_RELSZ_CFNP,              MSG_DT_RELENT_CFNP,
 505                 MSG_DT_PLTREL_CFNP,             MSG_DT_DEBUG_CFNP,
 506                 MSG_DT_TEXTREL_CFNP,            MSG_DT_JMPREL_CFNP,
 507                 MSG_DT_BIND_NOW_CFNP,           MSG_DT_INIT_ARRAY_CFNP,
 508                 MSG_DT_FINI_ARRAY_CFNP,         MSG_DT_INIT_ARRAYSZ_CFNP,
 509                 MSG_DT_FINI_ARRAYSZ_CFNP,       MSG_DT_RUNPATH_CFNP,
 510                 MSG_DT_FLAGS_CFNP,              0,
 511                 MSG_DT_PREINIT_ARRAY_CFNP,      MSG_DT_PREINIT_ARRAYSZ_CFNP
 512         };
 513         static const conv_ds_msg_t ds_null_cf = {
 514             CONV_DS_MSG_INIT(DT_NULL, tags_null_cf) };
 515         static const conv_ds_msg_t ds_null_cfnp = {
 516             CONV_DS_MSG_INIT(DT_NULL, tags_null_cfnp) };
 517         static const conv_ds_msg_t ds_null_nf = {
 518             CONV_DS_MSG_INIT(DT_NULL, tags_null_nf) };
 519         static const conv_ds_msg_t ds_null_dmp = {
 520             CONV_DS_MSG_INIT(DT_NULL, tags_null_dmp) };
 521 
 522         /*
 523          * DT_SPARC_REGISTER was originally assigned 0x7000001. It is processor
 524          * specific, and should have been in the range DT_LOPROC-DT_HIPROC
 525          * instead of here. When the error was fixed,
 526          * DT_DEPRECATED_SPARC_REGISTER was created to maintain backward
 527          * compatability.
 528          */
 529         static const Msg        tags_sdreg_cf[] = {
 530             MSG_DT_DEP_SPARC_REG_CF };
 531         static const Msg        tags_sdreg_cfnp[] = {
 532             MSG_DT_DEP_SPARC_REG_CFNP };
 533         static const Msg        tags_sdreg_nf[] = {
 534             MSG_DT_DEP_SPARC_REG_NF };
 535 
 536         static const conv_ds_msg_t ds_sdreg_cf = {
 537             CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cf) };
 538         static const conv_ds_msg_t ds_sdreg_cfnp = {
 539             CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cfnp) };
 540         static const conv_ds_msg_t ds_sdreg_nf = {
 541             CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_nf) };
 542 
 543 
 544         /*
 545          * SUNW: DT_LOOS -> DT_HIOS range. Note holes between DT_SUNW_TLSSORTSZ,
 546          * DT_SUNW_STRPAD, and DT_SUNW_LDMACH. We handle the outliers
 547          * separately below as single values.
 548          */
 549         static const Msg        tags_sunw_auxiliary_cf[] = {
 550                 MSG_DT_SUNW_AUXILIARY_CF,       MSG_DT_SUNW_RTLDINF_CF,
 551                 MSG_DT_SUNW_FILTER_CF,          MSG_DT_SUNW_CAP_CF,
 552                 MSG_DT_SUNW_SYMTAB_CF,          MSG_DT_SUNW_SYMSZ_CF,
 553                 MSG_DT_SUNW_SORTENT_CF,         MSG_DT_SUNW_SYMSORT_CF,
 554                 MSG_DT_SUNW_SYMSORTSZ_CF,       MSG_DT_SUNW_TLSSORT_CF,
 555                 MSG_DT_SUNW_TLSSORTSZ_CF,       MSG_DT_SUNW_CAPINFO_CF,
 556                 MSG_DT_SUNW_STRPAD_CF,          MSG_DT_SUNW_CAPCHAIN_CF,
 557                 MSG_DT_SUNW_LDMACH_CF,          0,
 558                 MSG_DT_SUNW_CAPCHAINENT_CF,     0,
 559                 MSG_DT_SUNW_CAPCHAINSZ_CF,      0,
 560                 0,                              0,
 561                 MSG_DT_SUNW_ASLR_CF
 562         };
 563         static const Msg        tags_sunw_auxiliary_cfnp[] = {
 564                 MSG_DT_SUNW_AUXILIARY_CFNP,     MSG_DT_SUNW_RTLDINF_CFNP,
 565                 MSG_DT_SUNW_FILTER_CFNP,        MSG_DT_SUNW_CAP_CFNP,
 566                 MSG_DT_SUNW_SYMTAB_CFNP,        MSG_DT_SUNW_SYMSZ_CFNP,
 567                 MSG_DT_SUNW_SORTENT_CFNP,       MSG_DT_SUNW_SYMSORT_CFNP,
 568                 MSG_DT_SUNW_SYMSORTSZ_CFNP,     MSG_DT_SUNW_TLSSORT_CFNP,
 569                 MSG_DT_SUNW_TLSSORTSZ_CFNP,     MSG_DT_SUNW_CAPINFO_CFNP,
 570                 MSG_DT_SUNW_STRPAD_CFNP,        MSG_DT_SUNW_CAPCHAIN_CFNP,
 571                 MSG_DT_SUNW_LDMACH_CFNP,        0,
 572                 MSG_DT_SUNW_CAPCHAINENT_CFNP,   0,
 573                 MSG_DT_SUNW_CAPCHAINSZ_CFNP,    0,
 574                 0,                              0,
 575                 MSG_DT_SUNW_ASLR_CFNP
 576         };
 577         static const Msg        tags_sunw_auxiliary_nf[] = {
 578                 MSG_DT_SUNW_AUXILIARY_NF,       MSG_DT_SUNW_RTLDINF_NF,
 579                 MSG_DT_SUNW_FILTER_NF,          MSG_DT_SUNW_CAP_NF,
 580                 MSG_DT_SUNW_SYMTAB_NF,          MSG_DT_SUNW_SYMSZ_NF,
 581                 MSG_DT_SUNW_SORTENT_NF,         MSG_DT_SUNW_SYMSORT_NF,
 582                 MSG_DT_SUNW_SYMSORTSZ_NF,       MSG_DT_SUNW_TLSSORT_NF,
 583                 MSG_DT_SUNW_TLSSORTSZ_NF,       MSG_DT_SUNW_CAPINFO_NF,
 584                 MSG_DT_SUNW_STRPAD_NF,          MSG_DT_SUNW_CAPCHAIN_NF,
 585                 MSG_DT_SUNW_LDMACH_NF,          0,
 586                 MSG_DT_SUNW_CAPCHAINENT_NF,     0,
 587                 MSG_DT_SUNW_CAPCHAINSZ_NF,      0,
 588                 0,                              0,
 589                 MSG_DT_SUNW_ASLR_NF
 590         };
 591         static const conv_ds_msg_t ds_sunw_auxiliary_cf = {
 592             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cf) };
 593         static const conv_ds_msg_t ds_sunw_auxiliary_cfnp = {
 594             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cfnp) };
 595         static const conv_ds_msg_t ds_sunw_auxiliary_nf = {
 596             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_nf) };
 597 
 598         /*
 599          * GNU: (In DT_VALRNGLO section) DT_GNU_PRELINKED - DT_GNU_LIBLISTSZ
 600          */
 601         static const Msg        tags_gnu_prelinked_cf[] = {
 602                 MSG_DT_GNU_PRELINKED_CF,        MSG_DT_GNU_CONFLICTSZ_CF,
 603                 MSG_DT_GNU_LIBLISTSZ_CF
 604         };
 605         static const Msg        tags_gnu_prelinked_cfnp[] = {
 606                 MSG_DT_GNU_PRELINKED_CFNP,      MSG_DT_GNU_CONFLICTSZ_CFNP,
 607                 MSG_DT_GNU_LIBLISTSZ_CFNP
 608         };
 609         static const Msg        tags_gnu_prelinked_nf[] = {
 610                 MSG_DT_GNU_PRELINKED_NF,        MSG_DT_GNU_CONFLICTSZ_NF,
 611                 MSG_DT_GNU_LIBLISTSZ_NF
 612         };
 613         static const conv_ds_msg_t ds_gnu_prelinked_cf = {
 614             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cf) };
 615         static const conv_ds_msg_t ds_gnu_prelinked_cfnp = {
 616             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cfnp) };
 617         static const conv_ds_msg_t ds_gnu_prelinked_nf = {
 618             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_nf) };
 619 
 620         /*
 621          * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
 622          */
 623         static const Msg        tags_checksum_cf[] = {
 624                 MSG_DT_CHECKSUM_CF,             MSG_DT_PLTPADSZ_CF,
 625                 MSG_DT_MOVEENT_CF,              MSG_DT_MOVESZ_CF,
 626                 MSG_DT_FEATURE_1_CF,            MSG_DT_POSFLAG_1_CF,
 627                 MSG_DT_SYMINSZ_CF,              MSG_DT_SYMINENT_CF
 628         };
 629         static const Msg        tags_checksum_cfnp[] = {
 630                 MSG_DT_CHECKSUM_CFNP,           MSG_DT_PLTPADSZ_CFNP,
 631                 MSG_DT_MOVEENT_CFNP,            MSG_DT_MOVESZ_CFNP,
 632                 MSG_DT_FEATURE_1_CFNP,          MSG_DT_POSFLAG_1_CFNP,
 633                 MSG_DT_SYMINSZ_CFNP,            MSG_DT_SYMINENT_CFNP
 634         };
 635         static const Msg        tags_checksum_nf[] = {
 636                 MSG_DT_CHECKSUM_NF,             MSG_DT_PLTPADSZ_NF,
 637                 MSG_DT_MOVEENT_NF,              MSG_DT_MOVESZ_NF,
 638                 MSG_DT_FEATURE_1_NF,            MSG_DT_POSFLAG_1_NF,
 639                 MSG_DT_SYMINSZ_NF,              MSG_DT_SYMINENT_NF
 640         };
 641         static const conv_ds_msg_t ds_checksum_cf = {
 642             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cf) };
 643         static const conv_ds_msg_t ds_checksum_cfnp = {
 644             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cfnp) };
 645         static const conv_ds_msg_t ds_checksum_nf = {
 646             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_nf) };
 647 
 648         /*
 649          * GNU: (In DT_ADDRRNGLO section) DT_GNU_HASH - DT_GNU_LIBLIST
 650          */
 651         static const Msg        tags_gnu_hash_cf[] = {
 652                 MSG_DT_GNU_HASH_CF,             MSG_DT_TLSDESC_PLT_CF,
 653                 MSG_DT_TLSDESC_GOT_CF,          MSG_DT_GNU_CONFLICT_CF,
 654                 MSG_DT_GNU_LIBLIST_CF
 655         };
 656         static const Msg        tags_gnu_hash_cfnp[] = {
 657                 MSG_DT_GNU_HASH_CFNP,           MSG_DT_TLSDESC_PLT_CFNP,
 658                 MSG_DT_TLSDESC_GOT_CFNP,        MSG_DT_GNU_CONFLICT_CFNP,
 659                 MSG_DT_GNU_LIBLIST_CFNP
 660         };
 661         static const Msg        tags_gnu_hash_nf[] = {
 662                 MSG_DT_GNU_HASH_NF,             MSG_DT_TLSDESC_PLT_NF,
 663                 MSG_DT_TLSDESC_GOT_NF,          MSG_DT_GNU_CONFLICT_NF,
 664                 MSG_DT_GNU_LIBLIST_NF
 665         };
 666         static const conv_ds_msg_t ds_gnu_hash_cf = {
 667             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cf) };
 668         static const conv_ds_msg_t ds_gnu_hash_cfnp = {
 669             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cfnp) };
 670         static const conv_ds_msg_t ds_gnu_hash_nf = {
 671             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_nf) };
 672 
 673         /*
 674          * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
 675          */
 676         static const Msg        tags_config_cf[] = {
 677                 MSG_DT_CONFIG_CF,               MSG_DT_DEPAUDIT_CF,
 678                 MSG_DT_AUDIT_CF,                MSG_DT_PLTPAD_CF,
 679                 MSG_DT_MOVETAB_CF,              MSG_DT_SYMINFO_CF
 680         };
 681         static const Msg        tags_config_cfnp[] = {
 682                 MSG_DT_CONFIG_CFNP,             MSG_DT_DEPAUDIT_CFNP,
 683                 MSG_DT_AUDIT_CFNP,              MSG_DT_PLTPAD_CFNP,
 684                 MSG_DT_MOVETAB_CFNP,            MSG_DT_SYMINFO_CFNP
 685         };
 686         static const Msg        tags_config_nf[] = {
 687                 MSG_DT_CONFIG_NF,               MSG_DT_DEPAUDIT_NF,
 688                 MSG_DT_AUDIT_NF,                MSG_DT_PLTPAD_NF,
 689                 MSG_DT_MOVETAB_NF,              MSG_DT_SYMINFO_NF
 690         };
 691         static const conv_ds_msg_t ds_config_cf = {
 692             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cf) };
 693         static const conv_ds_msg_t ds_config_cfnp = {
 694             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cfnp) };
 695         static const conv_ds_msg_t ds_config_nf = {
 696             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_nf) };
 697 
 698         /*
 699          * SUNW: generic range. Note hole between DT_VERSYM and DT_RELACOUNT.
 700          */
 701         static const Msg        tags_versym_cf[] = { MSG_DT_VERSYM_CF };
 702         static const Msg        tags_versym_cfnp[] = { MSG_DT_VERSYM_CFNP };
 703         static const Msg        tags_versym_nf[] = { MSG_DT_VERSYM_NF };
 704         static const conv_ds_msg_t ds_versym_cf = {
 705             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cf) };
 706         static const conv_ds_msg_t ds_versym_cfnp = {
 707             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cfnp) };
 708         static const conv_ds_msg_t ds_versym_nf = {
 709             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_nf) };
 710 
 711         static const Msg        tags_relacount_cf[] = {
 712                 MSG_DT_RELACOUNT_CF,            MSG_DT_RELCOUNT_CF,
 713                 MSG_DT_FLAGS_1_CF,              MSG_DT_VERDEF_CF,
 714                 MSG_DT_VERDEFNUM_CF,            MSG_DT_VERNEED_CF,
 715                 MSG_DT_VERNEEDNUM_CF
 716         };
 717         static const Msg        tags_relacount_cfnp[] = {
 718                 MSG_DT_RELACOUNT_CFNP,          MSG_DT_RELCOUNT_CFNP,
 719                 MSG_DT_FLAGS_1_CFNP,            MSG_DT_VERDEF_CFNP,
 720                 MSG_DT_VERDEFNUM_CFNP,          MSG_DT_VERNEED_CFNP,
 721                 MSG_DT_VERNEEDNUM_CFNP
 722         };
 723         static const Msg        tags_relacount_nf[] = {
 724                 MSG_DT_RELACOUNT_NF,            MSG_DT_RELCOUNT_NF,
 725                 MSG_DT_FLAGS_1_NF,              MSG_DT_VERDEF_NF,
 726                 MSG_DT_VERDEFNUM_NF,            MSG_DT_VERNEED_NF,
 727                 MSG_DT_VERNEEDNUM_NF
 728         };
 729         static const conv_ds_msg_t ds_relacount_cf = {
 730             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cf) };
 731         static const conv_ds_msg_t ds_relacount_cfnp = {
 732             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cfnp) };
 733         static const conv_ds_msg_t ds_relacount_nf = {
 734             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_nf) };
 735 
 736         /*
 737          * DT_LOPROC - DT_HIPROC range: solaris/sparc-only
 738          */
 739         static const Msg tags_sparc_reg_cf[] = { MSG_DT_SPARC_REGISTER_CF };
 740         static const Msg tags_sparc_reg_cfnp[] = { MSG_DT_SPARC_REGISTER_CFNP };
 741         static const Msg tags_sparc_reg_nf[] = { MSG_DT_SPARC_REGISTER_NF };
 742         static const Msg tags_sparc_reg_dmp[] = { MSG_DT_SPARC_REGISTER_DMP };
 743         static const conv_ds_msg_t ds_sparc_reg_cf = {
 744             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cf) };
 745         static const conv_ds_msg_t ds_sparc_reg_cfnp = {
 746             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cfnp) };
 747         static const conv_ds_msg_t ds_sparc_reg_nf = {
 748             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_nf) };
 749         static const conv_ds_msg_t ds_sparc_reg_dmp = {
 750             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_dmp) };
 751 
 752         /*
 753          * DT_LOPROC - DT_HIPROC range: Solaris osabi, all hardware
 754          */
 755         static const Msg        tags_auxiliary_cf[] = {
 756                 MSG_DT_AUXILIARY_CF,    MSG_DT_USED_CF,
 757                 MSG_DT_FILTER_CF
 758         };
 759         static const Msg        tags_auxiliary_cfnp[] = {
 760                 MSG_DT_AUXILIARY_CFNP,  MSG_DT_USED_CFNP,
 761                 MSG_DT_FILTER_CFNP
 762         };
 763         static const Msg        tags_auxiliary_nf[] = {
 764                 MSG_DT_AUXILIARY_NF,    MSG_DT_USED_NF,
 765                 MSG_DT_FILTER_NF
 766         };
 767         static const conv_ds_msg_t ds_auxiliary_cf = {
 768             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cf) };
 769         static const conv_ds_msg_t ds_auxiliary_cfnp = {
 770             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cfnp) };
 771         static const conv_ds_msg_t ds_auxiliary_nf = {
 772             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_nf) };
 773 
 774 
 775         static const conv_ds_t  *retarr[MAX_RET];
 776 
 777         int     ndx = 0;
 778         int     fmt_osabi = CONV_TYPE_FMT_ALT(fmt_flags);
 779         int     mach_sparc, osabi_solaris, osabi_linux;
 780 
 781 
 782 
 783         osabi_solaris = (osabi == ELFOSABI_NONE) ||
 784             (osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL);
 785         osabi_linux = (osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL);
 786         mach_sparc = (mach == EM_SPARC) || (mach == EM_SPARCV9) ||
 787             (mach == EM_SPARC32PLUS) || (mach == CONV_MACH_ALL);
 788 
 789         /*
 790          * Fill in retarr with the descriptors for the messages that
 791          * apply to the current osabi. Note that we order these items such
 792          * that the more common are placed at the beginning, and the less
 793          * likely at the end. This should speed the common case.
 794          *
 795          * Note that the CFNP and DMP styles are very similar, so they
 796          * are combined in 'default', and fmt_osabi is consulted when there
 797          * are differences.
 798          */
 799         switch (fmt_osabi) {
 800         case CONV_FMT_ALT_CF:
 801                 retarr[ndx++] = CONV_DS_ADDR(ds_null_cf);
 802                 if (osabi_solaris)
 803                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cf);
 804                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cf);
 805                 retarr[ndx++] = CONV_DS_ADDR(ds_config_cf);
 806                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_cf);
 807                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cf);
 808                 if (osabi_solaris) {
 809                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cf);
 810                         if (mach_sparc) {
 811                                 retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_cf);
 812                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cf);
 813                         }
 814                 }
 815                 if (osabi_linux) {
 816                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cf);
 817                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cf);
 818                 }
 819                 break;
 820 
 821         case CONV_FMT_ALT_NF:
 822                 retarr[ndx++] = CONV_DS_ADDR(ds_null_nf);
 823                 if (osabi_solaris)
 824                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_nf);
 825                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_nf);
 826                 retarr[ndx++] = CONV_DS_ADDR(ds_config_nf);
 827                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_nf);
 828                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_nf);
 829                 if (osabi_solaris) {
 830                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_nf);
 831                         if (mach_sparc) {
 832                                 retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_nf);
 833                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_nf);
 834                         }
 835                 }
 836                 if (osabi_linux) {
 837                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_nf);
 838                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_nf);
 839                 }
 840                 break;
 841         default:
 842                 /*
 843                  * The default style for the generic range is CFNP,
 844                  * while dump has a couple of different strings.
 845                  */
 846 
 847                 retarr[ndx++] = (fmt_osabi == CONV_FMT_ALT_DUMP) ?
 848                     CONV_DS_ADDR(ds_null_dmp) : CONV_DS_ADDR(ds_null_cfnp);
 849                 if (osabi_solaris)
 850                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cfnp);
 851                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cfnp);
 852                 retarr[ndx++] = CONV_DS_ADDR(ds_config_cfnp);
 853                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_cfnp);
 854                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cfnp);
 855                 if (osabi_solaris) {
 856                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cfnp);
 857                         if (mach_sparc) {
 858                                 /*
 859                                  * The default style for DT_SPARC_REGISTER
 860                                  * is the dump style, which omits the 'SPARC_'.
 861                                  * CFNP keeps the prefix.
 862                                  */
 863                                 retarr[ndx++] =
 864                                     (fmt_osabi == CONV_FMT_ALT_CFNP) ?
 865                                     CONV_DS_ADDR(ds_sparc_reg_cfnp) :
 866                                     CONV_DS_ADDR(ds_sparc_reg_dmp);
 867                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cfnp);
 868                         }
 869                 }
 870                 if (osabi_linux) {
 871                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cfnp);
 872                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cfnp);
 873                 }
 874                 break;
 875         }
 876 
 877         retarr[ndx++] = NULL;
 878         assert(ndx <= MAX_RET);
 879         return (retarr);
 880 }
 881 
 882 conv_iter_ret_t
 883 conv_iter_dyn_tag(conv_iter_osabi_t osabi, Half mach,
 884     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
 885 {
 886         return (conv_iter_ds(osabi, mach,
 887             conv_dyn_tag_strings(osabi, mach, fmt_flags), func, uvalue));
 888 }
 889 
 890 
 891 #define BINDTSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE +                       \
 892                 MSG_BND_NEEDED_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 893                 MSG_BND_REFER_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 894                 MSG_BND_FILTER_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 895                 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 896 
 897 /*
 898  * Ensure that Conv_bnd_type_buf_t is large enough:
 899  *
 900  * BINDTSZ is the real minimum size of the buffer required by conv_bnd_type().
 901  * However, Conv_bnd_type_buf_t uses CONV_BND_TYPE_BUFSIZE to set the
 902  * buffer size. We do things this way because the definition of BINDTSZ uses
 903  * information that is not available in the environment of other programs
 904  * that include the conv.h header file.
 905  */
 906 #if (CONV_BND_TYPE_BUFSIZE != BINDTSZ) && !defined(__lint)
 907 #define REPORT_BUFSIZE BINDTSZ
 908 #include "report_bufsize.h"
 909 #error "CONV_BND_TYPE_BUFSIZE does not match BINDTSZ"
 910 #endif
 911 
 912 const char *
 913 conv_bnd_type(uint_t flags, Conv_bnd_type_buf_t *bnd_type_buf)
 914 {
 915         static const Val_desc vda[] = {
 916                 { BND_NEEDED,           MSG_BND_NEEDED },
 917                 { BND_REFER,            MSG_BND_REFER },
 918                 { BND_FILTER,           MSG_BND_FILTER },
 919                 { 0,                    0 }
 920         };
 921         static CONV_EXPN_FIELD_ARG conv_arg = {
 922             NULL, sizeof (bnd_type_buf->buf) };
 923 
 924         if (flags == 0)
 925                 return (MSG_ORIG(MSG_STR_EMPTY));
 926 
 927         conv_arg.buf = bnd_type_buf->buf;
 928         conv_arg.oflags = conv_arg.rflags = flags;
 929         (void) conv_expn_field(&conv_arg, vda, 0);
 930 
 931         return ((const char *)bnd_type_buf->buf);
 932 }
 933 
 934 /*
 935  * Note, conv_bnd_obj() is called with either:
 936  *      LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or
 937  *      LML_FLG_OBJDELETED, or
 938  *      LML_FLG_ATEXIT.
 939  */
 940 #define BINDOSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
 941                 MSG_BND_ADDED_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 942                 MSG_BND_REEVAL_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 943                 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 944 
 945 /*
 946  * Ensure that Conv_bnd_obj_buf_t is large enough:
 947  *
 948  * BINDOSZ is the real minimum size of the buffer required by conv_bnd_obj().
 949  * However, Conv_bnd_obj_buf_t uses CONV_BND_OBJ_BUFSIZE to set the
 950  * buffer size. We do things this way because the definition of BINDOSZ uses
 951  * information that is not available in the environment of other programs
 952  * that include the conv.h header file.
 953  */
 954 #if (CONV_BND_OBJ_BUFSIZE != BINDOSZ) && !defined(__lint)
 955 #define REPORT_BUFSIZE BINDOSZ
 956 #include "report_bufsize.h"
 957 #error "CONV_BND_OBJ_BUFSIZE does not match BINDOSZ"
 958 #endif
 959 
 960 const char *
 961 conv_bnd_obj(uint_t flags, Conv_bnd_obj_buf_t *bnd_obj_buf)
 962 {
 963         static const Val_desc vda[] = {
 964                 { LML_FLG_OBJADDED,     MSG_BND_ADDED },
 965                 { LML_FLG_OBJREEVAL,    MSG_BND_REEVAL },
 966                 { LML_FLG_OBJDELETED,   MSG_BND_DELETED },
 967                 { LML_FLG_ATEXIT,       MSG_BND_ATEXIT },
 968                 { 0,                    0 }
 969         };
 970         static CONV_EXPN_FIELD_ARG conv_arg = {
 971             NULL, sizeof (bnd_obj_buf->buf) };
 972 
 973         if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL |
 974             LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0)
 975                 return (MSG_ORIG(MSG_BND_REVISIT));
 976 
 977         /*
 978          * Note, we're not worried about unknown flags for this family, only
 979          * the selected flags are of interest, so we leave conv_arg.rflags
 980          * set to 0.
 981          */
 982         conv_arg.buf = bnd_obj_buf->buf;
 983         conv_arg.oflags = flags;
 984         (void) conv_expn_field(&conv_arg, vda, 0);
 985 
 986         return ((const char *)bnd_obj_buf->buf);
 987 }