1bb16d227Schristos /* load.c --- loading object files into the M32C simulator. 2bb16d227Schristos 3*8b657b07Schristos Copyright (C) 2005-2023 Free Software Foundation, Inc. 4bb16d227Schristos Contributed by Red Hat, Inc. 5bb16d227Schristos 6bb16d227Schristos This file is part of the GNU simulators. 7bb16d227Schristos 8bb16d227Schristos This program is free software; you can redistribute it and/or modify 9bb16d227Schristos it under the terms of the GNU General Public License as published by 10bb16d227Schristos the Free Software Foundation; either version 3 of the License, or 11bb16d227Schristos (at your option) any later version. 12bb16d227Schristos 13bb16d227Schristos This program is distributed in the hope that it will be useful, 14bb16d227Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15bb16d227Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16bb16d227Schristos GNU General Public License for more details. 17bb16d227Schristos 18bb16d227Schristos You should have received a copy of the GNU General Public License 19bb16d227Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20bb16d227Schristos 21*8b657b07Schristos /* This must come before any other includes. */ 22*8b657b07Schristos #include "defs.h" 23*8b657b07Schristos 24bb16d227Schristos #include <stdlib.h> 25bb16d227Schristos #include <stdio.h> 26bb16d227Schristos #include <string.h> 27bb16d227Schristos 28bb16d227Schristos #include "bfd.h" 29bb16d227Schristos 30bb16d227Schristos #include "cpu.h" 31bb16d227Schristos #include "mem.h" 32bb16d227Schristos #include "load.h" 33bb16d227Schristos 34bb16d227Schristos int (*decode_opcode) (void) = 0; 35bb16d227Schristos int default_machine = 0; 36bb16d227Schristos 37bb16d227Schristos void 38bb16d227Schristos m32c_set_mach (unsigned long mach) 39bb16d227Schristos { 40bb16d227Schristos switch (mach) 41bb16d227Schristos { 42bb16d227Schristos case bfd_mach_m16c: 43bb16d227Schristos m32c_set_cpu (CPU_M16C); 44bb16d227Schristos if (verbose) 45bb16d227Schristos fprintf (stderr, "[cpu: r8c/m16c]\n"); 46bb16d227Schristos break; 47bb16d227Schristos case bfd_mach_m32c: 48bb16d227Schristos m32c_set_cpu (CPU_M32C); 49bb16d227Schristos if (verbose) 50bb16d227Schristos fprintf (stderr, "[cpu: m32cm/m32c]\n"); 51bb16d227Schristos break; 52bb16d227Schristos default: 53bb16d227Schristos fprintf (stderr, "unknown m32c machine type 0x%lx\n", mach); 54bb16d227Schristos decode_opcode = 0; 55bb16d227Schristos break; 56bb16d227Schristos } 57bb16d227Schristos } 58bb16d227Schristos 59bb16d227Schristos void 60bb16d227Schristos m32c_load (bfd * prog) 61bb16d227Schristos { 62bb16d227Schristos asection *s; 63bb16d227Schristos unsigned long mach = bfd_get_mach (prog); 64bb16d227Schristos unsigned long highest_addr_loaded = 0; 65bb16d227Schristos 66bb16d227Schristos if (mach == 0 && default_machine != 0) 67bb16d227Schristos mach = default_machine; 68bb16d227Schristos 69bb16d227Schristos m32c_set_mach (mach); 70bb16d227Schristos 71bb16d227Schristos for (s = prog->sections; s; s = s->next) 72bb16d227Schristos { 73bb16d227Schristos #if 0 74bb16d227Schristos /* This was a good idea until we started storing the RAM data in 75bb16d227Schristos ROM, at which point everything was all messed up. The code 76bb16d227Schristos remains as a reminder. */ 77bb16d227Schristos if ((s->flags & SEC_ALLOC) && !(s->flags & SEC_READONLY)) 78bb16d227Schristos { 7982650ea5Schristos if (strcmp (bfd_section_name (s), ".stack")) 80bb16d227Schristos { 81bb16d227Schristos int secend = 8282650ea5Schristos bfd_section_size (s) + bfd_section_lma (s); 8382650ea5Schristos if (heaptop < secend && bfd_section_lma (s) < 0x10000) 84bb16d227Schristos { 85bb16d227Schristos heaptop = heapbottom = secend; 86bb16d227Schristos } 87bb16d227Schristos } 88bb16d227Schristos } 89bb16d227Schristos #endif 90bb16d227Schristos if (s->flags & SEC_LOAD) 91bb16d227Schristos { 92bb16d227Schristos char *buf; 93bb16d227Schristos bfd_size_type size; 94bb16d227Schristos bfd_vma base; 95bb16d227Schristos 9682650ea5Schristos size = bfd_section_size (s); 97bb16d227Schristos if (size <= 0) 98bb16d227Schristos continue; 99bb16d227Schristos 10082650ea5Schristos base = bfd_section_lma (s); 101bb16d227Schristos if (verbose) 102*8b657b07Schristos fprintf (stderr, "[load a=%08" PRIx64 " s=%08x %s]\n", 103*8b657b07Schristos (uint64_t) base, (int) size, bfd_section_name (s)); 104bb16d227Schristos buf = (char *) malloc (size); 105bb16d227Schristos bfd_get_section_contents (prog, s, buf, 0, size); 106bb16d227Schristos mem_put_blk (base, buf, size); 107bb16d227Schristos free (buf); 108bb16d227Schristos if (highest_addr_loaded < base + size - 1 && size >= 4) 109bb16d227Schristos highest_addr_loaded = base + size - 1; 110bb16d227Schristos } 111bb16d227Schristos } 112bb16d227Schristos 113bb16d227Schristos if (strcmp (bfd_get_target (prog), "srec") == 0) 114bb16d227Schristos { 115bb16d227Schristos heaptop = heapbottom = 0; 116bb16d227Schristos switch (mach) 117bb16d227Schristos { 118bb16d227Schristos case bfd_mach_m16c: 119bb16d227Schristos if (highest_addr_loaded > 0x10000) 120bb16d227Schristos regs.r_pc = mem_get_si (0x000ffffc) & membus_mask; 121bb16d227Schristos else 122bb16d227Schristos regs.r_pc = mem_get_si (0x000fffc) & membus_mask; 123bb16d227Schristos break; 124bb16d227Schristos case bfd_mach_m32c: 125bb16d227Schristos regs.r_pc = mem_get_si (0x00fffffc) & membus_mask; 126bb16d227Schristos break; 127bb16d227Schristos } 128bb16d227Schristos } 129bb16d227Schristos else 130bb16d227Schristos regs.r_pc = prog->start_address; 131bb16d227Schristos if (verbose) 132bb16d227Schristos fprintf (stderr, "[start pc=%08x]\n", (unsigned int) regs.r_pc); 133bb16d227Schristos } 134