diff options
| -rw-r--r-- | src/unexelf.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index f50e849fdcf..c53974be9f2 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -682,7 +682,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 682 | ElfW(Addr) new_data2_addr; | 682 | ElfW(Addr) new_data2_addr; |
| 683 | 683 | ||
| 684 | int n, nn; | 684 | int n, nn; |
| 685 | int old_bss_index, old_sbss_index; | 685 | int old_bss_index, old_sbss_index, old_plt_index; |
| 686 | int old_data_index, new_data2_index; | 686 | int old_data_index, new_data2_index; |
| 687 | int old_mdebug_index; | 687 | int old_mdebug_index; |
| 688 | struct stat stat_buf; | 688 | struct stat stat_buf; |
| @@ -740,15 +740,34 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 740 | old_sbss_index = find_section (".sbss", old_section_names, | 740 | old_sbss_index = find_section (".sbss", old_section_names, |
| 741 | old_name, old_file_h, old_section_h, 1); | 741 | old_name, old_file_h, old_section_h, 1); |
| 742 | if (old_sbss_index != -1) | 742 | if (old_sbss_index != -1) |
| 743 | if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS) | 743 | if (OLD_SECTION_H (old_sbss_index).sh_type != SHT_NOBITS) |
| 744 | old_sbss_index = -1; | 744 | old_sbss_index = -1; |
| 745 | 745 | ||
| 746 | if (old_sbss_index == -1) | 746 | /* PowerPC64 has .plt in the BSS section. */ |
| 747 | old_plt_index = find_section (".plt", old_section_names, | ||
| 748 | old_name, old_file_h, old_section_h, 1); | ||
| 749 | if (old_plt_index != -1) | ||
| 750 | if (OLD_SECTION_H (old_plt_index).sh_type != SHT_NOBITS) | ||
| 751 | old_plt_index = -1; | ||
| 752 | |||
| 753 | if (old_sbss_index == -1 && old_plt_index == -1) | ||
| 747 | { | 754 | { |
| 748 | old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; | 755 | old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; |
| 749 | old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; | 756 | old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; |
| 750 | new_data2_index = old_bss_index; | 757 | new_data2_index = old_bss_index; |
| 751 | } | 758 | } |
| 759 | else if (old_plt_index != -1 | ||
| 760 | && (old_sbss_index == -1 | ||
| 761 | || (OLD_SECTION_H (old_sbss_index).sh_addr | ||
| 762 | > OLD_SECTION_H (old_plt_index).sh_addr))) | ||
| 763 | { | ||
| 764 | old_bss_addr = OLD_SECTION_H (old_plt_index).sh_addr; | ||
| 765 | old_bss_size = OLD_SECTION_H (old_bss_index).sh_size | ||
| 766 | + OLD_SECTION_H (old_plt_index).sh_size; | ||
| 767 | if (old_sbss_index != -1) | ||
| 768 | old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size; | ||
| 769 | new_data2_index = old_plt_index; | ||
| 770 | } | ||
| 752 | else | 771 | else |
| 753 | { | 772 | { |
| 754 | old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; | 773 | old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; |
| @@ -934,7 +953,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 934 | if (n == old_bss_index | 953 | if (n == old_bss_index |
| 935 | /* The new bss and sbss section's size is zero, and its file offset | 954 | /* The new bss and sbss section's size is zero, and its file offset |
| 936 | and virtual address should be off by NEW_DATA2_SIZE. */ | 955 | and virtual address should be off by NEW_DATA2_SIZE. */ |
| 937 | || n == old_sbss_index | 956 | || n == old_sbss_index || n == old_plt_index |
| 938 | ) | 957 | ) |
| 939 | { | 958 | { |
| 940 | /* NN should be `old_s?bss_index + 1' at this point. */ | 959 | /* NN should be `old_s?bss_index + 1' at this point. */ |