Annotation of qemu/roms/openbios/libopenbios/xcoff_load.c, revision 1.1.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.