summaryrefslogtreecommitdiff
path: root/src/unexelf.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2005-11-01 21:32:27 +0000
committerAndreas Schwab <schwab@suse.de>2005-11-01 21:32:27 +0000
commit825dad898e2d43eb2802c070fd4ce08816f907df (patch)
treeeaaff34a0c280858f17d3cb3a950c9d09290151f /src/unexelf.c
parentcf7ec6c373428dd13458481707ee2a902e83f5b2 (diff)
(unexec): Handle .plt section in BSS segment.
Diffstat (limited to 'src/unexelf.c')
-rw-r--r--src/unexelf.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index f50e849fdc..c53974be9f 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -682,7 +682,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
ElfW(Addr) new_data2_addr;
int n, nn;
- int old_bss_index, old_sbss_index;
+ int old_bss_index, old_sbss_index, old_plt_index;
int old_data_index, new_data2_index;
int old_mdebug_index;
struct stat stat_buf;
@@ -740,15 +740,34 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
old_sbss_index = find_section (".sbss", old_section_names,
old_name, old_file_h, old_section_h, 1);
if (old_sbss_index != -1)
- if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS)
+ if (OLD_SECTION_H (old_sbss_index).sh_type != SHT_NOBITS)
old_sbss_index = -1;
- if (old_sbss_index == -1)
+ /* PowerPC64 has .plt in the BSS section. */
+ old_plt_index = find_section (".plt", old_section_names,
+ old_name, old_file_h, old_section_h, 1);
+ if (old_plt_index != -1)
+ if (OLD_SECTION_H (old_plt_index).sh_type != SHT_NOBITS)
+ old_plt_index = -1;
+
+ if (old_sbss_index == -1 && old_plt_index == -1)
{
old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
new_data2_index = old_bss_index;
}
+ else if (old_plt_index != -1
+ && (old_sbss_index == -1
+ || (OLD_SECTION_H (old_sbss_index).sh_addr
+ > OLD_SECTION_H (old_plt_index).sh_addr)))
+ {
+ old_bss_addr = OLD_SECTION_H (old_plt_index).sh_addr;
+ old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
+ + OLD_SECTION_H (old_plt_index).sh_size;
+ if (old_sbss_index != -1)
+ old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size;
+ new_data2_index = old_plt_index;
+ }
else
{
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)
if (n == old_bss_index
/* The new bss and sbss section's size is zero, and its file offset
and virtual address should be off by NEW_DATA2_SIZE. */
- || n == old_sbss_index
+ || n == old_sbss_index || n == old_plt_index
)
{
/* NN should be `old_s?bss_index + 1' at this point. */