Ignore:
Timestamp:
Jul 14, 2020, 7:49:28 PM (4 years ago)
Author:
coas-nagasima
Message:

prototoolにelfファイルヘッダーを付けてntshellで必要な情報を読み取れるよう変更

File:
1 edited

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/ntshell/src/main.c

    r442 r443  
    7575#include "netcmd.h"
    7676#endif
     77#include "../musl-1.1.18/include/elf.h"
    7778
    7879ID ws_api_mailboxid = MAIN_DATAQUEUE;
     
    122123static void main_timeout(struct main_obj_t *obj, bool_t wakeup);
    123124static int execute_command(struct main_obj_t *obj, int wait);
     125static const Elf32_Ehdr *load_elf(const uint8_t *file);
     126static void execute_elf(const Elf32_Ehdr *, long *args);
    124127static int usrcmd_ntopt_callback(long *args, void *extobj);
    125128#ifndef NTSHELL_NO_SOCKET
     
    134137int shellcmd_exit_code;
    135138volatile int shellcmd_state;
    136 typedef void (*PowerOn_Reset_t)(long *args);
     139typedef void (*elf_entry_t)(long *args);
    137140jmp_buf shellcmd_exit;
    138141
     
    549552
    550553        if ((found == 0) && setjmp(shellcmd_exit) == 0) {
    551                 found = 1;
    552                 (*((PowerOn_Reset_t *)0x18200000))(args);
     554                const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
     555                if (elf != NULL) {
     556                        found = 1;
     557                        execute_elf(elf, args);
     558                }
    553559        }
    554560
     
    643649}
    644650
     651const Elf32_Ehdr *load_elf(const uint8_t *file)
     652{
     653        Elf32_Ehdr Ehdr;
     654
     655        memcpy(&Ehdr, &file[0], sizeof(Elf32_Ehdr));
     656
     657        // Magic
     658        if ((Ehdr.e_ident[EI_MAG0] != ELFMAG0)
     659                || (Ehdr.e_ident[EI_MAG1] != ELFMAG1)
     660                || (Ehdr.e_ident[EI_MAG2] != ELFMAG2)
     661                || (Ehdr.e_ident[EI_MAG3] != ELFMAG3))
     662                return NULL;
     663
     664        // Class
     665        if (Ehdr.e_ident[EI_CLASS] != ELFCLASS32)
     666                return NULL;
     667
     668        // Byte order
     669        if (Ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
     670                return NULL;
     671
     672        // ELF Version
     673        if (Ehdr.e_ident[EI_VERSION] != EV_CURRENT)
     674                return NULL;
     675
     676        // type
     677        if (Ehdr.e_type != ET_EXEC)
     678                return NULL;
     679
     680        // Machine
     681        if (Ehdr.e_machine != EM_ARM)
     682                return NULL;
     683
     684        if (Ehdr.e_version != EV_CURRENT)
     685                return NULL;
     686
     687        return (const Elf32_Ehdr *)file;
     688}
     689
     690void execute_elf(const Elf32_Ehdr *Ehdr, long *args)
     691{
     692        const uint8_t *file = (const uint8_t *)Ehdr;
     693        Elf32_Shdr StringShdr;
     694        memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
     695
     696        if (Ehdr->e_shoff > 0) {
     697                Elf32_Shdr Shdr;
     698                for (int i = 0; i < Ehdr->e_shnum; i++) {
     699                        memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
     700                        Shdr.sh_size -= Shdr.sh_addr;
     701
     702                        char *name;
     703                        if (Shdr.sh_name > 0) {
     704                                name = (char *)&file[StringShdr.sh_offset + Shdr.sh_name];
     705                        }
     706                        else {
     707                                name = NULL;
     708                        }
     709
     710                        if ((Shdr.sh_flags & SHF_ALLOC) == 0) {
     711                                // skip
     712                        }
     713                        else if (Shdr.sh_type == SHT_PROGBITS) {
     714                                if ((Shdr.sh_flags & SHF_WRITE) == 0) {
     715                                        // inplace
     716                                }
     717                                else {
     718                                        memcpy(Shdr.sh_addr, Shdr.sh_offset, Shdr.sh_size);
     719                                }
     720                        }
     721                        else if (Shdr.sh_type == SHT_NOBITS) {
     722                                memset(Shdr.sh_addr, 0, Shdr.sh_size);
     723                        }
     724                        else {
     725                                // skip
     726                        }
     727                }
     728        }
     729
     730        ((elf_entry_t)Ehdr->e_entry)(args);
     731}
Note: See TracChangeset for help on using the changeset viewer.