maltalinux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: malta

To: maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
From: beth@linux-mips.org
Date: Thu, 11 Aug 2005 14:27:52 +0100
Reply-to: linux-mips@linux-mips.org
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    malta
Changes by:     beth@ftp.linux-mips.org 05/08/11 14:27:51

Modified files:
        linux/arch/mips/kernel: Tag: MaltaRef_2_6 vpe.c 

Log message:
        Support fully linked SP programs.

diff -urN malta/linux/arch/mips/kernel/vpe.c malta/linux/arch/mips/kernel/vpe.c
--- malta/linux/arch/mips/kernel/vpe.c  2005/08/08 13:24:14     1.1.1000.2
+++ malta/linux/arch/mips/kernel/vpe.c  2005/08/11 13:27:51     1.1.1000.3
@@ -852,8 +852,7 @@
        Elf_Shdr *sechdrs;
        long err = 0;
        char *secstrings, *strtab = NULL;
-       unsigned int len, i, symindex = 0, strindex = 0;
-
+       unsigned int len, i, symindex = 0, strindex = 0, relocate = 0;
        struct module mod;      // so we can re-use the relocations code
 
        memset(&mod, 0, sizeof(struct module));
@@ -865,13 +864,17 @@
        /* Sanity checks against insmoding binaries or wrong arch,
           weird elf version */
        if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
-           || hdr->e_type != ET_REL || !elf_check_arch(hdr)
+           || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
+           || !elf_check_arch(hdr)
            || hdr->e_shentsize != sizeof(*sechdrs)) {
                printk(KERN_WARNING
                       "VPE program, wrong arch or weird elf version\n");
 
                return -ENOEXEC;
        }
+       
+       if (hdr->e_type == ET_REL) 
+           relocate = 1;
 
        if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
                printk(KERN_ERR "VPE program length %u truncated\n", len);
@@ -886,87 +889,116 @@
        /* And these should exist, but gcc whinges if we don't init them */
        symindex = strindex = 0;
 
-       for (i = 1; i < hdr->e_shnum; i++) {
+       if (relocate) {
+               for (i = 1; i < hdr->e_shnum; i++) {
+                       if (sechdrs[i].sh_type != SHT_NOBITS
+                           && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) 
{
+                               printk(KERN_ERR "VPE program length %u 
truncated\n",
+                                      len);
+                               return -ENOEXEC;
+                       }
 
-               if (sechdrs[i].sh_type != SHT_NOBITS
-                   && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
-                       printk(KERN_ERR "VPE program length %u truncated\n",
-                              len);
-                       return -ENOEXEC;
+                       /* Mark all sections sh_addr with their address in the
+                          temporary image. */
+                       sechdrs[i].sh_addr = (size_t) hdr + 
sechdrs[i].sh_offset;
+
+                       /* Internal symbols and strings. */
+                       if (sechdrs[i].sh_type == SHT_SYMTAB) {
+                               symindex = i;
+                               strindex = sechdrs[i].sh_link;
+                               strtab = (char *)hdr + 
sechdrs[strindex].sh_offset;
+                       }
                }
 
-               /* Mark all sections sh_addr with their address in the
-                  temporary image. */
-               sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
-
-               /* Internal symbols and strings. */
-               if (sechdrs[i].sh_type == SHT_SYMTAB) {
-                       symindex = i;
-                       strindex = sechdrs[i].sh_link;
-                       strtab = (char *)hdr + sechdrs[strindex].sh_offset;
-               }
+               layout_sections(&mod, hdr, sechdrs, secstrings);
        }
 
-       layout_sections(&mod, hdr, sechdrs, secstrings);
 
        v->load_addr = alloc_progmem(mod.core_size);
        memset(v->load_addr, 0, mod.core_size);
 
        printk("VPE elf_loader: loading to %p\n", v->load_addr);
 
-       for (i = 0; i < hdr->e_shnum; i++) {
-               void *dest;
+       if (relocate) {
+               for (i = 0; i < hdr->e_shnum; i++) {
+                       void *dest;
+
+                       if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+                               continue;
+
+                       dest = v->load_addr + sechdrs[i].sh_entsize;
+
+                       if (sechdrs[i].sh_type != SHT_NOBITS)
+                               memcpy(dest, (void *)sechdrs[i].sh_addr,
+                                      sechdrs[i].sh_size);
+                       /* Update sh_addr to point to copy in image. */
+                       sechdrs[i].sh_addr = (unsigned long)dest;
+                       
+                       printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n", 
+                              secstrings + sechdrs[i].sh_name, 
sechdrs[i].sh_addr);
+               }
 
-               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
-                       continue;
 
-               dest = v->load_addr + sechdrs[i].sh_entsize;
+               /* Fix up syms, so that st_value is a pointer to location. */
+               err = simplify_symbols(sechdrs, symindex, strtab, secstrings,
+                                      hdr->e_shnum, &mod);
+               if (err < 0) {
+                       printk(KERN_WARNING "VPE: unable to simplify 
symbols\n");
+                       goto cleanup;
+               }
 
-               if (sechdrs[i].sh_type != SHT_NOBITS)
-                       memcpy(dest, (void *)sechdrs[i].sh_addr,
-                              sechdrs[i].sh_size);
-               /* Update sh_addr to point to copy in image. */
-               sechdrs[i].sh_addr = (unsigned long)dest;
+               /* Now do relocations. */
+               for (i = 1; i < hdr->e_shnum; i++) {
+                       const char *strtab = (char *)sechdrs[strindex].sh_addr;
+                       unsigned int info = sechdrs[i].sh_info;
+
+                       /* Not a valid relocation section? */
+                       if (info >= hdr->e_shnum)
+                               continue;
+
+                       /* Don't bother with non-allocated sections */
+                       if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+                               continue;
+
+                       if (sechdrs[i].sh_type == SHT_REL)
+                               err = apply_relocations(sechdrs, strtab, 
symindex, i, &mod);
+                       else if (sechdrs[i].sh_type == SHT_RELA)
+                               err = apply_relocate_add(sechdrs, strtab, 
symindex, i,
+                                                        &mod);
+                       if (err < 0) {
+                               printk(KERN_WARNING
+                                      "vpe_elfload: error in relocations err 
%ld\n",
+                                      err);
+                               goto cleanup;
+                       }
+               }
+       } else {
+               for (i = 0; i < hdr->e_shnum; i++) {
 
-               printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n", 
-                      secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
-       }
+                       if (!(sechdrs[i].sh_flags & SHF_ALLOC) || 
sechdrs[i].sh_type == PT_MIPS_REGINFO)
+                               continue;
 
-       /* Fix up syms, so that st_value is a pointer to location. */
-       err =
-               simplify_symbols(sechdrs, symindex, strtab, secstrings,
-                                hdr->e_shnum, &mod);
-       if (err < 0) {
-               printk(KERN_WARNING "VPE: unable to simplify symbols\n");
-               goto cleanup;
-       }
-
-       /* Now do relocations. */
-       for (i = 1; i < hdr->e_shnum; i++) {
-               const char *strtab = (char *)sechdrs[strindex].sh_addr;
-               unsigned int info = sechdrs[i].sh_info;
-
-               /* Not a valid relocation section? */
-               if (info >= hdr->e_shnum)
-                       continue;
-
-               /* Don't bother with non-allocated sections */
-               if (!(sechdrs[info].sh_flags & SHF_ALLOC))
-                       continue;
-
-               if (sechdrs[i].sh_type == SHT_REL)
-                       err = apply_relocations(sechdrs, strtab, symindex, i, 
&mod);
-               else if (sechdrs[i].sh_type == SHT_RELA)
-                       err = apply_relocate_add(sechdrs, strtab, symindex, i,
-                                                &mod);
-               if (err < 0) {
-                       printk(KERN_WARNING
-                              "vpe_elfload: error in relocations err %ld\n",
-                              err);
-                       goto cleanup;
+                       if (sechdrs[i].sh_addr < (unsigned int)v->load_addr) {
+                               printk( KERN_WARNING "vpe_elfload: fully linked 
image has invalid " 
+                                       "section, name %s address 0x%x, before 
load "
+                                       "address of 0x%x\n", secstrings + 
sechdrs[i].sh_name,
+                                       sechdrs[i].sh_addr, (unsigned 
int)v->load_addr);
+                               return -ENOEXEC;
+                       }
+
+                       printk(KERN_DEBUG " copying section sh_name %s, sh_addr 
0x%x size 0x%x\n", 
+                              secstrings + sechdrs[i].sh_name, 
sechdrs[i].sh_addr,
+                              sechdrs[i].sh_size);
+
+                       if (sechdrs[i].sh_type != SHT_NOBITS)
+                               memcpy((void *)sechdrs[i].sh_addr, v->pbuffer + 
sechdrs[i].sh_offset,
+                                       sechdrs[i].sh_size);
+                       else
+                               memset((void *)sechdrs[i].sh_addr, 0, 
sechdrs[i].sh_size);
                }
        }
 
+
        /* make sure it's physically written out */
        flush_icache_range((unsigned long)v->load_addr,
                           (unsigned long)v->load_addr + v->len);
@@ -1119,6 +1151,14 @@
                ret = -ENOEXEC;
        }
 
+       /* It's good to be able to run the SP and if it chokes have a look at
+          the /dev/rt?. But if we reset the pointer to the shared struct we 
+          loose what has happened. So perhaps if garbage is sent to the vpe 
+          device, use it as a trigger for the reset. Hopefully a nice 
+          executable will be along shortly. */
+       if (ret < 0)
+               v->shared_ptr = NULL;
+
        // cleanup any temp buffers
        if (v->pbuffer)
                vfree(v->pbuffer);

<Prev in Thread] Current Thread [Next in Thread>