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,            0,
 562                 0,                              0,
 563                 MSG_DT_SUNW_KMOD_CF
 564         };
 565         static const Msg        tags_sunw_auxiliary_cfnp[] = {
 566                 MSG_DT_SUNW_AUXILIARY_CFNP,     MSG_DT_SUNW_RTLDINF_CFNP,
 567                 MSG_DT_SUNW_FILTER_CFNP,        MSG_DT_SUNW_CAP_CFNP,
 568                 MSG_DT_SUNW_SYMTAB_CFNP,        MSG_DT_SUNW_SYMSZ_CFNP,
 569                 MSG_DT_SUNW_SORTENT_CFNP,       MSG_DT_SUNW_SYMSORT_CFNP,
 570                 MSG_DT_SUNW_SYMSORTSZ_CFNP,     MSG_DT_SUNW_TLSSORT_CFNP,
 571                 MSG_DT_SUNW_TLSSORTSZ_CFNP,     MSG_DT_SUNW_CAPINFO_CFNP,
 572                 MSG_DT_SUNW_STRPAD_CFNP,        MSG_DT_SUNW_CAPCHAIN_CFNP,
 573                 MSG_DT_SUNW_LDMACH_CFNP,        0,
 574                 MSG_DT_SUNW_CAPCHAINENT_CFNP,   0,
 575                 MSG_DT_SUNW_CAPCHAINSZ_CFNP,    0,
 576                 0,                              0,
 577                 MSG_DT_SUNW_ASLR_CFNP,          0,
 578                 0,                              0,
 579                 MSG_DT_SUNW_KMOD_CFNP
 580         };
 581         static const Msg        tags_sunw_auxiliary_nf[] = {
 582                 MSG_DT_SUNW_AUXILIARY_NF,       MSG_DT_SUNW_RTLDINF_NF,
 583                 MSG_DT_SUNW_FILTER_NF,          MSG_DT_SUNW_CAP_NF,
 584                 MSG_DT_SUNW_SYMTAB_NF,          MSG_DT_SUNW_SYMSZ_NF,
 585                 MSG_DT_SUNW_SORTENT_NF,         MSG_DT_SUNW_SYMSORT_NF,
 586                 MSG_DT_SUNW_SYMSORTSZ_NF,       MSG_DT_SUNW_TLSSORT_NF,
 587                 MSG_DT_SUNW_TLSSORTSZ_NF,       MSG_DT_SUNW_CAPINFO_NF,
 588                 MSG_DT_SUNW_STRPAD_NF,          MSG_DT_SUNW_CAPCHAIN_NF,
 589                 MSG_DT_SUNW_LDMACH_NF,          0,
 590                 MSG_DT_SUNW_CAPCHAINENT_NF,     0,
 591                 MSG_DT_SUNW_CAPCHAINSZ_NF,      0,
 592                 0,                              0,
 593                 MSG_DT_SUNW_ASLR_NF,            0,
 594                 0,                              0,
 595                 MSG_DT_SUNW_KMOD_NF
 596         };
 597         static const conv_ds_msg_t ds_sunw_auxiliary_cf = {
 598             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cf) };
 599         static const conv_ds_msg_t ds_sunw_auxiliary_cfnp = {
 600             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cfnp) };
 601         static const conv_ds_msg_t ds_sunw_auxiliary_nf = {
 602             CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_nf) };
 603 
 604         /*
 605          * GNU: (In DT_VALRNGLO section) DT_GNU_PRELINKED - DT_GNU_LIBLISTSZ
 606          */
 607         static const Msg        tags_gnu_prelinked_cf[] = {
 608                 MSG_DT_GNU_PRELINKED_CF,        MSG_DT_GNU_CONFLICTSZ_CF,
 609                 MSG_DT_GNU_LIBLISTSZ_CF
 610         };
 611         static const Msg        tags_gnu_prelinked_cfnp[] = {
 612                 MSG_DT_GNU_PRELINKED_CFNP,      MSG_DT_GNU_CONFLICTSZ_CFNP,
 613                 MSG_DT_GNU_LIBLISTSZ_CFNP
 614         };
 615         static const Msg        tags_gnu_prelinked_nf[] = {
 616                 MSG_DT_GNU_PRELINKED_NF,        MSG_DT_GNU_CONFLICTSZ_NF,
 617                 MSG_DT_GNU_LIBLISTSZ_NF
 618         };
 619         static const conv_ds_msg_t ds_gnu_prelinked_cf = {
 620             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cf) };
 621         static const conv_ds_msg_t ds_gnu_prelinked_cfnp = {
 622             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cfnp) };
 623         static const conv_ds_msg_t ds_gnu_prelinked_nf = {
 624             CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_nf) };
 625 
 626         /*
 627          * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
 628          */
 629         static const Msg        tags_checksum_cf[] = {
 630                 MSG_DT_CHECKSUM_CF,             MSG_DT_PLTPADSZ_CF,
 631                 MSG_DT_MOVEENT_CF,              MSG_DT_MOVESZ_CF,
 632                 MSG_DT_FEATURE_1_CF,            MSG_DT_POSFLAG_1_CF,
 633                 MSG_DT_SYMINSZ_CF,              MSG_DT_SYMINENT_CF
 634         };
 635         static const Msg        tags_checksum_cfnp[] = {
 636                 MSG_DT_CHECKSUM_CFNP,           MSG_DT_PLTPADSZ_CFNP,
 637                 MSG_DT_MOVEENT_CFNP,            MSG_DT_MOVESZ_CFNP,
 638                 MSG_DT_FEATURE_1_CFNP,          MSG_DT_POSFLAG_1_CFNP,
 639                 MSG_DT_SYMINSZ_CFNP,            MSG_DT_SYMINENT_CFNP
 640         };
 641         static const Msg        tags_checksum_nf[] = {
 642                 MSG_DT_CHECKSUM_NF,             MSG_DT_PLTPADSZ_NF,
 643                 MSG_DT_MOVEENT_NF,              MSG_DT_MOVESZ_NF,
 644                 MSG_DT_FEATURE_1_NF,            MSG_DT_POSFLAG_1_NF,
 645                 MSG_DT_SYMINSZ_NF,              MSG_DT_SYMINENT_NF
 646         };
 647         static const conv_ds_msg_t ds_checksum_cf = {
 648             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cf) };
 649         static const conv_ds_msg_t ds_checksum_cfnp = {
 650             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cfnp) };
 651         static const conv_ds_msg_t ds_checksum_nf = {
 652             CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_nf) };
 653 
 654         /*
 655          * GNU: (In DT_ADDRRNGLO section) DT_GNU_HASH - DT_GNU_LIBLIST
 656          */
 657         static const Msg        tags_gnu_hash_cf[] = {
 658                 MSG_DT_GNU_HASH_CF,             MSG_DT_TLSDESC_PLT_CF,
 659                 MSG_DT_TLSDESC_GOT_CF,          MSG_DT_GNU_CONFLICT_CF,
 660                 MSG_DT_GNU_LIBLIST_CF
 661         };
 662         static const Msg        tags_gnu_hash_cfnp[] = {
 663                 MSG_DT_GNU_HASH_CFNP,           MSG_DT_TLSDESC_PLT_CFNP,
 664                 MSG_DT_TLSDESC_GOT_CFNP,        MSG_DT_GNU_CONFLICT_CFNP,
 665                 MSG_DT_GNU_LIBLIST_CFNP
 666         };
 667         static const Msg        tags_gnu_hash_nf[] = {
 668                 MSG_DT_GNU_HASH_NF,             MSG_DT_TLSDESC_PLT_NF,
 669                 MSG_DT_TLSDESC_GOT_NF,          MSG_DT_GNU_CONFLICT_NF,
 670                 MSG_DT_GNU_LIBLIST_NF
 671         };
 672         static const conv_ds_msg_t ds_gnu_hash_cf = {
 673             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cf) };
 674         static const conv_ds_msg_t ds_gnu_hash_cfnp = {
 675             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cfnp) };
 676         static const conv_ds_msg_t ds_gnu_hash_nf = {
 677             CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_nf) };
 678 
 679         /*
 680          * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
 681          */
 682         static const Msg        tags_config_cf[] = {
 683                 MSG_DT_CONFIG_CF,               MSG_DT_DEPAUDIT_CF,
 684                 MSG_DT_AUDIT_CF,                MSG_DT_PLTPAD_CF,
 685                 MSG_DT_MOVETAB_CF,              MSG_DT_SYMINFO_CF
 686         };
 687         static const Msg        tags_config_cfnp[] = {
 688                 MSG_DT_CONFIG_CFNP,             MSG_DT_DEPAUDIT_CFNP,
 689                 MSG_DT_AUDIT_CFNP,              MSG_DT_PLTPAD_CFNP,
 690                 MSG_DT_MOVETAB_CFNP,            MSG_DT_SYMINFO_CFNP
 691         };
 692         static const Msg        tags_config_nf[] = {
 693                 MSG_DT_CONFIG_NF,               MSG_DT_DEPAUDIT_NF,
 694                 MSG_DT_AUDIT_NF,                MSG_DT_PLTPAD_NF,
 695                 MSG_DT_MOVETAB_NF,              MSG_DT_SYMINFO_NF
 696         };
 697         static const conv_ds_msg_t ds_config_cf = {
 698             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cf) };
 699         static const conv_ds_msg_t ds_config_cfnp = {
 700             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cfnp) };
 701         static const conv_ds_msg_t ds_config_nf = {
 702             CONV_DS_MSG_INIT(DT_CONFIG, tags_config_nf) };
 703 
 704         /*
 705          * SUNW: generic range. Note hole between DT_VERSYM and DT_RELACOUNT.
 706          */
 707         static const Msg        tags_versym_cf[] = { MSG_DT_VERSYM_CF };
 708         static const Msg        tags_versym_cfnp[] = { MSG_DT_VERSYM_CFNP };
 709         static const Msg        tags_versym_nf[] = { MSG_DT_VERSYM_NF };
 710         static const conv_ds_msg_t ds_versym_cf = {
 711             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cf) };
 712         static const conv_ds_msg_t ds_versym_cfnp = {
 713             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cfnp) };
 714         static const conv_ds_msg_t ds_versym_nf = {
 715             CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_nf) };
 716 
 717         static const Msg        tags_relacount_cf[] = {
 718                 MSG_DT_RELACOUNT_CF,            MSG_DT_RELCOUNT_CF,
 719                 MSG_DT_FLAGS_1_CF,              MSG_DT_VERDEF_CF,
 720                 MSG_DT_VERDEFNUM_CF,            MSG_DT_VERNEED_CF,
 721                 MSG_DT_VERNEEDNUM_CF
 722         };
 723         static const Msg        tags_relacount_cfnp[] = {
 724                 MSG_DT_RELACOUNT_CFNP,          MSG_DT_RELCOUNT_CFNP,
 725                 MSG_DT_FLAGS_1_CFNP,            MSG_DT_VERDEF_CFNP,
 726                 MSG_DT_VERDEFNUM_CFNP,          MSG_DT_VERNEED_CFNP,
 727                 MSG_DT_VERNEEDNUM_CFNP
 728         };
 729         static const Msg        tags_relacount_nf[] = {
 730                 MSG_DT_RELACOUNT_NF,            MSG_DT_RELCOUNT_NF,
 731                 MSG_DT_FLAGS_1_NF,              MSG_DT_VERDEF_NF,
 732                 MSG_DT_VERDEFNUM_NF,            MSG_DT_VERNEED_NF,
 733                 MSG_DT_VERNEEDNUM_NF
 734         };
 735         static const conv_ds_msg_t ds_relacount_cf = {
 736             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cf) };
 737         static const conv_ds_msg_t ds_relacount_cfnp = {
 738             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cfnp) };
 739         static const conv_ds_msg_t ds_relacount_nf = {
 740             CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_nf) };
 741 
 742         /*
 743          * DT_LOPROC - DT_HIPROC range: solaris/sparc-only
 744          */
 745         static const Msg tags_sparc_reg_cf[] = { MSG_DT_SPARC_REGISTER_CF };
 746         static const Msg tags_sparc_reg_cfnp[] = { MSG_DT_SPARC_REGISTER_CFNP };
 747         static const Msg tags_sparc_reg_nf[] = { MSG_DT_SPARC_REGISTER_NF };
 748         static const Msg tags_sparc_reg_dmp[] = { MSG_DT_SPARC_REGISTER_DMP };
 749         static const conv_ds_msg_t ds_sparc_reg_cf = {
 750             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cf) };
 751         static const conv_ds_msg_t ds_sparc_reg_cfnp = {
 752             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cfnp) };
 753         static const conv_ds_msg_t ds_sparc_reg_nf = {
 754             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_nf) };
 755         static const conv_ds_msg_t ds_sparc_reg_dmp = {
 756             CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_dmp) };
 757 
 758         /*
 759          * DT_LOPROC - DT_HIPROC range: Solaris osabi, all hardware
 760          */
 761         static const Msg        tags_auxiliary_cf[] = {
 762                 MSG_DT_AUXILIARY_CF,    MSG_DT_USED_CF,
 763                 MSG_DT_FILTER_CF
 764         };
 765         static const Msg        tags_auxiliary_cfnp[] = {
 766                 MSG_DT_AUXILIARY_CFNP,  MSG_DT_USED_CFNP,
 767                 MSG_DT_FILTER_CFNP
 768         };
 769         static const Msg        tags_auxiliary_nf[] = {
 770                 MSG_DT_AUXILIARY_NF,    MSG_DT_USED_NF,
 771                 MSG_DT_FILTER_NF
 772         };
 773         static const conv_ds_msg_t ds_auxiliary_cf = {
 774             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cf) };
 775         static const conv_ds_msg_t ds_auxiliary_cfnp = {
 776             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cfnp) };
 777         static const conv_ds_msg_t ds_auxiliary_nf = {
 778             CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_nf) };
 779 
 780 
 781         static const conv_ds_t  *retarr[MAX_RET];
 782 
 783         int     ndx = 0;
 784         int     fmt_osabi = CONV_TYPE_FMT_ALT(fmt_flags);
 785         int     mach_sparc, osabi_solaris, osabi_linux;
 786 
 787 
 788 
 789         osabi_solaris = (osabi == ELFOSABI_NONE) ||
 790             (osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL);
 791         osabi_linux = (osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL);
 792         mach_sparc = (mach == EM_SPARC) || (mach == EM_SPARCV9) ||
 793             (mach == EM_SPARC32PLUS) || (mach == CONV_MACH_ALL);
 794 
 795         /*
 796          * Fill in retarr with the descriptors for the messages that
 797          * apply to the current osabi. Note that we order these items such
 798          * that the more common are placed at the beginning, and the less
 799          * likely at the end. This should speed the common case.
 800          *
 801          * Note that the CFNP and DMP styles are very similar, so they
 802          * are combined in 'default', and fmt_osabi is consulted when there
 803          * are differences.
 804          */
 805         switch (fmt_osabi) {
 806         case CONV_FMT_ALT_CF:
 807                 retarr[ndx++] = CONV_DS_ADDR(ds_null_cf);
 808                 if (osabi_solaris)
 809                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cf);
 810                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cf);
 811                 retarr[ndx++] = CONV_DS_ADDR(ds_config_cf);
 812                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_cf);
 813                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cf);
 814                 if (osabi_solaris) {
 815                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cf);
 816                         if (mach_sparc) {
 817                                 retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_cf);
 818                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cf);
 819                         }
 820                 }
 821                 if (osabi_linux) {
 822                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cf);
 823                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cf);
 824                 }
 825                 break;
 826 
 827         case CONV_FMT_ALT_NF:
 828                 retarr[ndx++] = CONV_DS_ADDR(ds_null_nf);
 829                 if (osabi_solaris)
 830                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_nf);
 831                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_nf);
 832                 retarr[ndx++] = CONV_DS_ADDR(ds_config_nf);
 833                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_nf);
 834                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_nf);
 835                 if (osabi_solaris) {
 836                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_nf);
 837                         if (mach_sparc) {
 838                                 retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_nf);
 839                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_nf);
 840                         }
 841                 }
 842                 if (osabi_linux) {
 843                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_nf);
 844                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_nf);
 845                 }
 846                 break;
 847         default:
 848                 /*
 849                  * The default style for the generic range is CFNP,
 850                  * while dump has a couple of different strings.
 851                  */
 852 
 853                 retarr[ndx++] = (fmt_osabi == CONV_FMT_ALT_DUMP) ?
 854                     CONV_DS_ADDR(ds_null_dmp) : CONV_DS_ADDR(ds_null_cfnp);
 855                 if (osabi_solaris)
 856                         retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cfnp);
 857                 retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cfnp);
 858                 retarr[ndx++] = CONV_DS_ADDR(ds_config_cfnp);
 859                 retarr[ndx++] = CONV_DS_ADDR(ds_versym_cfnp);
 860                 retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cfnp);
 861                 if (osabi_solaris) {
 862                         retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cfnp);
 863                         if (mach_sparc) {
 864                                 /*
 865                                  * The default style for DT_SPARC_REGISTER
 866                                  * is the dump style, which omits the 'SPARC_'.
 867                                  * CFNP keeps the prefix.
 868                                  */
 869                                 retarr[ndx++] =
 870                                     (fmt_osabi == CONV_FMT_ALT_CFNP) ?
 871                                     CONV_DS_ADDR(ds_sparc_reg_cfnp) :
 872                                     CONV_DS_ADDR(ds_sparc_reg_dmp);
 873                                 retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cfnp);
 874                         }
 875                 }
 876                 if (osabi_linux) {
 877                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cfnp);
 878                         retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cfnp);
 879                 }
 880                 break;
 881         }
 882 
 883         retarr[ndx++] = NULL;
 884         assert(ndx <= MAX_RET);
 885         return (retarr);
 886 }
 887 
 888 conv_iter_ret_t
 889 conv_iter_dyn_tag(conv_iter_osabi_t osabi, Half mach,
 890     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
 891 {
 892         return (conv_iter_ds(osabi, mach,
 893             conv_dyn_tag_strings(osabi, mach, fmt_flags), func, uvalue));
 894 }
 895 
 896 
 897 #define BINDTSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE +                       \
 898                 MSG_BND_NEEDED_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 899                 MSG_BND_REFER_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 900                 MSG_BND_FILTER_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 901                 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 902 
 903 /*
 904  * Ensure that Conv_bnd_type_buf_t is large enough:
 905  *
 906  * BINDTSZ is the real minimum size of the buffer required by conv_bnd_type().
 907  * However, Conv_bnd_type_buf_t uses CONV_BND_TYPE_BUFSIZE to set the
 908  * buffer size. We do things this way because the definition of BINDTSZ uses
 909  * information that is not available in the environment of other programs
 910  * that include the conv.h header file.
 911  */
 912 #if (CONV_BND_TYPE_BUFSIZE != BINDTSZ) && !defined(__lint)
 913 #define REPORT_BUFSIZE BINDTSZ
 914 #include "report_bufsize.h"
 915 #error "CONV_BND_TYPE_BUFSIZE does not match BINDTSZ"
 916 #endif
 917 
 918 const char *
 919 conv_bnd_type(uint_t flags, Conv_bnd_type_buf_t *bnd_type_buf)
 920 {
 921         static const Val_desc vda[] = {
 922                 { BND_NEEDED,           MSG_BND_NEEDED },
 923                 { BND_REFER,            MSG_BND_REFER },
 924                 { BND_FILTER,           MSG_BND_FILTER },
 925                 { 0,                    0 }
 926         };
 927         static CONV_EXPN_FIELD_ARG conv_arg = {
 928             NULL, sizeof (bnd_type_buf->buf) };
 929 
 930         if (flags == 0)
 931                 return (MSG_ORIG(MSG_STR_EMPTY));
 932 
 933         conv_arg.buf = bnd_type_buf->buf;
 934         conv_arg.oflags = conv_arg.rflags = flags;
 935         (void) conv_expn_field(&conv_arg, vda, 0);
 936 
 937         return ((const char *)bnd_type_buf->buf);
 938 }
 939 
 940 /*
 941  * Note, conv_bnd_obj() is called with either:
 942  *      LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or
 943  *      LML_FLG_OBJDELETED, or
 944  *      LML_FLG_ATEXIT.
 945  */
 946 #define BINDOSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
 947                 MSG_BND_ADDED_SIZE      + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 948                 MSG_BND_REEVAL_SIZE     + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 949                 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 950 
 951 /*
 952  * Ensure that Conv_bnd_obj_buf_t is large enough:
 953  *
 954  * BINDOSZ is the real minimum size of the buffer required by conv_bnd_obj().
 955  * However, Conv_bnd_obj_buf_t uses CONV_BND_OBJ_BUFSIZE to set the
 956  * buffer size. We do things this way because the definition of BINDOSZ uses
 957  * information that is not available in the environment of other programs
 958  * that include the conv.h header file.
 959  */
 960 #if (CONV_BND_OBJ_BUFSIZE != BINDOSZ) && !defined(__lint)
 961 #define REPORT_BUFSIZE BINDOSZ
 962 #include "report_bufsize.h"
 963 #error "CONV_BND_OBJ_BUFSIZE does not match BINDOSZ"
 964 #endif
 965 
 966 const char *
 967 conv_bnd_obj(uint_t flags, Conv_bnd_obj_buf_t *bnd_obj_buf)
 968 {
 969         static const Val_desc vda[] = {
 970                 { LML_FLG_OBJADDED,     MSG_BND_ADDED },
 971                 { LML_FLG_OBJREEVAL,    MSG_BND_REEVAL },
 972                 { LML_FLG_OBJDELETED,   MSG_BND_DELETED },
 973                 { LML_FLG_ATEXIT,       MSG_BND_ATEXIT },
 974                 { 0,                    0 }
 975         };
 976         static CONV_EXPN_FIELD_ARG conv_arg = {
 977             NULL, sizeof (bnd_obj_buf->buf) };
 978 
 979         if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL |
 980             LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0)
 981                 return (MSG_ORIG(MSG_BND_REVISIT));
 982 
 983         /*
 984          * Note, we're not worried about unknown flags for this family, only
 985          * the selected flags are of interest, so we leave conv_arg.rflags
 986          * set to 0.
 987          */
 988         conv_arg.buf = bnd_obj_buf->buf;
 989         conv_arg.oflags = flags;
 990         (void) conv_expn_field(&conv_arg, vda, 0);
 991 
 992         return ((const char *)bnd_obj_buf->buf);
 993 }