]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/aarch64/memory.c
sim: split sim-signal.h include out
[thirdparty/binutils-gdb.git] / sim / aarch64 / memory.c
CommitLineData
2e8cf49e
NC
1/* memory.c -- Memory accessor functions for the AArch64 simulator
2
3666a048 3 Copyright (C) 2015-2021 Free Software Foundation, Inc.
2e8cf49e
NC
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
6df01ab8
MF
22/* This must come before any other includes. */
23#include "defs.h"
24
2e8cf49e
NC
25#include <sys/types.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
2e8cf49e 30#include "libiberty.h"
2e8cf49e
NC
31
32#include "memory.h"
33#include "simulator.h"
34
35#include "sim-core.h"
1fef66b0 36#include "sim-signal.h"
2e8cf49e
NC
37
38static inline void
39mem_error (sim_cpu *cpu, const char *message, uint64_t addr)
40{
2e8cf49e
NC
41 TRACE_MEMORY (cpu, "ERROR: %s: %" PRIx64, message, addr);
42}
43
7517e550 44/* FIXME: AArch64 requires aligned memory access if SCTRLR_ELx.A is set,
5ab6d79e 45 but we are not implementing that here. */
7517e550 46#define FETCH_FUNC64(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
2e8cf49e
NC
47 RETURN_TYPE \
48 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
49 { \
7517e550
NC
50 RETURN_TYPE val = (RETURN_TYPE) (ACCESS_TYPE) \
51 sim_core_read_unaligned_##N (cpu, 0, read_map, address); \
52 TRACE_MEMORY (cpu, "read of %" PRIx64 " (%d bytes) from %" PRIx64, \
53 val, N, address); \
54 \
55 return val; \
56 }
57
58FETCH_FUNC64 (uint64_t, uint64_t, u64, 8)
59FETCH_FUNC64 (int64_t, int64_t, s64, 8)
60
61#define FETCH_FUNC32(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
62 RETURN_TYPE \
63 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
64 { \
65 RETURN_TYPE val = (RETURN_TYPE) (ACCESS_TYPE) \
66 sim_core_read_unaligned_##N (cpu, 0, read_map, address); \
67 TRACE_MEMORY (cpu, "read of %8x (%d bytes) from %" PRIx64, \
68 val, N, address); \
e101a78b
NC
69 \
70 return val; \
2e8cf49e
NC
71 }
72
7517e550
NC
73FETCH_FUNC32 (uint32_t, uint32_t, u32, 4)
74FETCH_FUNC32 (int32_t, int32_t, s32, 4)
75FETCH_FUNC32 (uint32_t, uint16_t, u16, 2)
76FETCH_FUNC32 (int32_t, int16_t, s16, 2)
77FETCH_FUNC32 (uint32_t, uint8_t, u8, 1)
78FETCH_FUNC32 (int32_t, int8_t, s8, 1)
2e8cf49e
NC
79
80void
81aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a)
82{
83 a->v[0] = sim_core_read_unaligned_8 (cpu, 0, read_map, address);
84 a->v[1] = sim_core_read_unaligned_8 (cpu, 0, read_map, address + 8);
85}
86
5ab6d79e
NC
87/* FIXME: Aarch64 requires aligned memory access if SCTRLR_ELx.A is set,
88 but we are not implementing that here. */
2e8cf49e
NC
89#define STORE_FUNC(TYPE, NAME, N) \
90 void \
91 aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
92 { \
93 TRACE_MEMORY (cpu, \
94 "write of %" PRIx64 " (%d bytes) to %" PRIx64, \
95 (uint64_t) value, N, address); \
96 \
97 sim_core_write_unaligned_##N (cpu, 0, write_map, address, value); \
98 }
99
5ab6d79e
NC
100STORE_FUNC (uint64_t, u64, 8)
101STORE_FUNC (int64_t, s64, 8)
102STORE_FUNC (uint32_t, u32, 4)
103STORE_FUNC (int32_t, s32, 4)
104STORE_FUNC (uint16_t, u16, 2)
105STORE_FUNC (int16_t, s16, 2)
106STORE_FUNC (uint8_t, u8, 1)
107STORE_FUNC (int8_t, s8, 1)
2e8cf49e
NC
108
109void
110aarch64_set_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister a)
111{
112 TRACE_MEMORY (cpu,
113 "write of long double %" PRIx64 " %" PRIx64 " to %" PRIx64,
114 a.v[0], a.v[1], address);
115
116 sim_core_write_unaligned_8 (cpu, 0, write_map, address, a.v[0]);
117 sim_core_write_unaligned_8 (cpu, 0, write_map, address + 8, a.v[1]);
118}
119
120void
121aarch64_get_mem_blk (sim_cpu * cpu,
122 uint64_t address,
123 char * buffer,
124 unsigned length)
125{
126 unsigned len;
127
128 len = sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map,
129 buffer, address, length);
130 if (len == length)
131 return;
132
133 memset (buffer, 0, length);
134 if (cpu)
135 mem_error (cpu, "read of non-existant mem block at", address);
136
137 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
138 sim_stopped, SIM_SIGBUS);
139}
140
141const char *
142aarch64_get_mem_ptr (sim_cpu *cpu, uint64_t address)
143{
144 char *addr = sim_core_trans_addr (CPU_STATE (cpu), cpu, read_map, address);
145
146 if (addr == NULL)
147 {
148 mem_error (cpu, "request for non-existant mem addr of", address);
149 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),
150 sim_stopped, SIM_SIGBUS);
151 }
152
153 return addr;
154}
155
156/* We implement a combined stack and heap. That way the sbrk()
157 function in libgloss/aarch64/syscalls.c has a chance to detect
158 an out-of-memory condition by noticing a stack/heap collision.
159
160 The heap starts at the end of loaded memory and carries on up
161 to an arbitary 2Gb limit. */
162
163uint64_t
164aarch64_get_heap_start (sim_cpu *cpu)
165{
5357150c 166 uint64_t heap = trace_sym_value (CPU_STATE (cpu), "end");
2e8cf49e
NC
167
168 if (heap == 0)
5357150c 169 heap = trace_sym_value (CPU_STATE (cpu), "_end");
2e8cf49e
NC
170 if (heap == 0)
171 {
172 heap = STACK_TOP - 0x100000;
173 sim_io_eprintf (CPU_STATE (cpu),
174 "Unable to find 'end' symbol - using addr based "
175 "upon stack instead %" PRIx64 "\n",
176 heap);
177 }
178 return heap;
179}
180
181uint64_t
182aarch64_get_stack_start (sim_cpu *cpu)
183{
184 if (aarch64_get_heap_start (cpu) >= STACK_TOP)
185 mem_error (cpu, "executable is too big", aarch64_get_heap_start (cpu));
186 return STACK_TOP;
187}