diff options
| author | Alan Modra | 2015-11-08 09:28:59 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-11-08 10:00:59 -0800 |
| commit | 856f4eaba8a76953e0bbcfc7ebb0ca4f2e3cf351 (patch) | |
| tree | 000e2b8044bc1eb30fc4abb57a4ee33353662de2 /src | |
| parent | 0bcd08ef052bca9b8d08696068c2a0c387d0dd56 (diff) | |
| download | emacs-856f4eaba8a76953e0bbcfc7ebb0ca4f2e3cf351.tar.gz emacs-856f4eaba8a76953e0bbcfc7ebb0ca4f2e3cf351.zip | |
ELF unexec: Tidy code
Separate out some of the more mechanical changes so following patches
are smaller.
* unexelf.c (unexec): Rearrange initialisation of program
header vars. Use pointer vars in loops rather than indexing
section header array via macros. Simplify _OBJC_ sym code
and reloc handling code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexelf.c | 210 |
1 files changed, 96 insertions, 114 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index 1699f310263..d6c66488cc7 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -812,20 +812,11 @@ unexec (const char *new_name, const char *old_name) | |||
| 812 | if (new_base == MAP_FAILED) | 812 | if (new_base == MAP_FAILED) |
| 813 | fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno)); | 813 | fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno)); |
| 814 | 814 | ||
| 815 | new_file_h = (ElfW (Ehdr) *) new_base; | ||
| 816 | new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff); | ||
| 817 | new_section_h = (ElfW (Shdr) *) | ||
| 818 | ((byte *) new_base + old_file_h->e_shoff + new_data2_incr); | ||
| 819 | |||
| 820 | /* Make our new file, program and section headers as copies of the | 815 | /* Make our new file, program and section headers as copies of the |
| 821 | originals. */ | 816 | originals. */ |
| 822 | 817 | ||
| 818 | new_file_h = (ElfW (Ehdr) *) new_base; | ||
| 823 | memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); | 819 | memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); |
| 824 | memcpy (new_program_h, old_program_h, | ||
| 825 | old_file_h->e_phnum * old_file_h->e_phentsize); | ||
| 826 | |||
| 827 | /* Modify the e_shstrndx if necessary. */ | ||
| 828 | PATCH_INDEX (new_file_h->e_shstrndx); | ||
| 829 | 820 | ||
| 830 | /* Fix up file header. We'll add one section. Section header is | 821 | /* Fix up file header. We'll add one section. Section header is |
| 831 | further away now. */ | 822 | further away now. */ |
| @@ -833,6 +824,16 @@ unexec (const char *new_name, const char *old_name) | |||
| 833 | new_file_h->e_shoff += new_data2_incr; | 824 | new_file_h->e_shoff += new_data2_incr; |
| 834 | new_file_h->e_shnum += 1; | 825 | new_file_h->e_shnum += 1; |
| 835 | 826 | ||
| 827 | /* Modify the e_shstrndx if necessary. */ | ||
| 828 | PATCH_INDEX (new_file_h->e_shstrndx); | ||
| 829 | |||
| 830 | new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff); | ||
| 831 | new_section_h = (ElfW (Shdr) *) | ||
| 832 | ((byte *) new_base + old_file_h->e_shoff + new_data2_incr); | ||
| 833 | |||
| 834 | memcpy (new_program_h, old_program_h, | ||
| 835 | old_file_h->e_phnum * old_file_h->e_phentsize); | ||
| 836 | |||
| 836 | #ifdef UNEXELF_DEBUG | 837 | #ifdef UNEXELF_DEBUG |
| 837 | DEBUG_LOG (old_file_h->e_shoff); | 838 | DEBUG_LOG (old_file_h->e_shoff); |
| 838 | fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum); | 839 | fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum); |
| @@ -905,32 +906,35 @@ unexec (const char *new_name, const char *old_name) | |||
| 905 | for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) | 906 | for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) |
| 906 | { | 907 | { |
| 907 | caddr_t src; | 908 | caddr_t src; |
| 909 | ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n); | ||
| 910 | ElfW (Shdr) *new_shdr = &NEW_SECTION_H (nn); | ||
| 911 | |||
| 908 | /* If it is (s)bss section, insert the new data2 section before it. */ | 912 | /* If it is (s)bss section, insert the new data2 section before it. */ |
| 909 | /* new_data2_index is the index of either old_sbss or old_bss, that was | 913 | /* new_data2_index is the index of either old_sbss or old_bss, that was |
| 910 | chosen as a section for new_data2. */ | 914 | chosen as a section for new_data2. */ |
| 911 | if (n == new_data2_index) | 915 | if (n == new_data2_index) |
| 912 | { | 916 | { |
| 913 | /* Steal the data section header for this data2 section. */ | 917 | /* Steal the data section header for this data2 section. */ |
| 914 | memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), | 918 | memcpy (new_shdr, &OLD_SECTION_H (old_data_index), |
| 915 | new_file_h->e_shentsize); | 919 | new_file_h->e_shentsize); |
| 916 | 920 | ||
| 917 | NEW_SECTION_H (nn).sh_addr = new_data2_addr; | 921 | new_shdr->sh_addr = new_data2_addr; |
| 918 | NEW_SECTION_H (nn).sh_offset = new_data2_offset; | 922 | new_shdr->sh_offset = new_data2_offset; |
| 919 | NEW_SECTION_H (nn).sh_size = new_data2_size; | 923 | new_shdr->sh_size = new_data2_size; |
| 920 | /* Use the bss section's alignment. This will assure that the | 924 | /* Use the bss section's alignment. This will assure that the |
| 921 | new data2 section always be placed in the same spot as the old | 925 | new data2 section always be placed in the same spot as the old |
| 922 | bss section by any other application. */ | 926 | bss section by any other application. */ |
| 923 | NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign; | 927 | new_shdr->sh_addralign = old_shdr->sh_addralign; |
| 924 | 928 | ||
| 925 | /* Now copy over what we have in the memory now. */ | 929 | /* Now copy over what we have in the memory now. */ |
| 926 | memcpy (NEW_SECTION_H (nn).sh_offset + new_base, | 930 | memcpy (new_shdr->sh_offset + new_base, |
| 927 | (caddr_t) OLD_SECTION_H (n).sh_addr, | 931 | (caddr_t) old_shdr->sh_addr, |
| 928 | new_data2_size); | 932 | new_data2_size); |
| 929 | nn++; | 933 | nn++; |
| 934 | new_shdr++; | ||
| 930 | } | 935 | } |
| 931 | 936 | ||
| 932 | memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), | 937 | memcpy (new_shdr, old_shdr, old_file_h->e_shentsize); |
| 933 | old_file_h->e_shentsize); | ||
| 934 | 938 | ||
| 935 | if (n == old_bss_index | 939 | if (n == old_bss_index |
| 936 | /* The new bss and sbss section's size is zero, and its file offset | 940 | /* The new bss and sbss section's size is zero, and its file offset |
| @@ -939,13 +943,13 @@ unexec (const char *new_name, const char *old_name) | |||
| 939 | ) | 943 | ) |
| 940 | { | 944 | { |
| 941 | /* NN should be `old_s?bss_index + 1' at this point. */ | 945 | /* NN should be `old_s?bss_index + 1' at this point. */ |
| 942 | NEW_SECTION_H (nn).sh_offset = new_data2_offset + new_data2_size; | 946 | new_shdr->sh_offset = new_data2_offset + new_data2_size; |
| 943 | NEW_SECTION_H (nn).sh_addr = new_data2_addr + new_data2_size; | 947 | new_shdr->sh_addr = new_data2_addr + new_data2_size; |
| 944 | /* Let the new bss section address alignment be the same as the | 948 | /* Let the new bss section address alignment be the same as the |
| 945 | section address alignment followed the old bss section, so | 949 | section address alignment followed the old bss section, so |
| 946 | this section will be placed in exactly the same place. */ | 950 | this section will be placed in exactly the same place. */ |
| 947 | NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign; | 951 | new_shdr->sh_addralign = OLD_SECTION_H (nn).sh_addralign; |
| 948 | NEW_SECTION_H (nn).sh_size = 0; | 952 | new_shdr->sh_size = 0; |
| 949 | } | 953 | } |
| 950 | else | 954 | else |
| 951 | { | 955 | { |
| @@ -975,53 +979,50 @@ temacs: | |||
| 975 | 25 1709 0x4 0x10 | 979 | 25 1709 0x4 0x10 |
| 976 | */ | 980 | */ |
| 977 | 981 | ||
| 978 | if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset | 982 | if (new_shdr->sh_offset >= old_bss_offset |
| 979 | || (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size | 983 | || (new_shdr->sh_offset + new_shdr->sh_size |
| 980 | > new_data2_offset)) | 984 | > new_data2_offset)) |
| 981 | NEW_SECTION_H (nn).sh_offset += new_data2_incr; | 985 | new_shdr->sh_offset += new_data2_incr; |
| 982 | 986 | ||
| 983 | /* Any section that was originally placed after the section | 987 | /* Any section that was originally placed after the section |
| 984 | header table should now be off by the size of one section | 988 | header table should now be off by the size of one section |
| 985 | header table entry. */ | 989 | header table entry. */ |
| 986 | if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff) | 990 | if (new_shdr->sh_offset > new_file_h->e_shoff) |
| 987 | NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize; | 991 | new_shdr->sh_offset += new_file_h->e_shentsize; |
| 988 | } | 992 | } |
| 989 | 993 | ||
| 990 | /* If any section hdr refers to the section after the new .data | 994 | /* If any section hdr refers to the section after the new .data |
| 991 | section, make it refer to next one because we have inserted | 995 | section, make it refer to next one because we have inserted |
| 992 | a new section in between. */ | 996 | a new section in between. */ |
| 993 | 997 | ||
| 994 | PATCH_INDEX (NEW_SECTION_H (nn).sh_link); | 998 | PATCH_INDEX (new_shdr->sh_link); |
| 995 | /* For symbol tables, info is a symbol table index, | 999 | /* For symbol tables, info is a symbol table index, |
| 996 | so don't change it. */ | 1000 | so don't change it. */ |
| 997 | if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB | 1001 | if (new_shdr->sh_type != SHT_SYMTAB |
| 998 | && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM) | 1002 | && new_shdr->sh_type != SHT_DYNSYM) |
| 999 | PATCH_INDEX (NEW_SECTION_H (nn).sh_info); | 1003 | PATCH_INDEX (new_shdr->sh_info); |
| 1000 | 1004 | ||
| 1001 | if (old_sbss_index != -1) | 1005 | if (old_sbss_index != -1) |
| 1002 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss")) | 1006 | if (!strcmp (old_section_names + new_shdr->sh_name, ".sbss")) |
| 1003 | { | 1007 | { |
| 1004 | NEW_SECTION_H (nn).sh_offset = | 1008 | new_shdr->sh_offset = |
| 1005 | round_up (NEW_SECTION_H (nn).sh_offset, | 1009 | round_up (new_shdr->sh_offset, |
| 1006 | NEW_SECTION_H (nn).sh_addralign); | 1010 | new_shdr->sh_addralign); |
| 1007 | NEW_SECTION_H (nn).sh_type = SHT_PROGBITS; | 1011 | new_shdr->sh_type = SHT_PROGBITS; |
| 1008 | } | 1012 | } |
| 1009 | 1013 | ||
| 1010 | /* Now, start to copy the content of sections. */ | 1014 | /* Now, start to copy the content of sections. */ |
| 1011 | if (NEW_SECTION_H (nn).sh_type == SHT_NULL | 1015 | if (new_shdr->sh_type == SHT_NULL |
| 1012 | || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) | 1016 | || new_shdr->sh_type == SHT_NOBITS) |
| 1013 | continue; | 1017 | continue; |
| 1014 | 1018 | ||
| 1015 | /* Write out the sections. .data and .data1 (and data2, called | 1019 | /* Write out the sections. .data and .data1 (and data2, called |
| 1016 | ".data" in the strings table) get copied from the current process | 1020 | ".data" in the strings table) get copied from the current process |
| 1017 | instead of the old file. */ | 1021 | instead of the old file. */ |
| 1018 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") | 1022 | if (!strcmp (old_section_names + new_shdr->sh_name, ".data") |
| 1019 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1023 | || !strcmp (old_section_names + new_shdr->sh_name, ".sdata") |
| 1020 | ".sdata") | 1024 | || !strcmp (old_section_names + new_shdr->sh_name, ".lit4") |
| 1021 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1025 | || !strcmp (old_section_names + new_shdr->sh_name, ".lit8") |
| 1022 | ".lit4") | ||
| 1023 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1024 | ".lit8") | ||
| 1025 | /* The conditional bit below was in Oliva's original code | 1026 | /* The conditional bit below was in Oliva's original code |
| 1026 | (1999-08-25) and seems to have been dropped by mistake | 1027 | (1999-08-25) and seems to have been dropped by mistake |
| 1027 | subsequently. It prevents a crash at startup under X in | 1028 | subsequently. It prevents a crash at startup under X in |
| @@ -1043,28 +1044,22 @@ temacs: | |||
| 1043 | loader, but I never got anywhere with an SGI support call | 1044 | loader, but I never got anywhere with an SGI support call |
| 1044 | seeking clues. -- fx 2002-11-29. */ | 1045 | seeking clues. -- fx 2002-11-29. */ |
| 1045 | #ifdef IRIX6_5 | 1046 | #ifdef IRIX6_5 |
| 1046 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1047 | || !strcmp (old_section_names + new_shdr->sh_name, ".got") |
| 1047 | ".got") | ||
| 1048 | #endif | 1048 | #endif |
| 1049 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1049 | || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1") |
| 1050 | ".sdata1") | 1050 | || !strcmp (old_section_names + new_shdr->sh_name, ".data1") |
| 1051 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1051 | || !strcmp (old_section_names + new_shdr->sh_name, ".sbss")) |
| 1052 | ".data1") | 1052 | src = (caddr_t) old_shdr->sh_addr; |
| 1053 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1054 | ".sbss")) | ||
| 1055 | src = (caddr_t) OLD_SECTION_H (n).sh_addr; | ||
| 1056 | else | 1053 | else |
| 1057 | src = old_base + OLD_SECTION_H (n).sh_offset; | 1054 | src = old_base + old_shdr->sh_offset; |
| 1058 | 1055 | ||
| 1059 | memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, | 1056 | memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size); |
| 1060 | NEW_SECTION_H (nn).sh_size); | ||
| 1061 | 1057 | ||
| 1062 | #if defined __alpha__ && !defined __OpenBSD__ | 1058 | #if defined __alpha__ && !defined __OpenBSD__ |
| 1063 | /* Update Alpha COFF symbol table: */ | 1059 | /* Update Alpha COFF symbol table: */ |
| 1064 | if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug") | 1060 | if (strcmp (old_section_names + old_shdr->sh_name, ".mdebug") == 0) |
| 1065 | == 0) | ||
| 1066 | { | 1061 | { |
| 1067 | pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base); | 1062 | pHDRR symhdr = (pHDRR) (new_shdr->sh_offset + new_base); |
| 1068 | 1063 | ||
| 1069 | symhdr->cbLineOffset += new_data2_size; | 1064 | symhdr->cbLineOffset += new_data2_size; |
| 1070 | symhdr->cbDnOffset += new_data2_size; | 1065 | symhdr->cbDnOffset += new_data2_size; |
| @@ -1081,13 +1076,13 @@ temacs: | |||
| 1081 | #endif /* __alpha__ && !__OpenBSD__ */ | 1076 | #endif /* __alpha__ && !__OpenBSD__ */ |
| 1082 | 1077 | ||
| 1083 | #if defined (_SYSTYPE_SYSV) | 1078 | #if defined (_SYSTYPE_SYSV) |
| 1084 | if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG | 1079 | if (new_shdr->sh_type == SHT_MIPS_DEBUG |
| 1085 | && old_mdebug_index != -1) | 1080 | && old_mdebug_index != -1) |
| 1086 | { | 1081 | { |
| 1087 | ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset; | 1082 | ptrdiff_t new_offset = new_shdr->sh_offset; |
| 1088 | ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset; | 1083 | ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset; |
| 1089 | ptrdiff_t diff = new_offset - old_offset; | 1084 | ptrdiff_t diff = new_offset - old_offset; |
| 1090 | HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); | 1085 | HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base); |
| 1091 | 1086 | ||
| 1092 | if (diff) | 1087 | if (diff) |
| 1093 | { | 1088 | { |
| @@ -1123,8 +1118,8 @@ temacs: | |||
| 1123 | n_phdrr->__fileaddr += movement; \ | 1118 | n_phdrr->__fileaddr += movement; \ |
| 1124 | } | 1119 | } |
| 1125 | 1120 | ||
| 1126 | HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset); | 1121 | HDRR *o_phdrr = (HDRR *) ((byte *) old_base + old_shdr->sh_offset); |
| 1127 | HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset); | 1122 | HDRR *n_phdrr = (HDRR *) ((byte *) new_base + new_shdr->sh_offset); |
| 1128 | unsigned movement = new_data2_size; | 1123 | unsigned movement = new_data2_size; |
| 1129 | 1124 | ||
| 1130 | MDEBUGADJUST (idnMax, cbDnOffset); | 1125 | MDEBUGADJUST (idnMax, cbDnOffset); |
| @@ -1141,8 +1136,8 @@ temacs: | |||
| 1141 | requires special handling. */ | 1136 | requires special handling. */ |
| 1142 | if (n_phdrr->cbLine > 0) | 1137 | if (n_phdrr->cbLine > 0) |
| 1143 | { | 1138 | { |
| 1144 | if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset | 1139 | if (o_phdrr->cbLineOffset > (old_shdr->sh_offset |
| 1145 | + OLD_SECTION_H (n).sh_size)) | 1140 | + old_shdr->sh_size)) |
| 1146 | { | 1141 | { |
| 1147 | /* line data is in a hole in elf. do special copy and adjust | 1142 | /* line data is in a hole in elf. do special copy and adjust |
| 1148 | for this ld mistake. | 1143 | for this ld mistake. |
| @@ -1162,13 +1157,11 @@ temacs: | |||
| 1162 | #endif /* __sgi */ | 1157 | #endif /* __sgi */ |
| 1163 | 1158 | ||
| 1164 | /* If it is the symbol table, its st_shndx field needs to be patched. */ | 1159 | /* If it is the symbol table, its st_shndx field needs to be patched. */ |
| 1165 | if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB | 1160 | if (new_shdr->sh_type == SHT_SYMTAB |
| 1166 | || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) | 1161 | || new_shdr->sh_type == SHT_DYNSYM) |
| 1167 | { | 1162 | { |
| 1168 | ElfW (Shdr) *spt = &NEW_SECTION_H (nn); | 1163 | ptrdiff_t num = new_shdr->sh_size / new_shdr->sh_entsize; |
| 1169 | ptrdiff_t num = spt->sh_size / spt->sh_entsize; | 1164 | ElfW (Sym) *sym = (ElfW (Sym) *) (new_shdr->sh_offset + new_base); |
| 1170 | ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset + | ||
| 1171 | new_base); | ||
| 1172 | for (; num--; sym++) | 1165 | for (; num--; sym++) |
| 1173 | { | 1166 | { |
| 1174 | if ((sym->st_shndx == SHN_UNDEF) | 1167 | if ((sym->st_shndx == SHN_UNDEF) |
| @@ -1186,15 +1179,16 @@ temacs: | |||
| 1186 | { | 1179 | { |
| 1187 | byte *symnames; | 1180 | byte *symnames; |
| 1188 | ElfW (Sym) *symp, *symendp; | 1181 | ElfW (Sym) *symp, *symendp; |
| 1182 | ElfW (Shdr) *sym_shdr = &NEW_SECTION_H (n); | ||
| 1189 | 1183 | ||
| 1190 | if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM | 1184 | if (sym_shdr->sh_type != SHT_DYNSYM |
| 1191 | && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) | 1185 | && sym_shdr->sh_type != SHT_SYMTAB) |
| 1192 | continue; | 1186 | continue; |
| 1193 | 1187 | ||
| 1194 | symnames = ((byte *) new_base | 1188 | symnames = ((byte *) new_base |
| 1195 | + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); | 1189 | + NEW_SECTION_H (sym_shdr->sh_link).sh_offset); |
| 1196 | symp = (ElfW (Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); | 1190 | symp = (ElfW (Sym) *) (sym_shdr->sh_offset + new_base); |
| 1197 | symendp = (ElfW (Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); | 1191 | symendp = (ElfW (Sym) *) ((byte *) symp + sym_shdr->sh_size); |
| 1198 | 1192 | ||
| 1199 | for (; symp < symendp; symp ++) | 1193 | for (; symp < symendp; symp ++) |
| 1200 | { | 1194 | { |
| @@ -1218,22 +1212,21 @@ temacs: | |||
| 1218 | if (strncmp ((char *) (symnames + symp->st_name), | 1212 | if (strncmp ((char *) (symnames + symp->st_name), |
| 1219 | "_OBJC_", sizeof ("_OBJC_") - 1) == 0) | 1213 | "_OBJC_", sizeof ("_OBJC_") - 1) == 0) |
| 1220 | { | 1214 | { |
| 1221 | caddr_t old, new; | 1215 | ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx); |
| 1216 | ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr; | ||
| 1217 | ptrdiff_t newoff = reladdr + new_shdr->sh_offset; | ||
| 1222 | 1218 | ||
| 1223 | new = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr) | ||
| 1224 | + NEW_SECTION_H (symp->st_shndx).sh_offset + new_base); | ||
| 1225 | /* "Unpatch" index. */ | 1219 | /* "Unpatch" index. */ |
| 1226 | nn = symp->st_shndx; | 1220 | nn = symp->st_shndx; |
| 1227 | if (nn > old_bss_index) | 1221 | if (nn > old_bss_index) |
| 1228 | nn--; | 1222 | nn--; |
| 1229 | if (nn == old_bss_index) | 1223 | if (nn == old_bss_index) |
| 1230 | memset (new, 0, symp->st_size); | 1224 | memset (new_base + newoff, 0, symp->st_size); |
| 1231 | else | 1225 | else |
| 1232 | { | 1226 | { |
| 1233 | old = ((symp->st_value | 1227 | ElfW (Shdr) *old_shdr = &OLD_SECTION_H (nn); |
| 1234 | - NEW_SECTION_H (symp->st_shndx).sh_addr) | 1228 | ptrdiff_t oldoff = reladdr + old_shdr->sh_offset; |
| 1235 | + OLD_SECTION_H (nn).sh_offset + old_base); | 1229 | memcpy (new_base + newoff, old_base + oldoff, symp->st_size); |
| 1236 | memcpy (new, old, symp->st_size); | ||
| 1237 | } | 1230 | } |
| 1238 | } | 1231 | } |
| 1239 | #endif | 1232 | #endif |
| @@ -1244,13 +1237,10 @@ temacs: | |||
| 1244 | that it can undo relocations performed by the runtime linker. */ | 1237 | that it can undo relocations performed by the runtime linker. */ |
| 1245 | for (n = new_file_h->e_shnum; 0 < --n; ) | 1238 | for (n = new_file_h->e_shnum; 0 < --n; ) |
| 1246 | { | 1239 | { |
| 1247 | ElfW (Shdr) section = NEW_SECTION_H (n); | 1240 | ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n); |
| 1248 | 1241 | ElfW (Shdr) *shdr; | |
| 1249 | /* Cause a compilation error if anyone uses n instead of nn below. */ | ||
| 1250 | #define n ((void) 0); | ||
| 1251 | n /* Prevent 'macro "n" is not used' warnings. */ | ||
| 1252 | 1242 | ||
| 1253 | switch (section.sh_type) | 1243 | switch (rel_shdr->sh_type) |
| 1254 | { | 1244 | { |
| 1255 | default: | 1245 | default: |
| 1256 | break; | 1246 | break; |
| @@ -1259,28 +1249,22 @@ temacs: | |||
| 1259 | /* This code handles two different size structs, but there should | 1249 | /* This code handles two different size structs, but there should |
| 1260 | be no harm in that provided that r_offset is always the first | 1250 | be no harm in that provided that r_offset is always the first |
| 1261 | member. */ | 1251 | member. */ |
| 1262 | nn = section.sh_info; | 1252 | shdr = &NEW_SECTION_H (rel_shdr->sh_info); |
| 1263 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") | 1253 | if (!strcmp (old_section_names + shdr->sh_name, ".data") |
| 1264 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1254 | || !strcmp (old_section_names + shdr->sh_name, ".sdata") |
| 1265 | ".sdata") | 1255 | || !strcmp (old_section_names + shdr->sh_name, ".lit4") |
| 1266 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1256 | || !strcmp (old_section_names + shdr->sh_name, ".lit8") |
| 1267 | ".lit4") | ||
| 1268 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1269 | ".lit8") | ||
| 1270 | #ifdef IRIX6_5 /* see above */ | 1257 | #ifdef IRIX6_5 /* see above */ |
| 1271 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1258 | || !strcmp (old_section_names + shdr->sh_name, ".got") |
| 1272 | ".got") | ||
| 1273 | #endif | 1259 | #endif |
| 1274 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1260 | || !strcmp (old_section_names + shdr->sh_name, ".sdata1") |
| 1275 | ".sdata1") | 1261 | || !strcmp (old_section_names + shdr->sh_name, ".data1")) |
| 1276 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1277 | ".data1")) | ||
| 1278 | { | 1262 | { |
| 1279 | ElfW (Addr) offset = (NEW_SECTION_H (nn).sh_addr | 1263 | ElfW (Addr) offset = shdr->sh_addr - shdr->sh_offset; |
| 1280 | - NEW_SECTION_H (nn).sh_offset); | 1264 | caddr_t reloc = old_base + rel_shdr->sh_offset, end; |
| 1281 | caddr_t reloc = old_base + section.sh_offset, end; | 1265 | for (end = reloc + rel_shdr->sh_size; |
| 1282 | for (end = reloc + section.sh_size; reloc < end; | 1266 | reloc < end; |
| 1283 | reloc += section.sh_entsize) | 1267 | reloc += rel_shdr->sh_entsize) |
| 1284 | { | 1268 | { |
| 1285 | ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset; | 1269 | ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset; |
| 1286 | #ifdef __alpha__ | 1270 | #ifdef __alpha__ |
| @@ -1295,8 +1279,6 @@ temacs: | |||
| 1295 | } | 1279 | } |
| 1296 | break; | 1280 | break; |
| 1297 | } | 1281 | } |
| 1298 | |||
| 1299 | #undef n | ||
| 1300 | } | 1282 | } |
| 1301 | 1283 | ||
| 1302 | /* Write out new_file, and free the buffers. */ | 1284 | /* Write out new_file, and free the buffers. */ |