1 /* memory.c -- Memory accessor functions for the AArch64 simulator
3 Copyright (C) 2015-2016 Free Software Foundation, Inc.
5 Contributed by Red Hat.
7 This file is part of GDB.
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.
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.
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/>. */
23 #include <sys/types.h>
30 #include "libiberty.h"
31 #include "elf/internal.h"
32 #include "elf/common.h"
35 #include "simulator.h"
40 mem_error (sim_cpu
*cpu
, const char *message
, uint64_t addr
)
43 sim_io_eprintf (CPU_STATE (cpu
), "\n");
44 TRACE_MEMORY (cpu
, "ERROR: %s: %" PRIx64
, message
, addr
);
47 #define FETCH_FUNC(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
49 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
51 return (RETURN_TYPE) sim_core_read_##N (cpu, 0, read_map, address); \
54 /* A variant of the FETCH_FUNC macro that uses unaligned reads.
55 The AArch64 only requires 4-byte alignment for 8-byte quantities
56 but the sim common core does not support this. */
57 #define FETCH_FUNC_U(RETURN_TYPE, ACCESS_TYPE, NAME) \
59 aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
61 return (RETURN_TYPE) sim_core_read_unaligned_8 (cpu, 0, read_map, address); \
64 FETCH_FUNC_U (uint64_t, uint64_t, u64
)
65 FETCH_FUNC_U (int64_t, int64_t, s64
)
66 FETCH_FUNC (uint32_t, uint32_t, u32
, 4)
67 FETCH_FUNC (int32_t, int32_t, s32
, 4)
68 FETCH_FUNC (uint32_t, uint16_t, u16
, 2)
69 FETCH_FUNC (int32_t, int16_t, s16
, 2)
70 FETCH_FUNC (uint32_t, uint8_t, u8
, 1)
71 FETCH_FUNC (int32_t, int8_t, s8
, 1)
72 FETCH_FUNC (float, float, float, 4)
73 FETCH_FUNC_U (double, double, double)
76 aarch64_get_mem_long_double (sim_cpu
*cpu
, uint64_t address
, FRegister
*a
)
78 a
->v
[0] = sim_core_read_unaligned_8 (cpu
, 0, read_map
, address
);
79 a
->v
[1] = sim_core_read_unaligned_8 (cpu
, 0, read_map
, address
+ 8);
82 #define STORE_FUNC(TYPE, NAME, N) \
84 aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
87 "write of %" PRIx64 " (%d bytes) to %" PRIx64, \
88 (uint64_t) value, N, address); \
90 sim_core_write_unaligned_##N (cpu, 0, write_map, address, value); \
93 /* A variant of the STORE_FUNC macro that uses unaligned writes.
94 The AArch64 only requires 4-byte alignment for 8-byte quantities
95 but the sim common core does not support this. */
96 #define STORE_FUNC_U(TYPE, NAME) \
98 aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
101 "write of %" PRIx64 " (8 bytes) to %" PRIx64, \
102 (uint64_t) value, address); \
104 sim_core_write_unaligned_8 (cpu, 0, write_map, address, value); \
107 STORE_FUNC_U (uint64_t, u64
)
108 STORE_FUNC_U (int64_t, s64
)
109 STORE_FUNC (uint32_t, u32
, 4)
110 STORE_FUNC (int32_t, s32
, 4)
111 STORE_FUNC (uint16_t, u16
, 2)
112 STORE_FUNC (int16_t, s16
, 2)
113 STORE_FUNC (uint8_t, u8
, 1)
114 STORE_FUNC (int8_t, s8
, 1)
115 STORE_FUNC (float, float, 4)
116 STORE_FUNC_U (double, double)
119 aarch64_set_mem_long_double (sim_cpu
*cpu
, uint64_t address
, FRegister a
)
122 "write of long double %" PRIx64
" %" PRIx64
" to %" PRIx64
,
123 a
.v
[0], a
.v
[1], address
);
125 sim_core_write_unaligned_8 (cpu
, 0, write_map
, address
, a
.v
[0]);
126 sim_core_write_unaligned_8 (cpu
, 0, write_map
, address
+ 8, a
.v
[1]);
130 aarch64_get_mem_blk (sim_cpu
* cpu
,
137 len
= sim_core_read_buffer (CPU_STATE (cpu
), cpu
, read_map
,
138 buffer
, address
, length
);
142 memset (buffer
, 0, length
);
144 mem_error (cpu
, "read of non-existant mem block at", address
);
146 sim_engine_halt (CPU_STATE (cpu
), cpu
, NULL
, aarch64_get_PC (cpu
),
147 sim_stopped
, SIM_SIGBUS
);
151 aarch64_get_mem_ptr (sim_cpu
*cpu
, uint64_t address
)
153 char *addr
= sim_core_trans_addr (CPU_STATE (cpu
), cpu
, read_map
, address
);
157 mem_error (cpu
, "request for non-existant mem addr of", address
);
158 sim_engine_halt (CPU_STATE (cpu
), cpu
, NULL
, aarch64_get_PC (cpu
),
159 sim_stopped
, SIM_SIGBUS
);
165 /* We implement a combined stack and heap. That way the sbrk()
166 function in libgloss/aarch64/syscalls.c has a chance to detect
167 an out-of-memory condition by noticing a stack/heap collision.
169 The heap starts at the end of loaded memory and carries on up
170 to an arbitary 2Gb limit. */
173 aarch64_get_heap_start (sim_cpu
*cpu
)
175 uint64_t heap
= aarch64_get_sym_value ("end");
178 heap
= aarch64_get_sym_value ("_end");
181 heap
= STACK_TOP
- 0x100000;
182 sim_io_eprintf (CPU_STATE (cpu
),
183 "Unable to find 'end' symbol - using addr based "
184 "upon stack instead %" PRIx64
"\n",
191 aarch64_get_stack_start (sim_cpu
*cpu
)
193 if (aarch64_get_heap_start (cpu
) >= STACK_TOP
)
194 mem_error (cpu
, "executable is too big", aarch64_get_heap_start (cpu
));
This page took 0.032658 seconds and 4 git commands to generate.