/* Get the full section index, if necessary from the
XINDEX table. */
- if (sym->st_shndx != SHN_XINDEX)
- sec = shdr_info[sym->st_shndx].idx;
- else
- {
- elf_assert (shndxdata != NULL
- && shndxdata->d_buf != NULL);
-
- sec = shdr_info[xshndx].idx;
- }
+ if (sym->st_shndx == SHN_XINDEX)
+ elf_assert (shndxdata != NULL
+ && shndxdata->d_buf != NULL);
+ size_t sidx = (sym->st_shndx != SHN_XINDEX
+ ? sym->st_shndx : xshndx);
+ sec = shdr_info[sidx].idx;
if (sec != 0)
{
shdr_info[cnt].shdr.sh_info = destidx - 1;
}
}
+ else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0
+ && GELF_ST_TYPE (sym->st_info) != STT_SECTION
+ && shdr_info[sidx].shdr.sh_type != SHT_GROUP)
+ {
+ /* Removing a real symbol from an allocated
+ symbol table is hard and probably a
+ mistake. Really removing it means
+ rewriting the dynamic segment and hash
+ sections. Just warn and set the symbol
+ section to UNDEF. */
+ error (0, 0,
+ gettext ("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt);
+ sym->st_shndx = SHN_UNDEF;
+ if (gelf_update_sym (shdr_info[cnt].data, destidx,
+ sym) == 0)
+ INTERNAL_ERROR (fname);
+ shdr_info[cnt].newsymidx[inner] = destidx++;
+ }
else if (debug_fname != NULL
&& shdr_info[cnt].debug_data == NULL)
/* The symbol points to a section that is discarded
this is a section or group signature symbol
for a section which has been removed. */
{
- size_t sidx = (sym->st_shndx != SHN_XINDEX
- ? sym->st_shndx : xshndx);
elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
|| ((shdr_info[sidx].shdr.sh_type
== SHT_GROUP)