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