sim: drop redundant SIM_AC_OPTION_WARNINGS
[deliverable/binutils-gdb.git] / sim / aarch64 / memory.c
1 /* memory.c -- Memory accessor functions for the AArch64 simulator
2
3 Copyright (C) 2015-2021 Free Software Foundation, Inc.
4
5 Contributed by Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 /* This must come before any other includes. */
23 #include "defs.h"
24
25 #include <sys/types.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "libiberty.h"
31
32 #include "memory.h"
33 #include "simulator.h"
34
35 #include "sim-core.h"
36
37 static inline void
38 mem_error (sim_cpu *cpu, const char *message, uint64_t addr)
39 {
40 TRACE_MEMORY (cpu, "ERROR: %s: %" PRIx64, message, addr);
41 }
42
43 /* FIXME: AArch64 requires aligned memory access if SCTRLR_ELx.A is set,
44 but we are not implementing that here. */
45 #define FETCH_FUNC64(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
46 RETURN_TYPE \
47 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
48 { \
49 RETURN_TYPE val = (RETURN_TYPE) (ACCESS_TYPE) \
50 sim_core_read_unaligned_##N (cpu, 0, read_map, address); \
51 TRACE_MEMORY (cpu, "read of %" PRIx64 " (%d bytes) from %" PRIx64, \
52 val, N, address); \
53 \
54 return val; \
55 }
56
57 FETCH_FUNC64 (uint64_t, uint64_t, u64, 8)
58 FETCH_FUNC64 (int64_t, int64_t, s64, 8)
59
60 #define FETCH_FUNC32(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
61 RETURN_TYPE \
62 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
63 { \
64 RETURN_TYPE val = (RETURN_TYPE) (ACCESS_TYPE) \
65 sim_core_read_unaligned_##N (cpu, 0, read_map, address); \
66 TRACE_MEMORY (cpu, "read of %8x (%d bytes) from %" PRIx64, \
67 val, N, address); \
68 \
69 return val; \
70 }
71
72 FETCH_FUNC32 (uint32_t, uint32_t, u32, 4)
73 FETCH_FUNC32 (int32_t, int32_t, s32, 4)
74 FETCH_FUNC32 (uint32_t, uint16_t, u16, 2)
75 FETCH_FUNC32 (int32_t, int16_t, s16, 2)
76 FETCH_FUNC32 (uint32_t, uint8_t, u8, 1)
77 FETCH_FUNC32 (int32_t, int8_t, s8, 1)
78
79 void
80 aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a)
81 {
82 a->v[0] = sim_core_read_unaligned_8 (cpu, 0, read_map, address);
83 a->v[1] = sim_core_read_unaligned_8 (cpu, 0, read_map, address + 8);
84 }
85
86 /* FIXME: Aarch64 requires aligned memory access if SCTRLR_ELx.A is set,
87 but we are not implementing that here. */
88 #define STORE_FUNC(TYPE, NAME, N) \
89 void \
90 aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
91 { \
92 TRACE_MEMORY (cpu, \
93 "write of %" PRIx64 " (%d bytes) to %" PRIx64, \
94 (uint64_t) value, N, address); \
95 \
96 sim_core_write_unaligned_##N (cpu, 0, write_map, address, value); \
97 }
98
99 STORE_FUNC (uint64_t, u64, 8)
100 STORE_FUNC (int64_t, s64, 8)
101 STORE_FUNC (uint32_t, u32, 4)
102 STORE_FUNC (int32_t, s32, 4)
103 STORE_FUNC (uint16_t, u16, 2)
104 STORE_FUNC (int16_t, s16, 2)
105 STORE_FUNC (uint8_t, u8, 1)
106 STORE_FUNC (int8_t, s8, 1)
107
108 void
109 aarch64_set_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister a)
110 {
111 TRACE_MEMORY (cpu,
112 "write of long double %" PRIx64 " %" PRIx64 " to %" PRIx64,
113 a.v[0], a.v[1], address);
114
115 sim_core_write_unaligned_8 (cpu, 0, write_map, address, a.v[0]);
116 sim_core_write_unaligned_8 (cpu, 0, write_map, address + 8, a.v[1]);
117 }
118
119 void
120 aarch64_get_mem_blk (sim_cpu * cpu,
121 uint64_t address,
122 char * buffer,
123 unsigned length)
124 {
125 unsigned len;
126
127 len = sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map,
128 buffer, address, length);
129 if (len == length)
130 return;
131
132 memset (buffer, 0, length);
133 if (cpu)
134 mem_error (cpu, "read of non-existant mem block at", address);
135
136 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
137 sim_stopped, SIM_SIGBUS);
138 }
139
140 const char *
141 aarch64_get_mem_ptr (sim_cpu *cpu, uint64_t address)
142 {
143 char *addr = sim_core_trans_addr (CPU_STATE (cpu), cpu, read_map, address);
144
145 if (addr == NULL)
146 {
147 mem_error (cpu, "request for non-existant mem addr of", address);
148 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
149 sim_stopped, SIM_SIGBUS);
150 }
151
152 return addr;
153 }
154
155 /* We implement a combined stack and heap. That way the sbrk()
156 function in libgloss/aarch64/syscalls.c has a chance to detect
157 an out-of-memory condition by noticing a stack/heap collision.
158
159 The heap starts at the end of loaded memory and carries on up
160 to an arbitary 2Gb limit. */
161
162 uint64_t
163 aarch64_get_heap_start (sim_cpu *cpu)
164 {
165 uint64_t heap = trace_sym_value (CPU_STATE (cpu), "end");
166
167 if (heap == 0)
168 heap = trace_sym_value (CPU_STATE (cpu), "_end");
169 if (heap == 0)
170 {
171 heap = STACK_TOP - 0x100000;
172 sim_io_eprintf (CPU_STATE (cpu),
173 "Unable to find 'end' symbol - using addr based "
174 "upon stack instead %" PRIx64 "\n",
175 heap);
176 }
177 return heap;
178 }
179
180 uint64_t
181 aarch64_get_stack_start (sim_cpu *cpu)
182 {
183 if (aarch64_get_heap_start (cpu) >= STACK_TOP)
184 mem_error (cpu, "executable is too big", aarch64_get_heap_start (cpu));
185 return STACK_TOP;
186 }
This page took 0.041855 seconds and 4 git commands to generate.