diff options
| author | Stefan Monnier | 2012-03-25 16:37:21 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-03-25 16:37:21 -0400 |
| commit | 699c782b7668c44d0fa4446331b0590a6d5dac82 (patch) | |
| tree | 5dcce364741d0761920a3d274b0fc8aba4103d45 /src/unexelf.c | |
| parent | 98fb480ee31bf74cf554044f60f21df16566dd7f (diff) | |
| parent | e99a9b8bdccadded1f6fae88ee7a2a93dfd4eacf (diff) | |
| download | emacs-pending.tar.gz emacs-pending.zip | |
Merge from trunkpending
Diffstat (limited to 'src/unexelf.c')
| -rw-r--r-- | src/unexelf.c | 92 |
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 | ||
| 4 | This file is part of GNU Emacs. | 4 | This 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 | ||
| 566 | static ElfW(Addr) | 566 | static ElfW (Addr) |
| 567 | round_up (ElfW(Addr) x, ElfW(Addr) y) | 567 | round_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 | ||
| 582 | static int | 582 | static int |
| 583 | find_section (const char *name, const char *section_names, const char *file_name, | 583 | find_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; |