aboutsummaryrefslogtreecommitdiffstats
path: root/src/unexelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/unexelf.c')
-rw-r--r--src/unexelf.c92
1 files changed, 49 insertions, 43 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index 951e7c0eea6..ac9c9e75764 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 1985-1988, 1990, 1992, 1999-2011 1/* Copyright (C) 1985-1988, 1990, 1992, 1999-2012
2 Free Software Foundation, Inc. 2 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
@@ -453,7 +453,7 @@ typedef struct {
453 long cbRfdOffset; 453 long cbRfdOffset;
454 long cbExtOffset; 454 long cbExtOffset;
455} HDRR, *pHDRR; 455} HDRR, *pHDRR;
456#define cbHDRR sizeof(HDRR) 456#define cbHDRR sizeof (HDRR)
457#define hdrNil ((pHDRR)0) 457#define hdrNil ((pHDRR)0)
458#endif 458#endif
459 459
@@ -549,11 +549,11 @@ typedef struct {
549 */ 549 */
550 550
551#define OLD_SECTION_H(n) \ 551#define OLD_SECTION_H(n) \
552 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 552 (*(ElfW (Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
553#define NEW_SECTION_H(n) \ 553#define NEW_SECTION_H(n) \
554 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 554 (*(ElfW (Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
555#define NEW_PROGRAM_H(n) \ 555#define NEW_PROGRAM_H(n) \
556 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 556 (*(ElfW (Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
557 557
558#define PATCH_INDEX(n) \ 558#define PATCH_INDEX(n) \
559 do { \ 559 do { \
@@ -563,8 +563,8 @@ typedef unsigned char byte;
563 563
564/* Round X up to a multiple of Y. */ 564/* Round X up to a multiple of Y. */
565 565
566static ElfW(Addr) 566static ElfW (Addr)
567round_up (ElfW(Addr) x, ElfW(Addr) y) 567round_up (ElfW (Addr) x, ElfW (Addr) y)
568{ 568{
569 int rem = x % y; 569 int rem = x % y;
570 if (rem == 0) 570 if (rem == 0)
@@ -581,7 +581,7 @@ round_up (ElfW(Addr) x, ElfW(Addr) y)
581 581
582static int 582static int
583find_section (const char *name, const char *section_names, const char *file_name, 583find_section (const char *name, const char *section_names, const char *file_name,
584 ElfW(Ehdr) *old_file_h, ElfW(Shdr) *old_section_h, int noerror) 584 ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, int noerror)
585{ 585{
586 int idx; 586 int idx;
587 587
@@ -635,19 +635,19 @@ unexec (const char *new_name, const char *old_name)
635 635
636 /* Pointers to the file, program and section headers for the old and 636 /* Pointers to the file, program and section headers for the old and
637 new files. */ 637 new files. */
638 ElfW(Ehdr) *old_file_h, *new_file_h; 638 ElfW (Ehdr) *old_file_h, *new_file_h;
639 ElfW(Phdr) *old_program_h, *new_program_h; 639 ElfW (Phdr) *old_program_h, *new_program_h;
640 ElfW(Shdr) *old_section_h, *new_section_h; 640 ElfW (Shdr) *old_section_h, *new_section_h;
641 641
642 /* Point to the section name table in the old file. */ 642 /* Point to the section name table in the old file. */
643 char *old_section_names; 643 char *old_section_names;
644 644
645 ElfW(Addr) old_bss_addr, new_bss_addr; 645 ElfW (Addr) old_bss_addr, new_bss_addr;
646 ElfW(Word) old_bss_size, new_data2_size; 646 ElfW (Word) old_bss_size, new_data2_size;
647 ElfW(Off) new_data2_offset; 647 ElfW (Off) new_data2_offset;
648 ElfW(Addr) new_data2_addr; 648 ElfW (Addr) new_data2_addr;
649 ElfW(Off) old_bss_offset; 649 ElfW (Off) old_bss_offset;
650 ElfW(Word) new_data2_incr; 650 ElfW (Word) new_data2_incr;
651 651
652 int n, nn; 652 int n, nn;
653 int old_bss_index, old_sbss_index, old_plt_index; 653 int old_bss_index, old_sbss_index, old_plt_index;
@@ -690,9 +690,9 @@ unexec (const char *new_name, const char *old_name)
690 690
691 /* Get pointers to headers & section names */ 691 /* Get pointers to headers & section names */
692 692
693 old_file_h = (ElfW(Ehdr) *) old_base; 693 old_file_h = (ElfW (Ehdr) *) old_base;
694 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); 694 old_program_h = (ElfW (Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
695 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); 695 old_section_h = (ElfW (Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
696 old_section_names = (char *) old_base 696 old_section_names = (char *) old_base
697 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 697 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
698 698
@@ -759,7 +759,7 @@ unexec (const char *new_name, const char *old_name)
759 759
760#if defined (emacs) || !defined (DEBUG) 760#if defined (emacs) || !defined (DEBUG)
761 new_break = sbrk (0); 761 new_break = sbrk (0);
762 new_bss_addr = (ElfW(Addr)) new_break; 762 new_bss_addr = (ElfW (Addr)) new_break;
763#else 763#else
764 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 764 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
765#endif 765#endif
@@ -806,9 +806,9 @@ unexec (const char *new_name, const char *old_name)
806 if (new_base == MAP_FAILED) 806 if (new_base == MAP_FAILED)
807 fatal ("Can't allocate buffer for %s\n", old_name, 0); 807 fatal ("Can't allocate buffer for %s\n", old_name, 0);
808 808
809 new_file_h = (ElfW(Ehdr) *) new_base; 809 new_file_h = (ElfW (Ehdr) *) new_base;
810 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 810 new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
811 new_section_h = (ElfW(Shdr) *) 811 new_section_h = (ElfW (Shdr) *)
812 ((byte *) new_base + old_file_h->e_shoff + new_data2_incr); 812 ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
813 813
814 /* Make our new file, program and section headers as copies of the 814 /* Make our new file, program and section headers as copies of the
@@ -844,7 +844,7 @@ unexec (const char *new_name, const char *old_name)
844 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 844 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
845 { 845 {
846 /* Compute maximum of all requirements for alignment of section. */ 846 /* Compute maximum of all requirements for alignment of section. */
847 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; 847 ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
848 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) 848 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
849 alignment = OLD_SECTION_H (old_bss_index).sh_addralign; 849 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
850 850
@@ -1019,7 +1019,7 @@ temacs:
1019 /* The conditional bit below was in Oliva's original code 1019 /* The conditional bit below was in Oliva's original code
1020 (1999-08-25) and seems to have been dropped by mistake 1020 (1999-08-25) and seems to have been dropped by mistake
1021 subsequently. It prevents a crash at startup under X in 1021 subsequently. It prevents a crash at startup under X in
1022 `IRIX64 6.5 6.5.17m', whether compiled on that relase or 1022 `IRIX64 6.5 6.5.17m', whether compiled on that release or
1023 an earlier one. It causes no trouble on the other ELF 1023 an earlier one. It causes no trouble on the other ELF
1024 platforms I could test (Irix 6.5.15m, Solaris 8, Debian 1024 platforms I could test (Irix 6.5.15m, Solaris 8, Debian
1025 Potato x86, Debian Woody SPARC); however, it's reported 1025 Potato x86, Debian Woody SPARC); however, it's reported
@@ -1053,7 +1053,7 @@ temacs:
1053 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 1053 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
1054 NEW_SECTION_H (nn).sh_size); 1054 NEW_SECTION_H (nn).sh_size);
1055 1055
1056#ifdef __alpha__ 1056#if defined __alpha__ && !defined __OpenBSD__
1057 /* Update Alpha COFF symbol table: */ 1057 /* Update Alpha COFF symbol table: */
1058 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug") 1058 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
1059 == 0) 1059 == 0)
@@ -1072,14 +1072,14 @@ temacs:
1072 symhdr->cbRfdOffset += new_data2_size; 1072 symhdr->cbRfdOffset += new_data2_size;
1073 symhdr->cbExtOffset += new_data2_size; 1073 symhdr->cbExtOffset += new_data2_size;
1074 } 1074 }
1075#endif /* __alpha__ */ 1075#endif /* __alpha__ && !__OpenBSD__ */
1076 1076
1077#if defined (_SYSTYPE_SYSV) 1077#if defined (_SYSTYPE_SYSV)
1078 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG 1078 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
1079 && old_mdebug_index != -1) 1079 && old_mdebug_index != -1)
1080 { 1080 {
1081 int diff = NEW_SECTION_H(nn).sh_offset 1081 int diff = NEW_SECTION_H (nn).sh_offset
1082 - OLD_SECTION_H(old_mdebug_index).sh_offset; 1082 - OLD_SECTION_H (old_mdebug_index).sh_offset;
1083 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); 1083 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
1084 1084
1085 if (diff) 1085 if (diff)
@@ -1158,9 +1158,9 @@ temacs:
1158 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 1158 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
1159 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 1159 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
1160 { 1160 {
1161 ElfW(Shdr) *spt = &NEW_SECTION_H (nn); 1161 ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
1162 unsigned int num = spt->sh_size / spt->sh_entsize; 1162 unsigned int num = spt->sh_size / spt->sh_entsize;
1163 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset + 1163 ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
1164 new_base); 1164 new_base);
1165 for (; num--; sym++) 1165 for (; num--; sym++)
1166 { 1166 {
@@ -1178,7 +1178,7 @@ temacs:
1178 for (n = new_file_h->e_shnum - 1; n; n--) 1178 for (n = new_file_h->e_shnum - 1; n; n--)
1179 { 1179 {
1180 byte *symnames; 1180 byte *symnames;
1181 ElfW(Sym) *symp, *symendp; 1181 ElfW (Sym) *symp, *symendp;
1182 1182
1183 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM 1183 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
1184 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) 1184 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
@@ -1186,8 +1186,8 @@ temacs:
1186 1186
1187 symnames = ((byte *) new_base 1187 symnames = ((byte *) new_base
1188 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); 1188 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
1189 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); 1189 symp = (ElfW (Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
1190 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); 1190 symendp = (ElfW (Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
1191 1191
1192 for (; symp < symendp; symp ++) 1192 for (; symp < symendp; symp ++)
1193 { 1193 {
@@ -1219,9 +1219,15 @@ temacs:
1219 nn = symp->st_shndx; 1219 nn = symp->st_shndx;
1220 if (nn > old_bss_index) 1220 if (nn > old_bss_index)
1221 nn--; 1221 nn--;
1222 old = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr) 1222 if (nn == old_bss_index)
1223 + OLD_SECTION_H (nn).sh_offset + old_base); 1223 memset (new, 0, symp->st_size);
1224 memcpy (new, old, symp->st_size); 1224 else
1225 {
1226 old = ((symp->st_value
1227 - NEW_SECTION_H (symp->st_shndx).sh_addr)
1228 + OLD_SECTION_H (nn).sh_offset + old_base);
1229 memcpy (new, old, symp->st_size);
1230 }
1225 } 1231 }
1226#endif 1232#endif
1227 } 1233 }
@@ -1231,7 +1237,7 @@ temacs:
1231 that it can undo relocations performed by the runtime linker. */ 1237 that it can undo relocations performed by the runtime linker. */
1232 for (n = new_file_h->e_shnum - 1; n; n--) 1238 for (n = new_file_h->e_shnum - 1; n; n--)
1233 { 1239 {
1234 ElfW(Shdr) section = NEW_SECTION_H (n); 1240 ElfW (Shdr) section = NEW_SECTION_H (n);
1235 1241
1236 /* Cause a compilation error if anyone uses n instead of nn below. */ 1242 /* Cause a compilation error if anyone uses n instead of nn below. */
1237 #define n ((void) 0); 1243 #define n ((void) 0);
@@ -1263,21 +1269,21 @@ temacs:
1263 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), 1269 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1264 ".data1")) 1270 ".data1"))
1265 { 1271 {
1266 ElfW(Addr) offset = (NEW_SECTION_H (nn).sh_addr 1272 ElfW (Addr) offset = (NEW_SECTION_H (nn).sh_addr
1267 - NEW_SECTION_H (nn).sh_offset); 1273 - NEW_SECTION_H (nn).sh_offset);
1268 caddr_t reloc = old_base + section.sh_offset, end; 1274 caddr_t reloc = old_base + section.sh_offset, end;
1269 for (end = reloc + section.sh_size; reloc < end; 1275 for (end = reloc + section.sh_size; reloc < end;
1270 reloc += section.sh_entsize) 1276 reloc += section.sh_entsize)
1271 { 1277 {
1272 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset; 1278 ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset;
1273#ifdef __alpha__ 1279#ifdef __alpha__
1274 /* The Alpha ELF binutils currently have a bug that 1280 /* The Alpha ELF binutils currently have a bug that
1275 sometimes results in relocs that contain all 1281 sometimes results in relocs that contain all
1276 zeroes. Work around this for now... */ 1282 zeroes. Work around this for now... */
1277 if (((ElfW(Rel) *) reloc)->r_offset == 0) 1283 if (((ElfW (Rel) *) reloc)->r_offset == 0)
1278 continue; 1284 continue;
1279#endif 1285#endif
1280 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); 1286 memcpy (new_base + addr, old_base + addr, sizeof (ElfW (Addr)));
1281 } 1287 }
1282 } 1288 }
1283 break; 1289 break;