]> git.ipfire.org Git - thirdparty/elfutils.git/blame - tests/elf-print-reloc-syms.c
unstrip: Call adjust_relocs no more than once per section.
[thirdparty/elfutils.git] / tests / elf-print-reloc-syms.c
CommitLineData
2f9b180c
AM
1/* Copyright (C) 2024 Red Hat, Inc.
2 This file is part of elfutils.
3
4 This file is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20
21#include <fcntl.h>
22#include <gelf.h>
23#include <stdio.h>
24#include <unistd.h>
25#include <assert.h>
26
27static void
28print_reloc_symnames (Elf *elf, Elf_Scn *scn, GElf_Shdr *shdr, size_t sh_entsize)
29{
30 int nentries = shdr->sh_size / sh_entsize;
31
32 /* Get the data of the section. */
33 Elf_Data *data = elf_getdata (scn, NULL);
34 assert (data != NULL);
35
36 /* Get the symbol table information. */
37 Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
38 GElf_Shdr symshdr_mem;
39 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
40 Elf_Data *symdata = elf_getdata (symscn, NULL);
41 assert (symshdr != NULL);
42 assert (symdata != NULL);
43
44 /* Search for the optional extended section index table. */
45 Elf_Data *xndxdata = NULL;
46 int xndxscnidx = elf_scnshndx (scn);
47 if (xndxscnidx)
48 xndxdata = elf_getdata (elf_getscn (elf, xndxscnidx), NULL);
49
50 /* Get the section header string table index. */
51 size_t shstrndx;
52 assert (elf_getshdrstrndx (elf, &shstrndx) >= 0);
53
54 printf("Section: %s\n", elf_strptr (elf, shstrndx, shdr->sh_name));
55 for (int cnt = 0; cnt < nentries; ++cnt)
56 {
57 GElf_Rel relmem;
58 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
59
60
61 if (likely (rel != NULL))
62 {
63 GElf_Sym symmem;
64 Elf32_Word xndx;
65 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
66 GELF_R_SYM (rel->r_info),
67 &symmem, &xndx);
68
69 if (sym == NULL)
70 {
71 printf ("<SYM NOT FOUND>\n");
72 continue;
73 }
74
75 if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
76 printf ("%s\n", elf_strptr (elf, symshdr->sh_link, sym->st_name));
77 else
78 {
79 /* This is a relocation against a STT_SECTION symbol. */
80 GElf_Shdr secshdr_mem;
81 GElf_Shdr *secshdr;
82 secshdr = gelf_getshdr (elf_getscn (elf,
83 sym->st_shndx == SHN_XINDEX
84 ? xndx : sym->st_shndx),
85 &secshdr_mem);
86
87 if (secshdr == NULL)
88 printf("<SECTION NOT FOUND>\n");
89 else
90 printf ("%s\n",
91 elf_strptr (elf, shstrndx, secshdr->sh_name));
92 }
93 }
94 }
95}
96
97int
98main (int argc, char *argv[])
99{
100 if (argc != 2)
101 {
102 printf ("Usage: elf_print_reloc_syms FILE\n");
103 return -1;
104 }
105
106 elf_version (EV_CURRENT);
107
108 int fd = open(argv[1], O_RDONLY);
109 assert (fd != -1);
110
111 Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
112 assert (elf != NULL);
113
114 size_t shnums;
115 assert (elf_getshdrnum (elf, &shnums) >= 0);
116
117 Elf_Scn *scn = NULL;
118 while ((scn = elf_nextscn (elf, scn)) != NULL)
119 {
120 GElf_Shdr shdr_mem;
121 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
122
123 if (shdr != NULL)
124 {
125 /* Print the names of symbols referred to by relocations. */
126 if (shdr->sh_type == SHT_REL)
127 {
128 size_t sh_entsize = gelf_fsize (elf, ELF_T_REL, 1, EV_CURRENT);
129 print_reloc_symnames (elf, scn, shdr, sh_entsize);
130 }
131 else if (shdr->sh_type == SHT_RELA)
132 {
133 size_t sh_entsize = gelf_fsize (elf, ELF_T_RELA, 1, EV_CURRENT);
134 print_reloc_symnames (elf, scn, shdr, sh_entsize);
135 }
136 }
137 }
138
139 elf_end (elf);
140 close (fd);
141 return 0;
142}