Annotation of qemu/roms/openbios/libopenbios/xcoff_load.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *
        !             3:  *       <xcoff_load.c>
        !             4:  *
        !             5:  *       XCOFF file loader
        !             6:  *
        !             7:  *   Copyright (C) 2009 Laurent Vivier ([email protected])
        !             8:  *
        !             9:  *   from original XCOFF loader by Steven Noonan <[email protected]>
        !            10:  *
        !            11:  *   This program is free software; you can redistribute it and/or
        !            12:  *   modify it under the terms of the GNU General Public License
        !            13:  *   version 2
        !            14:  *
        !            15:  */
        !            16: 
        !            17: #include "config.h"
        !            18: #include "libopenbios/bindings.h"
        !            19: #include "libopenbios/xcoff_load.h"
        !            20: 
        !            21: #include "arch/common/xcoff.h"
        !            22: 
        !            23: #ifdef CONFIG_PPC
        !            24: extern void             flush_icache_range( char *start, char *stop );
        !            25: #endif
        !            26: 
        !            27: //#define DEBUG_XCOFF
        !            28: 
        !            29: #ifdef DEBUG_XCOFF
        !            30: #define DPRINTF(fmt, args...) \
        !            31:     do { printk("%s: " fmt, __func__ , ##args); } while (0)
        !            32: #else
        !            33: #define DPRINTF(fmt, args...) \
        !            34:     do { } while (0)
        !            35: #endif
        !            36: 
        !            37: int 
        !            38: is_xcoff(COFF_filehdr_t *fhdr)
        !            39: {
        !            40:        return (fhdr->f_magic == U802WRMAGIC
        !            41:             || fhdr->f_magic == U802ROMAGIC
        !            42:            || fhdr->f_magic == U802TOCMAGIC
        !            43:            || fhdr->f_magic == U802TOMAGIC);
        !            44: }
        !            45: 
        !            46: int 
        !            47: xcoff_load(struct sys_info *info, const char *filename)
        !            48: {
        !            49:        // Currently not implemented
        !            50:        return LOADER_NOT_SUPPORT;
        !            51: }
        !            52: 
        !            53: void
        !            54: xcoff_init_program(void)
        !            55: {
        !            56:        char *base;
        !            57:        COFF_filehdr_t *fhdr;
        !            58:        COFF_aouthdr_t *ahdr;
        !            59:        COFF_scnhdr_t *shdr;
        !            60:        uint32_t offset;
        !            61:        size_t total_size = 0;
        !            62:        int i;
        !            63: 
        !            64:        feval("0 state-valid !");
        !            65: 
        !            66:        feval("load-base");
        !            67:        base = (char*)cell2pointer(POP());
        !            68: 
        !            69:        fhdr = (COFF_filehdr_t*)base;
        !            70: 
        !            71:        /* Is it an XCOFF file ? */
        !            72:        if (!is_xcoff(fhdr)) {
        !            73:                DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic);
        !            74:                return;
        !            75:        }
        !            76: 
        !            77:        /* Is it executable ? */
        !            78:        if (fhdr->f_magic != 0x01DF &&
        !            79:            (fhdr->f_flags & COFF_F_EXEC) == 0) {
        !            80:                DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags);
        !            81:                return;
        !            82:        }
        !            83: 
        !            84:        /* Optional header is a.out ? */
        !            85:        if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) {
        !            86:                DPRINTF("AOUT optional error size mismatch in XCOFF file\n");
        !            87:                return;
        !            88:        }
        !            89: 
        !            90:         ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t));
        !            91: 
        !            92:        /* check a.out magic number */
        !            93:        if (ahdr->magic != AOUT_MAGIC) {
        !            94:                DPRINTF("Invalid AOUT optional header\n");
        !            95:                return;
        !            96:        }
        !            97: 
        !            98:        offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t);
        !            99: 
        !           100:        DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns);
        !           101: 
        !           102:        for (i = 0; i < fhdr->f_nscns; i++) {
        !           103: 
        !           104:                DPRINTF("Read header at offset %0x\n", offset);
        !           105: 
        !           106:                shdr = (COFF_scnhdr_t*)(base + offset);
        !           107: 
        !           108:                DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n",
        !           109:                        shdr->s_name, offset, shdr->s_scnptr,
        !           110:                        shdr->s_vaddr, shdr->s_size);
        !           111: 
        !           112:                if (strcmp(shdr->s_name, ".text") == 0) {
        !           113: 
        !           114:                        memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr,
        !           115:                               shdr->s_size);
        !           116:                        total_size += shdr->s_size;
        !           117: #ifdef CONFIG_PPC
        !           118:                        flush_icache_range((char*)(uintptr_t)shdr->s_vaddr,
        !           119:                                         (char*)(uintptr_t)(shdr->s_vaddr + shdr->s_size));
        !           120: #endif
        !           121:                } else if (strcmp(shdr->s_name, ".data") == 0) {
        !           122: 
        !           123:                        memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr,
        !           124:                               shdr->s_size);
        !           125:                        total_size += shdr->s_size;
        !           126: 
        !           127:                } else if (strcmp(shdr->s_name, ".bss") == 0) {
        !           128: 
        !           129:                        memset((void *)(uintptr_t)shdr->s_vaddr, 0, shdr->s_size);
        !           130:                        total_size += shdr->s_size;
        !           131:                } else {
        !           132:                        DPRINTF("    Skip '%s' section\n", shdr->s_name);
        !           133:                }
        !           134:                offset += sizeof(COFF_scnhdr_t);
        !           135:        }
        !           136: 
        !           137:        DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry);
        !           138: 
        !           139:        // Initialise saved-program-state
        !           140:        PUSH(*(uint32_t*)(uintptr_t)ahdr->entry);
        !           141:        feval("saved-program-state >sps.entry !");
        !           142:        PUSH(total_size);
        !           143:        feval("saved-program-state >sps.file-size !");
        !           144:        feval("xcoff saved-program-state >sps.file-type !");
        !           145: 
        !           146:        feval("-1 state-valid !");
        !           147: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.