|
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 } |