aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-10-10 08:33:03 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-10-11 18:46:19 -0400
commitbdf5d42c6e4d7aa56251b8899f60f55a88c0aaa7 (patch)
tree476947dc00f331238a56f138e164465d69aa5615 /arch
parent4b92fe2309c762d9ba9201a16f20d6d167e641b3 (diff)
[MIPS] VPE: reimplement ELF loader.
Loading ELF binaries based on the section table is totally wrong. This still leaves the other fat bug of referencing symbols in an executable unfixed, so people better don't run strip on their binaries ... As added bonus the new loader is also 23 lines shorter. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/kernel/vpe.c45
1 files changed, 11 insertions, 34 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 45077c4b2e22..61b729fa0548 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -936,8 +936,18 @@ static int vpe_elfload(struct vpe * v)
936 936
937 } 937 }
938 } else { 938 } else {
939 for (i = 0; i < hdr->e_shnum; i++) { 939 struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
940 940
941 for (i = 0; i < hdr->e_phnum; i++) {
942 if (phdr->p_type != PT_LOAD)
943 continue;
944
945 memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
946 memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
947 phdr++;
948 }
949
950 for (i = 0; i < hdr->e_shnum; i++) {
941 /* Internal symbols and strings. */ 951 /* Internal symbols and strings. */
942 if (sechdrs[i].sh_type == SHT_SYMTAB) { 952 if (sechdrs[i].sh_type == SHT_SYMTAB) {
943 symindex = i; 953 symindex = i;
@@ -948,39 +958,6 @@ static int vpe_elfload(struct vpe * v)
948 magic symbols */ 958 magic symbols */
949 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; 959 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
950 } 960 }
951
952 /* filter sections we dont want in the final image */
953 if (!(sechdrs[i].sh_flags & SHF_ALLOC) ||
954 (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) {
955 printk( KERN_DEBUG " ignoring section, "
956 "name %s type %x address 0x%x \n",
957 secstrings + sechdrs[i].sh_name,
958 sechdrs[i].sh_type, sechdrs[i].sh_addr);
959 continue;
960 }
961
962 if (sechdrs[i].sh_addr < (unsigned int)v->load_addr) {
963 printk( KERN_WARNING "VPE loader: "
964 "fully linked image has invalid section, "
965 "name %s type %x address 0x%x, before load "
966 "address of 0x%x\n",
967 secstrings + sechdrs[i].sh_name,
968 sechdrs[i].sh_type, sechdrs[i].sh_addr,
969 (unsigned int)v->load_addr);
970 return -ENOEXEC;
971 }
972
973 printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x "
974 "size 0x%x0 from x%p\n",
975 secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr,
976 sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset);
977
978 if (sechdrs[i].sh_type != SHT_NOBITS)
979 memcpy((void *)sechdrs[i].sh_addr,
980 (char *)hdr + sechdrs[i].sh_offset,
981 sechdrs[i].sh_size);
982 else
983 memset((void *)sechdrs[i].sh_addr, 0, sechdrs[i].sh_size);
984 } 961 }
985 } 962 }
986 963