1 /* Return section index of section header string table.
2 Copyright (C) 2002, 2005, 2009 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
46 elf_getshdrstrndx (elf
, dst
)
55 if (unlikely (elf
->kind
!= ELF_K_ELF
))
57 __libelf_seterrno (ELF_E_INVALID_HANDLE
);
61 rwlock_rdlock (elf
->lock
);
63 /* We rely here on the fact that the `elf' element is a common prefix
64 of `elf32' and `elf64'. */
65 assert (offsetof (struct Elf
, state
.elf
.ehdr
)
66 == offsetof (struct Elf
, state
.elf32
.ehdr
));
67 assert (sizeof (elf
->state
.elf
.ehdr
)
68 == sizeof (elf
->state
.elf32
.ehdr
));
69 assert (offsetof (struct Elf
, state
.elf
.ehdr
)
70 == offsetof (struct Elf
, state
.elf64
.ehdr
));
71 assert (sizeof (elf
->state
.elf
.ehdr
)
72 == sizeof (elf
->state
.elf64
.ehdr
));
74 if (unlikely (elf
->state
.elf
.ehdr
== NULL
))
76 __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR
);
83 num
= (elf
->class == ELFCLASS32
84 ? elf
->state
.elf32
.ehdr
->e_shstrndx
85 : elf
->state
.elf64
.ehdr
->e_shstrndx
);
87 /* Determine whether the index is too big to fit in the ELF
89 if (unlikely (num
== SHN_XINDEX
))
91 /* Yes. Search the zeroth section header. */
92 if (elf
->class == ELFCLASS32
)
96 if (elf
->state
.elf32
.scns
.data
[0].shdr
.e32
!= NULL
)
98 num
= elf
->state
.elf32
.scns
.data
[0].shdr
.e32
->sh_link
;
102 offset
= elf
->state
.elf32
.ehdr
->e_shoff
;
104 if (elf
->map_address
!= NULL
105 && elf
->state
.elf32
.ehdr
->e_ident
[EI_DATA
] == MY_ELFDATA
107 || (((size_t) ((char *) elf
->map_address
+ offset
))
108 & (__alignof__ (Elf32_Shdr
) - 1)) == 0))
109 /* We can directly access the memory. */
110 num
= ((Elf32_Shdr
*) (elf
->map_address
+ offset
))->sh_link
;
113 /* We avoid reading in all the section headers. Just read
117 if (unlikely (pread_retry (elf
->fildes
, &shdr_mem
,
118 sizeof (Elf32_Shdr
), offset
)
119 != sizeof (Elf32_Shdr
)))
121 /* We must be able to read this ELF section header. */
122 __libelf_seterrno (ELF_E_INVALID_FILE
);
127 if (elf
->state
.elf32
.ehdr
->e_ident
[EI_DATA
] != MY_ELFDATA
)
128 CONVERT (shdr_mem
.sh_link
);
129 num
= shdr_mem
.sh_link
;
134 if (elf
->state
.elf64
.scns
.data
[0].shdr
.e64
!= NULL
)
136 num
= elf
->state
.elf64
.scns
.data
[0].shdr
.e64
->sh_link
;
140 size_t offset
= elf
->state
.elf64
.ehdr
->e_shoff
;
142 if (elf
->map_address
!= NULL
143 && elf
->state
.elf64
.ehdr
->e_ident
[EI_DATA
] == MY_ELFDATA
145 || (((size_t) ((char *) elf
->map_address
+ offset
))
146 & (__alignof__ (Elf64_Shdr
) - 1)) == 0))
147 /* We can directly access the memory. */
148 num
= ((Elf64_Shdr
*) (elf
->map_address
+ offset
))->sh_link
;
151 /* We avoid reading in all the section headers. Just read
155 if (unlikely (pread_retry (elf
->fildes
, &shdr_mem
,
156 sizeof (Elf64_Shdr
), offset
)
157 != sizeof (Elf64_Shdr
)))
159 /* We must be able to read this ELF section header. */
160 __libelf_seterrno (ELF_E_INVALID_FILE
);
165 if (elf
->state
.elf64
.ehdr
->e_ident
[EI_DATA
] != MY_ELFDATA
)
166 CONVERT (shdr_mem
.sh_link
);
167 num
= shdr_mem
.sh_link
;
172 /* Store the result. */
178 rwlock_unlock (elf
->lock
);
182 INTDEF(elf_getshdrstrndx
)
183 /* Alias for the deprecated name. */
184 strong_alias (elf_getshdrstrndx
, elf_getshstrndx
)