kernel/kexec_file.c: remove unneeded for-loop in kexec_purgatory_setup_sechdrs
To update the entry point there is an extra loop over all section headers although this can be done in the main loop. So move it there and eliminate the extra loop and variable to store the 'entry section index'. Also, in the main loop, move the usual case, i.e. non-bss section, out of the extra if-block. Link: http://lkml.kernel.org/r/20180321112751.22196-8-prudo@linux.vnet.ibm.com Signed-off-by: Philipp Rudo <prudo@linux.vnet.ibm.com> Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Acked-by: Dave Young <dyoung@redhat.com> Cc: AKASHI Takahiro <takahiro.akashi@linaro.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
930457057a
commit
f1b1cca396
|
@ -792,7 +792,6 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
|
||||||
unsigned char *buf_addr;
|
unsigned char *buf_addr;
|
||||||
unsigned char *src;
|
unsigned char *src;
|
||||||
Elf_Shdr *sechdrs;
|
Elf_Shdr *sechdrs;
|
||||||
int entry_sidx = -1;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr));
|
sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr));
|
||||||
|
@ -824,32 +823,11 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
|
||||||
sechdrs[i].sh_offset;
|
sechdrs[i].sh_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Identify entry point section and make entry relative to section
|
|
||||||
* start.
|
|
||||||
*/
|
|
||||||
kbuf->image->start = pi->ehdr->e_entry;
|
|
||||||
for (i = 0; i < pi->ehdr->e_shnum; i++) {
|
|
||||||
if (!(sechdrs[i].sh_flags & SHF_ALLOC))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(sechdrs[i].sh_flags & SHF_EXECINSTR))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Make entry section relative */
|
|
||||||
if (sechdrs[i].sh_addr <= pi->ehdr->e_entry &&
|
|
||||||
((sechdrs[i].sh_addr + sechdrs[i].sh_size) >
|
|
||||||
pi->ehdr->e_entry)) {
|
|
||||||
entry_sidx = i;
|
|
||||||
kbuf->image->start -= sechdrs[i].sh_addr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load SHF_ALLOC sections */
|
/* Load SHF_ALLOC sections */
|
||||||
buf_addr = kbuf->buffer;
|
buf_addr = kbuf->buffer;
|
||||||
load_addr = curr_load_addr = kbuf->mem;
|
load_addr = curr_load_addr = kbuf->mem;
|
||||||
bss_addr = load_addr + kbuf->bufsz;
|
bss_addr = load_addr + kbuf->bufsz;
|
||||||
|
kbuf->image->start = pi->ehdr->e_entry;
|
||||||
|
|
||||||
for (i = 0; i < pi->ehdr->e_shnum; i++) {
|
for (i = 0; i < pi->ehdr->e_shnum; i++) {
|
||||||
unsigned long align;
|
unsigned long align;
|
||||||
|
@ -858,13 +836,28 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
align = sechdrs[i].sh_addralign;
|
align = sechdrs[i].sh_addralign;
|
||||||
if (sechdrs[i].sh_type != SHT_NOBITS) {
|
|
||||||
|
if (sechdrs[i].sh_type == SHT_NOBITS) {
|
||||||
|
bss_addr = ALIGN(bss_addr, align);
|
||||||
|
sechdrs[i].sh_addr = bss_addr;
|
||||||
|
bss_addr += sechdrs[i].sh_size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
curr_load_addr = ALIGN(curr_load_addr, align);
|
curr_load_addr = ALIGN(curr_load_addr, align);
|
||||||
offset = curr_load_addr - load_addr;
|
offset = curr_load_addr - load_addr;
|
||||||
/* We already modifed ->sh_offset to keep src addr */
|
/* We already modifed ->sh_offset to keep src addr */
|
||||||
src = (char *) sechdrs[i].sh_offset;
|
src = (char *)sechdrs[i].sh_offset;
|
||||||
memcpy(buf_addr + offset, src, sechdrs[i].sh_size);
|
memcpy(buf_addr + offset, src, sechdrs[i].sh_size);
|
||||||
|
|
||||||
|
if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
|
||||||
|
pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
|
||||||
|
pi->ehdr->e_entry < (sechdrs[i].sh_addr
|
||||||
|
+ sechdrs[i].sh_size)) {
|
||||||
|
kbuf->image->start -= sechdrs[i].sh_addr;
|
||||||
|
kbuf->image->start += curr_load_addr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Store load address and source address of section */
|
/* Store load address and source address of section */
|
||||||
sechdrs[i].sh_addr = curr_load_addr;
|
sechdrs[i].sh_addr = curr_load_addr;
|
||||||
|
|
||||||
|
@ -876,16 +869,7 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
|
||||||
|
|
||||||
/* Advance to the next address */
|
/* Advance to the next address */
|
||||||
curr_load_addr += sechdrs[i].sh_size;
|
curr_load_addr += sechdrs[i].sh_size;
|
||||||
} else {
|
|
||||||
bss_addr = ALIGN(bss_addr, align);
|
|
||||||
sechdrs[i].sh_addr = bss_addr;
|
|
||||||
bss_addr += sechdrs[i].sh_size;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Update entry point based on load address of text section */
|
|
||||||
if (entry_sidx >= 0)
|
|
||||||
kbuf->image->start += sechdrs[entry_sidx].sh_addr;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue