|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.