load.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* load.c --- loading object files into the RL78 simulator.
  2. Copyright (C) 2005-2022 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. */
  16. /* This must come before any other includes. */
  17. #include "defs.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "libiberty.h"
  22. #include "bfd.h"
  23. #include "elf-bfd.h"
  24. #include "elf/rl78.h"
  25. #include "cpu.h"
  26. #include "mem.h"
  27. #include "load.h"
  28. #include "elf/internal.h"
  29. #include "elf/common.h"
  30. /* Helper function for invoking a GDB-specified printf. */
  31. static void
  32. xprintf (host_callback *callback, const char *fmt, ...)
  33. {
  34. va_list ap;
  35. va_start (ap, fmt);
  36. (*callback->vprintf_filtered) (callback, fmt, ap);
  37. va_end (ap);
  38. }
  39. /* Given a file offset, look up the section name. */
  40. static const char *
  41. find_section_name_by_offset (bfd *abfd, file_ptr filepos)
  42. {
  43. asection *s;
  44. for (s = abfd->sections; s; s = s->next)
  45. if (s->filepos == filepos)
  46. return bfd_section_name (s);
  47. return "(unknown)";
  48. }
  49. void
  50. rl78_load (bfd *prog, host_callback *callbacks, const char * const simname)
  51. {
  52. Elf_Internal_Phdr * phdrs;
  53. long sizeof_phdrs;
  54. int num_headers;
  55. int i;
  56. int max_rom = 0;
  57. init_cpu ();
  58. /* Note we load by ELF program header not by BFD sections.
  59. This is because BFD sections get their information from
  60. the ELF section structure, which only includes a VMA value
  61. and not an LMA value. */
  62. sizeof_phdrs = bfd_get_elf_phdr_upper_bound (prog);
  63. if (sizeof_phdrs == 0)
  64. {
  65. fprintf (stderr, "%s: Failed to get size of program headers\n", simname);
  66. return;
  67. }
  68. phdrs = xmalloc (sizeof_phdrs);
  69. num_headers = bfd_get_elf_phdrs (prog, phdrs);
  70. if (num_headers < 1)
  71. {
  72. fprintf (stderr, "%s: Failed to read program headers\n", simname);
  73. return;
  74. }
  75. switch (elf_elfheader (prog)->e_flags & E_FLAG_RL78_CPU_MASK)
  76. {
  77. case E_FLAG_RL78_G10:
  78. rl78_g10_mode = 1;
  79. g13_multiply = 0;
  80. g14_multiply = 0;
  81. mem_set_mirror (0, 0xf8000, 4096);
  82. break;
  83. case E_FLAG_RL78_G13:
  84. rl78_g10_mode = 0;
  85. g13_multiply = 1;
  86. g14_multiply = 0;
  87. break;
  88. case E_FLAG_RL78_G14:
  89. rl78_g10_mode = 0;
  90. g13_multiply = 0;
  91. g14_multiply = 1;
  92. break;
  93. default:
  94. /* Keep whatever was manually specified. */
  95. break;
  96. }
  97. for (i = 0; i < num_headers; i++)
  98. {
  99. Elf_Internal_Phdr * p = phdrs + i;
  100. char *buf;
  101. bfd_vma size;
  102. bfd_vma base;
  103. file_ptr offset;
  104. size = p->p_filesz;
  105. if (size <= 0)
  106. continue;
  107. base = p->p_paddr;
  108. if (verbose > 1)
  109. fprintf (stderr,
  110. "[load segment: lma=%08" BFD_VMA_FMT "x vma=%08x "
  111. "size=%08" BFD_VMA_FMT "x]\n",
  112. base, (int) p->p_vaddr, size);
  113. if (callbacks)
  114. xprintf (callbacks,
  115. "Loading section %s, size %#" BFD_VMA_FMT "x "
  116. "lma %08" BFD_VMA_FMT "x vma %08lx\n",
  117. find_section_name_by_offset (prog, p->p_offset),
  118. size, base, p->p_vaddr);
  119. buf = xmalloc (size);
  120. offset = p->p_offset;
  121. if (bfd_seek (prog, offset, SEEK_SET) != 0)
  122. {
  123. fprintf (stderr, "%s, Failed to seek to offset %lx\n", simname, (long) offset);
  124. continue;
  125. }
  126. if (bfd_bread (buf, size, prog) != size)
  127. {
  128. fprintf (stderr, "%s: Failed to read %" BFD_VMA_FMT "x bytes\n",
  129. simname, size);
  130. continue;
  131. }
  132. if (base > 0xeffff || base + size > 0xeffff)
  133. {
  134. fprintf (stderr,
  135. "%s, Can't load image to RAM/SFR space: 0x%" BFD_VMA_FMT "x "
  136. "- 0x%" BFD_VMA_FMT "x\n",
  137. simname, base, base+size);
  138. continue;
  139. }
  140. if (max_rom < base + size)
  141. max_rom = base + size;
  142. mem_put_blk (base, buf, size);
  143. free (buf);
  144. }
  145. free (phdrs);
  146. mem_rom_size (max_rom);
  147. pc = prog->start_address;
  148. if (strcmp (bfd_get_target (prog), "srec") == 0
  149. || pc == 0)
  150. {
  151. pc = mem_get_hi (0);
  152. }
  153. if (verbose > 1)
  154. fprintf (stderr, "[start pc=%08x]\n", (unsigned int) pc);
  155. }