load.c 3.3 KB

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