tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_reloc.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /* 
       
     2   Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2 of the GNU General Public License as
       
     7   published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement
       
    15   or the like.  Any license provided herein, whether implied or
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with
       
    18   other software, or any other product whatsoever.
       
    19 
       
    20   You should have received a copy of the GNU General Public License along
       
    21   with this program; if not, write the Free Software Foundation, Inc., 51
       
    22   Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
       
    23 
       
    24   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    25   Mountain View, CA 94043, or:
       
    26 
       
    27   http://www.sgi.com
       
    28 
       
    29   For further information regarding this notice, see:
       
    30 
       
    31   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    32 
       
    33 
       
    34 
       
    35 $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_reloc.c,v 1.11 2005/08/04 05:09:37 davea Exp $ */
       
    36 
       
    37 /* The address of the Free Software Foundation is
       
    38    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    39    Boston, MA 02110-1301, USA.
       
    40    SGI has moved from the Crittenden Lane address.
       
    41 */
       
    42 
       
    43 
       
    44 
       
    45 
       
    46 #include "globals.h"
       
    47 
       
    48 
       
    49 #define DW_SECTION_REL_DEBUG_INFO    0
       
    50 #define DW_SECTION_REL_DEBUG_LINE    1
       
    51 #define DW_SECTION_REL_DEBUG_PUBNAME 2
       
    52 #define DW_SECTION_REL_DEBUG_ABBREV  3
       
    53 #define DW_SECTION_REL_DEBUG_ARANGES 4
       
    54 #define DW_SECTION_REL_DEBUG_FRAME   5
       
    55 #define DW_SECTION_REL_DEBUG_NUM     6
       
    56 
       
    57 #define DW_SECTNAME_REL_DEBUG_INFO    ".rel.debug_info"
       
    58 #define DW_SECTNAME_REL_DEBUG_LINE    ".rel.debug_line"
       
    59 #define DW_SECTNAME_REL_DEBUG_PUBNAME ".rel.debug_pubname"
       
    60 #define DW_SECTNAME_REL_DEBUG_ABBREV  ".rel.debug_abbrev"
       
    61 #define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges"
       
    62 #define DW_SECTNAME_REL_DEBUG_FRAME   ".rel.debug_frame"
       
    63 
       
    64 #define STRING_FOR_DUPLICATE " duplicate"
       
    65 #define STRING_FOR_NULL      " null"
       
    66 
       
    67 static char *sectnames[] = {
       
    68     DW_SECTNAME_REL_DEBUG_INFO,
       
    69     DW_SECTNAME_REL_DEBUG_LINE,
       
    70     DW_SECTNAME_REL_DEBUG_PUBNAME,
       
    71     DW_SECTNAME_REL_DEBUG_ABBREV,
       
    72     DW_SECTNAME_REL_DEBUG_ARANGES,
       
    73     DW_SECTNAME_REL_DEBUG_FRAME,
       
    74 };
       
    75 
       
    76 static char *error_msg_duplicate[] = {
       
    77     DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_DUPLICATE,
       
    78     DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_DUPLICATE,
       
    79     DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_DUPLICATE,
       
    80     DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_DUPLICATE,
       
    81     DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_DUPLICATE,
       
    82     DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_DUPLICATE,
       
    83 };
       
    84 
       
    85 static char *error_msg_null[] = {
       
    86     DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_NULL,
       
    87     DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_NULL,
       
    88     DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_NULL,
       
    89     DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_NULL,
       
    90     DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_NULL,
       
    91     DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_NULL,
       
    92 };
       
    93 
       
    94 #define SECT_DATA_SET(x) { \
       
    95 	    if (sect_data[(x)].buf != NULL) { \
       
    96 		print_error(dbg, error_msg_duplicate[(x)],DW_DLV_OK, err); \
       
    97 	    } \
       
    98             if ((data = elf_getdata(scn, 0)) == NULL || data->d_size == 0) { \
       
    99 		print_error(dbg, error_msg_null[(x)],DW_DLV_OK, err); \
       
   100 	    } \
       
   101 	    sect_data[(x)].buf = data -> d_buf; \
       
   102 	    sect_data[(x)].size = data -> d_size; \
       
   103 	    }
       
   104 
       
   105 static char *reloc_type_names[] = {
       
   106     "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32", "R_MIPS_REL32",
       
   107     "R_MIPS_26", "R_MIPS_HI16", "R_MIPS_LO16", "R_MIPS_GPREL16",
       
   108     "R_MIPS_LITERAL", "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16",
       
   109     "R_MIPS_GPREL32",		/* 12 */
       
   110     "reloc type 13?", "reloc type 14?", "reloc type 15?",
       
   111     "R_MIPS_SHIFT5",		/* 16 */
       
   112     "R_MIPS_SHIFT6",		/* 17 */
       
   113     "R_MIPS_64",		/* 18 */
       
   114     "R_MIPS_GOT_DISP",		/* 19 */
       
   115     "R_MIPS_GOT_PAGE",		/* 20 */
       
   116     "R_MIPS_GOT_OFST",		/* 21 */
       
   117     "R_MIPS_GOT_HI16",		/* 22 */
       
   118     "R_MIPS_GOT_LO16",		/* 23 */
       
   119     "R_MIPS_SUB",		/* 24 */
       
   120     "R_MIPS_INSERT_A",		/* 25 */
       
   121     "R_MIPS_INSERT_B",		/* 26 */
       
   122     "R_MIPS_DELETE",		/* 27 */
       
   123     "R_MIPS_HIGHER",		/* 28 */
       
   124     "R_MIPS_HIGHEST",		/* 29 */
       
   125     "R_MIPS_CALL_HI16",		/* 30 */
       
   126     "R_MIPS_CALL_LO16",		/* 31 */
       
   127     "R_MIPS_SCN_DISP",		/* 32 */
       
   128     "R_MIPS_REL16",		/* 33 */
       
   129     "R_MIPS_ADD_IMMEDIATE",	/* 34 */
       
   130 };
       
   131 
       
   132 /*
       
   133 	return valid reloc type names. 
       
   134 	if buf is used, it is static, so beware it
       
   135 	will be overrwritten by the next call.
       
   136 */
       
   137 static char *
       
   138 get_reloc_type_names(int index)
       
   139 {
       
   140     static char buf[100];
       
   141     int arysiz = sizeof(reloc_type_names) / sizeof(char *);
       
   142     char *retval;
       
   143 
       
   144     if (index < 0 || index >= arysiz) {
       
   145 	sprintf(buf, "reloc type %d unknown", (int) index);
       
   146 	retval = buf;
       
   147     } else {
       
   148 	retval = reloc_type_names[index];
       
   149     }
       
   150     return retval;
       
   151 }
       
   152 
       
   153 
       
   154 static struct {
       
   155     Dwarf_Small *buf;
       
   156     Dwarf_Unsigned size;
       
   157 } sect_data[DW_SECTION_REL_DEBUG_NUM];
       
   158 
       
   159 #ifndef HAVE_ELF64_GETEHDR
       
   160 #define Elf64_Addr  long
       
   161 #define Elf64_Word  unsigned long
       
   162 #define Elf64_Xword unsigned long
       
   163 #define Elf64_Sym   long
       
   164 #endif
       
   165 
       
   166 typedef size_t indx_type;
       
   167 
       
   168 typedef struct {
       
   169     indx_type indx;
       
   170     char *name;
       
   171     Elf32_Addr value;
       
   172     Elf32_Word size;
       
   173     int type;
       
   174     int bind;
       
   175     unsigned char other;
       
   176     Elf32_Half shndx;
       
   177 } SYM;
       
   178 
       
   179 
       
   180 typedef struct {
       
   181     indx_type indx;
       
   182     char *name;
       
   183     Elf64_Addr value;
       
   184     Elf64_Xword size;
       
   185     int type;
       
   186     int bind;
       
   187     unsigned char other;
       
   188     unsigned short shndx;
       
   189 } SYM64;
       
   190 
       
   191 static void print_reloc_information_64(int section_no,
       
   192 				       Dwarf_Small * buf,
       
   193 				       Dwarf_Unsigned size);
       
   194 static void print_reloc_information_32(int section_no,
       
   195 				       Dwarf_Small * buf,
       
   196 				       Dwarf_Unsigned size);
       
   197 static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf,
       
   198 		     Elf32_Word link);
       
   199 static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf,
       
   200 			   Elf64_Word link);
       
   201 static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size);
       
   202 static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf);
       
   203 static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf);
       
   204 
       
   205 static SYM *sym_data;
       
   206 static SYM64 *sym_data_64;
       
   207 
       
   208 void
       
   209 print_relocinfo(Dwarf_Debug dbg)
       
   210 {
       
   211     Elf *elf;
       
   212     char *endr_ident;
       
   213     int is_64bit;
       
   214     int res;
       
   215     int i;
       
   216     Elf32_Sym *sym = 0;
       
   217 
       
   218     for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
       
   219 	sect_data[i].buf = 0;
       
   220 	sect_data[i].size = 0;
       
   221     }
       
   222     res = dwarf_get_elf(dbg, &elf, &err);
       
   223     if (res != DW_DLV_OK) {
       
   224 	print_error(dbg, "dwarf_get_elf error", res, err);
       
   225     }
       
   226     if ((endr_ident = elf_getident(elf, NULL)) == NULL) {
       
   227 	print_error(dbg, "DW_ELF_GETIDENT_ERROR", res, err);
       
   228     }
       
   229     is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64);
       
   230     if (is_64bit) {
       
   231 	print_relocinfo_64(dbg, elf);
       
   232     } else {
       
   233 	print_relocinfo_32(dbg, elf);
       
   234     }
       
   235 }
       
   236 
       
   237 static void
       
   238 print_relocinfo_64(Dwarf_Debug dbg, Elf * elf)
       
   239 {
       
   240 #ifdef HAVE_ELF64_GETEHDR
       
   241     Elf_Scn *scn = NULL;
       
   242     Elf_Data *data;
       
   243     Elf64_Ehdr *ehdr64;
       
   244     Elf64_Shdr *shdr64;
       
   245     char *scn_name;
       
   246     int i;
       
   247     Elf64_Sym *sym_64 = 0;
       
   248 
       
   249     if ((ehdr64 = elf64_getehdr(elf)) == NULL) {
       
   250 	print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
       
   251     }
       
   252 
       
   253     while ((scn = elf_nextscn(elf, scn)) != NULL) {
       
   254 
       
   255 	if ((shdr64 = elf64_getshdr(scn)) == NULL) {
       
   256 	    print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
       
   257 	}
       
   258 	if ((scn_name =
       
   259 	     elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name))
       
   260 	    == NULL) {
       
   261 	    print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
       
   262 	}
       
   263 	if (shdr64->sh_type == SHT_SYMTAB) {
       
   264 	    size_t sym_size = 0;
       
   265 	    size_t count = 0;
       
   266 
       
   267 	    if ((sym_64 =
       
   268 		 (Elf64_Sym *) get_scndata(scn, &sym_size)) == NULL) {
       
   269 		print_error(dbg, "no symbol table data", DW_DLV_OK,
       
   270 			    err);
       
   271 	    }
       
   272 	    count = sym_size / sizeof(Elf64_Sym);
       
   273 	    sym_64++;
       
   274             free(sym_data_64);
       
   275 	    sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link);
       
   276 	    if (sym_data_64  == NULL) {
       
   277 		print_error(dbg, "problem reading symbol table data",
       
   278 			    DW_DLV_OK, err);
       
   279 	    }
       
   280 	} else if (strncmp(scn_name, ".rel.debug_", 11))
       
   281 	    continue;
       
   282 	else if (strcmp(scn_name, ".rel.debug_info") == 0) {
       
   283 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO)
       
   284 	} else if (strcmp(scn_name, ".rel.debug_line") == 0) {
       
   285 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE)
       
   286 	} else if (strcmp(scn_name, ".rel.debug_pubname") == 0) {
       
   287 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME)
       
   288 	} else if (strcmp(scn_name, ".rel.debug_aranges") == 0) {
       
   289 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES)
       
   290 	} else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) {
       
   291 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV)
       
   292 	} else if (strcmp(scn_name, ".rel.debug_frame") == 0) {
       
   293 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME)
       
   294 	}
       
   295     }				/* while */
       
   296 
       
   297     for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
       
   298 	if (sect_data[i].buf != NULL && sect_data[i].size > 0) {
       
   299 	    print_reloc_information_64(i, sect_data[i].buf,
       
   300 				       sect_data[i].size);
       
   301 	}
       
   302     }
       
   303 #endif
       
   304 }
       
   305 
       
   306 static void
       
   307 print_relocinfo_32(Dwarf_Debug dbg, Elf * elf)
       
   308 {
       
   309     Elf_Scn *scn = NULL;
       
   310     Elf_Data *data;
       
   311     Elf32_Ehdr *ehdr32;
       
   312     Elf32_Shdr *shdr32;
       
   313     char *scn_name;
       
   314     int i;
       
   315     Elf32_Sym  *sym = 0;
       
   316 
       
   317     if ((ehdr32 = elf32_getehdr(elf)) == NULL) {
       
   318 	print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
       
   319     }
       
   320     while ((scn = elf_nextscn(elf, scn)) != NULL) {
       
   321 	if ((shdr32 = elf32_getshdr(scn)) == NULL) {
       
   322 	    print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
       
   323 	}
       
   324 	if ((scn_name =
       
   325 	     elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name)
       
   326 	    ) == NULL) {
       
   327 	    print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
       
   328 	}
       
   329 	if (shdr32->sh_type == SHT_SYMTAB) {
       
   330 	    size_t sym_size = 0;
       
   331 	    size_t count = 0;
       
   332 
       
   333 	    if ((sym =
       
   334 		 (Elf32_Sym *) get_scndata(scn, &sym_size)) == NULL) {
       
   335 		print_error(dbg, "no symbol table data", DW_DLV_OK,
       
   336 			    err);
       
   337 	    }
       
   338 	    sym = (Elf32_Sym *) get_scndata(scn, &sym_size);
       
   339 	    count = sym_size / sizeof(Elf32_Sym);
       
   340 	    sym++;
       
   341             free(sym_data);
       
   342 	    sym_data = readsyms(sym, count, elf, shdr32->sh_link);
       
   343 	    if (sym_data  == NULL) {
       
   344 		print_error(dbg, "problem reading symbol table data",
       
   345 			    DW_DLV_OK, err);
       
   346 	    }
       
   347 	} else if (strncmp(scn_name, ".rel.debug_", 11))
       
   348 	    continue;
       
   349 	else if (strcmp(scn_name, ".rel.debug_info") == 0) {
       
   350 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO)
       
   351 	} else if (strcmp(scn_name, ".rel.debug_line") == 0) {
       
   352 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE)
       
   353 	} else if (strcmp(scn_name, ".rel.debug_pubname") == 0) {
       
   354 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME)
       
   355 	} else if (strcmp(scn_name, ".rel.debug_aranges") == 0) {
       
   356 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES)
       
   357 	} else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) {
       
   358 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV)
       
   359 	} else if (strcmp(scn_name, ".rel.debug_frame") == 0) {
       
   360 	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME)
       
   361 	}
       
   362     }				/* while */
       
   363 
       
   364     for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
       
   365 	if (sect_data[i].buf != NULL && sect_data[i].size > 0) {
       
   366 	    print_reloc_information_32(i, sect_data[i].buf,
       
   367 				       sect_data[i].size);
       
   368 	}
       
   369     }
       
   370 }
       
   371 
       
   372 #if HAVE_ELF64_R_INFO
       
   373 #ifndef ELF64_R_TYPE
       
   374 #define ELF64_R_TYPE(x) 0	/* FIXME */
       
   375 #endif
       
   376 #ifndef ELF64_R_SYM
       
   377 #define ELF64_R_SYM(x) 0	/* FIXME */
       
   378 #endif
       
   379 #ifndef ELF64_ST_TYPE
       
   380 #define ELF64_ST_TYPE(x) 0	/* FIXME */
       
   381 #endif
       
   382 #ifndef ELF64_ST_BIND
       
   383 #define ELF64_ST_BIND(x) 0	/* FIXME */
       
   384 #endif
       
   385 #endif /* HAVE_ELF64_R_INFO */
       
   386 
       
   387 
       
   388 static void
       
   389 print_reloc_information_64(int section_no, Dwarf_Small * buf,
       
   390 			   Dwarf_Unsigned size)
       
   391 {
       
   392     Dwarf_Unsigned off;
       
   393 
       
   394     printf("\n%s:\n", sectnames[section_no]);
       
   395 #if HAVE_ELF64_GETEHDR
       
   396     for (off = 0; off < size; off += sizeof(Elf64_Rel)) {
       
   397 #if HAVE_ELF64_R_INFO
       
   398 	/* This works for the Elf64_Rel in linux */
       
   399 	Elf64_Rel *p = (Elf64_Rel *) (buf + off);
       
   400 
       
   401 	printf("%5lu\t<%3ld> %-34s%s\n",
       
   402 	       (unsigned long int) (p->r_offset),
       
   403 	       (long)ELF64_R_SYM(p->r_info),
       
   404 	       sym_data[ELF64_R_SYM(p->r_info) - 1].name,
       
   405 	       get_reloc_type_names(ELF64_R_TYPE(p->r_info)));
       
   406 #else
       
   407 	/* sgi/mips -64 does not have r_info in the 64bit relocations,
       
   408 	   but seperate fields, with 3 types, actually. Only one of
       
   409 	   which prints here, as only one really used with dwarf */
       
   410 	Elf64_Rel *p = (Elf64_Rel *) (buf + off);
       
   411 
       
   412 	printf("%5llu\t<%3d> %-34s%s\n",
       
   413 	       (unsigned long long int) (p->r_offset),
       
   414 	       (long)p->r_sym, sym_data_64[p->r_sym - 1].name,
       
   415 	       get_reloc_type_names(p->r_type));
       
   416 #endif
       
   417     }
       
   418 #endif /* HAVE_ELF64_GETEHDR */
       
   419 }
       
   420 
       
   421 static void
       
   422 print_reloc_information_32(int section_no, Dwarf_Small * buf,
       
   423 			   Dwarf_Unsigned size)
       
   424 {
       
   425     Dwarf_Unsigned off;
       
   426 
       
   427     printf("\n%s:\n", sectnames[section_no]);
       
   428     for (off = 0; off < size; off += sizeof(Elf32_Rel)) {
       
   429 	Elf32_Rel *p = (Elf32_Rel *) (buf + off);
       
   430 
       
   431 	printf("%5lu\t<%3d> %-34s%s\n",
       
   432 	       (unsigned long int) (p->r_offset),
       
   433 	       ELF32_R_SYM(p->r_info),
       
   434 	       sym_data[ELF32_R_SYM(p->r_info) - 1].name,
       
   435 	       get_reloc_type_names(ELF32_R_TYPE(p->r_info)));
       
   436     }
       
   437 }
       
   438 
       
   439 static SYM *
       
   440 readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link)
       
   441 {
       
   442     SYM *s, *buf;
       
   443     indx_type i;
       
   444 
       
   445     if ((buf = (SYM *) calloc(num, sizeof(SYM))) == NULL) {
       
   446 	return NULL;
       
   447     }
       
   448     s = buf;			/* save pointer to head of array */
       
   449     for (i = 1; i < num; i++, data++, buf++) {
       
   450 	buf->indx = i;
       
   451 	buf->name = (char *) elf_strptr(elf, link, data->st_name);
       
   452 	buf->value = data->st_value;
       
   453 	buf->size = data->st_size;
       
   454 	buf->type = ELF32_ST_TYPE(data->st_info);
       
   455 	buf->bind = ELF32_ST_BIND(data->st_info);
       
   456 	buf->other = data->st_other;
       
   457 	buf->shndx = data->st_shndx;
       
   458     }				/* end for loop */
       
   459     return (s);
       
   460 }
       
   461 
       
   462 static SYM64 *
       
   463 read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link)
       
   464 {
       
   465 #ifdef HAVE_ELF64_GETEHDR
       
   466 
       
   467     SYM64 *s, *buf;
       
   468     indx_type i;
       
   469 
       
   470     if ((buf = (SYM64 *) calloc(num, sizeof(SYM64))) == NULL) {
       
   471 	return NULL;
       
   472     }
       
   473     s = buf;			/* save pointer to head of array */
       
   474     for (i = 1; i < num; i++, data++, buf++) {
       
   475 	buf->indx = i;
       
   476 	buf->name = (char *) elf_strptr(elf, link, data->st_name);
       
   477 	buf->value = data->st_value;
       
   478 	buf->size = data->st_size;
       
   479 	buf->type = ELF64_ST_TYPE(data->st_info);
       
   480 	buf->bind = ELF64_ST_BIND(data->st_info);
       
   481 	buf->other = data->st_other;
       
   482 	buf->shndx = data->st_shndx;
       
   483     }				/* end for loop */
       
   484     return (s);
       
   485 #else
       
   486     return 0;
       
   487 #endif /* HAVE_ELF64_GETEHDR */
       
   488 }
       
   489 
       
   490 static void *
       
   491 get_scndata(Elf_Scn * fd_scn, size_t * scn_size)
       
   492 {
       
   493     Elf_Data *p_data;
       
   494 
       
   495     p_data = 0;
       
   496     if ((p_data = elf_getdata(fd_scn, p_data)) == 0 ||
       
   497 	p_data->d_size == 0) {
       
   498 	return NULL;
       
   499     }
       
   500     *scn_size = p_data->d_size;
       
   501     return (p_data->d_buf);
       
   502 }
       
   503 
       
   504 /* Cleanup of malloc space (some of the pointers will be 0 here)
       
   505    so dwarfdump looks 'clean' to a malloc checker.
       
   506 */
       
   507 void
       
   508 clean_up_syms_malloc_data()
       
   509 {
       
   510     free(sym_data);
       
   511     free(sym_data_64);
       
   512 }