aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Modra2015-11-08 09:29:00 -0800
committerPaul Eggert2015-11-08 10:00:59 -0800
commit3ff9fc0e8d738be5004c65c3be314af9aca68148 (patch)
tree670d5f6de1d84737c944ba7c0c7f3f4e4395116c /src
parent190b968f189cb7d06223bb39045ec9055df67f68 (diff)
downloademacs-3ff9fc0e8d738be5004c65c3be314af9aca68148.tar.gz
emacs-3ff9fc0e8d738be5004c65c3be314af9aca68148.zip
ELF unexec: _OBJC_ symbols in bss sections
This code assumed that there was only one bss section. Rather than checking for a particular index, check the section type. Also, handle the possibility that the section was SHT_NOBITS originally and is unchanged, in which case no clearing is needed (and sh_offset isn't necessarily valid, which can lead to a wild memset). * unexelf.c (unexec): Properly handle _OBJC_ symbols in bss sections.
Diffstat (limited to 'src')
-rw-r--r--src/unexelf.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index 286ba2e99c1..df99f92a466 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -1176,20 +1176,25 @@ temacs:
1176 "_OBJC_", sizeof ("_OBJC_") - 1) == 0) 1176 "_OBJC_", sizeof ("_OBJC_") - 1) == 0)
1177 { 1177 {
1178 ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx); 1178 ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx);
1179 ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr; 1179 if (new_shdr->sh_type != SHT_NOBITS)
1180 ptrdiff_t newoff = reladdr + new_shdr->sh_offset;
1181
1182 /* "Unpatch" index. */
1183 nn = symp->st_shndx;
1184 if (nn > old_bss_index)
1185 nn--;
1186 if (nn == old_bss_index)
1187 memset (new_base + newoff, 0, symp->st_size);
1188 else
1189 { 1180 {
1190 ElfW (Shdr) *old_shdr = &OLD_SECTION_H (nn); 1181 ElfW (Shdr) *old_shdr;
1191 ptrdiff_t oldoff = reladdr + old_shdr->sh_offset; 1182 ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr;
1192 memcpy (new_base + newoff, old_base + oldoff, symp->st_size); 1183 ptrdiff_t newoff = reladdr + new_shdr->sh_offset;
1184
1185 /* "Unpatch" index. */
1186 nn = symp->st_shndx;
1187 if (nn > old_bss_index)
1188 nn--;
1189 old_shdr = &OLD_SECTION_H (nn);
1190 if (old_shdr->sh_type == SHT_NOBITS)
1191 memset (new_base + newoff, 0, symp->st_size);
1192 else
1193 {
1194 ptrdiff_t oldoff = reladdr + old_shdr->sh_offset;
1195 memcpy (new_base + newoff, old_base + oldoff,
1196 symp->st_size);
1197 }
1193 } 1198 }
1194 } 1199 }
1195#endif 1200#endif