diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexelf.c | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index 8d435f289f8..a9d1e247185 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -1183,50 +1183,55 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 1183 | for (n = new_file_h->e_shnum - 1; n; n--) | 1183 | for (n = new_file_h->e_shnum - 1; n; n--) |
| 1184 | { | 1184 | { |
| 1185 | ElfW(Shdr) section = NEW_SECTION_H (n); | 1185 | ElfW(Shdr) section = NEW_SECTION_H (n); |
| 1186 | switch (section.sh_type) { | 1186 | |
| 1187 | default: | 1187 | /* Cause a compilation error if anyone uses n instead of nn below. */ |
| 1188 | break; | 1188 | struct {int a;} n; |
| 1189 | case SHT_REL: | 1189 | |
| 1190 | case SHT_RELA: | 1190 | switch (section.sh_type) |
| 1191 | /* This code handles two different size structs, but there should | 1191 | { |
| 1192 | be no harm in that provided that r_offset is always the first | 1192 | default: |
| 1193 | member. */ | 1193 | break; |
| 1194 | nn = section.sh_info; | 1194 | case SHT_REL: |
| 1195 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") | 1195 | case SHT_RELA: |
| 1196 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1196 | /* This code handles two different size structs, but there should |
| 1197 | ".sdata") | 1197 | be no harm in that provided that r_offset is always the first |
| 1198 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1198 | member. */ |
| 1199 | ".lit4") | 1199 | nn = section.sh_info; |
| 1200 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1200 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") |
| 1201 | ".lit8") | 1201 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
| 1202 | ".sdata") | ||
| 1203 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1204 | ".lit4") | ||
| 1205 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1206 | ".lit8") | ||
| 1202 | #if __sgi | 1207 | #if __sgi |
| 1203 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1208 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
| 1204 | ".got") | 1209 | ".got") |
| 1205 | #endif | 1210 | #endif |
| 1206 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1211 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
| 1207 | ".sdata1") | 1212 | ".sdata1") |
| 1208 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1213 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
| 1209 | ".data1")) | 1214 | ".data1")) |
| 1210 | { | 1215 | { |
| 1211 | ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - | 1216 | ElfW(Addr) offset = (NEW_SECTION_H (nn).sh_addr |
| 1212 | NEW_SECTION_H (nn).sh_offset; | 1217 | - NEW_SECTION_H (nn).sh_offset); |
| 1213 | caddr_t reloc = old_base + section.sh_offset, end; | 1218 | caddr_t reloc = old_base + section.sh_offset, end; |
| 1214 | for (end = reloc + section.sh_size; reloc < end; | 1219 | for (end = reloc + section.sh_size; reloc < end; |
| 1215 | reloc += section.sh_entsize) | 1220 | reloc += section.sh_entsize) |
| 1216 | { | 1221 | { |
| 1217 | ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; | 1222 | ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; |
| 1218 | #ifdef __alpha__ | 1223 | #ifdef __alpha__ |
| 1219 | /* The Alpha ELF binutils currently have a bug that | 1224 | /* The Alpha ELF binutils currently have a bug that |
| 1220 | sometimes results in relocs that contain all | 1225 | sometimes results in relocs that contain all |
| 1221 | zeroes. Work around this for now... */ | 1226 | zeroes. Work around this for now... */ |
| 1222 | if (((ElfW(Rel) *) reloc)->r_offset == 0) | 1227 | if (((ElfW(Rel) *) reloc)->r_offset == 0) |
| 1223 | continue; | 1228 | continue; |
| 1224 | #endif | 1229 | #endif |
| 1225 | memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); | 1230 | memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); |
| 1226 | } | 1231 | } |
| 1227 | } | 1232 | } |
| 1228 | break; | 1233 | break; |
| 1229 | } | 1234 | } |
| 1230 | } | 1235 | } |
| 1231 | 1236 | ||
| 1232 | /* Write out new_file, and free the buffers. */ | 1237 | /* Write out new_file, and free the buffers. */ |