1/* VM library: macros to be optionally included in architecture-specific asm. 2 3 Copyright (C) 2017, 2019 Luca Saiu 4 Updated in 2020 by Luca Saiu 5 Written by Luca Saiu 6 7 This file is part of Jitter. 8 9 Jitter 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 Jitter 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 Jitter. If not, see <http://www.gnu.org/licenses/>. */ 21 22 23/* This is an assembly file independent from the architecture, containing Gas 24 macros to be optionally used (by CPP inclusion) in the architecture-specific 25 file machine/ARCHITECTURE/jitter/machine/jitter-machine-assembly.S . 26 27 The macros defined here are meant to be called from the .text section. 28 29 This file contains macro definitions only, and by itself generates nothing 30 except possibly possibly a .note.GNU-stack section. 31 Because of this this file is also safe to include as a source in Makefile.am 32 , so that make can automatically discover dependencies. */ 33 34#ifndef MACHINE_COMMON_S_ 35#define MACHINE_COMMON_S_ 36 37 38/* Include feature macros. 39 * ************************************************************************** */ 40 41/* The code from this header defines macros but expands to nothing except 42 possibly a .note.GNU-stack section, so it is safe to include from assembly 43 as well. */ 44#include <jitter/jitter-config.h> 45 46/* We use CPP token concatenation here. The header contains CPP macro 47 definitions only, and is safe to use from assembly. */ 48#include <jitter/jitter-cpp.h> 49 50 51/* Expand to nothing if we have no assembly support. 52 * ************************************************************************** */ 53 54/* If in this configuration the assembler is not Gas or we do not know its 55 syntax or either configure or the user has decided to disable assembly 56 support, for any reason, expand the rest of this file to whitespace only. */ 57 58#if defined (JITTER_HAVE_ASSEMBLY) && defined (JITTER_HAVE_KNOWN_BINARY_FORMAT) 59 60/* If we arrived here we can acually use assembly. */ 61 62 63 64 65/* Global GNU Assembler settings and definitions. 66 * ************************************************************************** */ 67 68/* I like the & separator and <> quoting. */ 69.altmacro 70 71 72 73 74/* Machine dependencies. 75 * ************************************************************************** */ 76 77/* FIXME: factor with jitter.h . */ 78#if JITTER_SIZEOF_VOID_P == 8 79# define jitter_asm_word .quad 80#elif JITTER_SIZEOF_VOID_P == 4 81# define jitter_asm_word .long 82#elif JITTER_SIZEOF_VOID_P == 2 83# define jitter_asm_word .word 84# warning "Weird: running Jitter on a 16-bit machine; this is untested." 85#else 86# error "Weird: this machine's word size is not 8, 4 or 2 bytes" 87#endif // #if JITTER_SIZEOF_VOID_P == ... 88 89 90 91 92/* Stack executability not required. 93 * ************************************************************************** */ 94 95/* Do not require an executable stack. Jitter, or a Jittery VM runtime, never 96 directly relies on that. 97 98 Rationale: none of my assembly code relies on executable stacks, even if GCC 99 assumes, by default, that an assembly source file does. Since this file is 100 included in every assembly source this is a good place to put this. If some 101 other source linked to the Jitter runtime requires an executable stack then 102 the linked executable will have it, thanks to another 103 .section .note.GNU-stack, "x", @progbits 104 written somewhere else. 105 The Jitter runtime itself, along with every example in the distribution, 106 could easily be compiled and linked with 107 -Wa,--noexecstack -Wl,-z,noexecstack 108 , if there were nothing else. */ 109#if defined (JITTER_HOST_OS_IS_ELF) \ 110 && defined (JITTER_HAVE_SECTION_NOTE_GNU_STACK) 111.section .note.GNU-stack, "", @progbits 112.previous 113#endif // defined (JITTER_HOST_OS_IS_ELF) && ... 114 115 116 117 118/* Switching sections. 119 * ************************************************************************** */ 120 121/* The macros defined in the rest of this file are called from a .text section. 122 123 This assumption is important on weak binary formats for which the GNU 124 Assembler does not support a section stack; when done with emitting output 125 for a non-default section we can return to the previous stream with .text 126 instead of a non-portable directive such as .popsection . The full power of 127 a subsection stack is not used here. 128 129 These definitions should be simple and general enough to work on any platform 130 where Gas works, with no conditionalization. */ 131 132/* Enter the given subsection in the named section (initial dot included). */ 133.macro jitter_asm_enter_section section, subsection 134 \section \subsection 135.endm 136 137/* Exit the current subsection and change to .text. */ 138.macro jitter_asm_exit_section 139 .text 140.endm 141 142 143 144 145/* Global definitions. 146 * ************************************************************************** */ 147 148/* The definitions here are format-specific. I know of no general way of 149 emitting global definitions working on every format. */ 150 151/* Here the defined global may require an "_" prefix, 152 .def .. .endef , and no .type . 153 About the word size kludge, it may not be very portable. Still, the only 154 widely used COFF systems are supported this way, and even this effort is 155 more than those systems deserve. 156 FIXME: possibly factor with jitter/jitter-sections.h . */ 157#if JITTER_SIZEOF_VOID_P == 8 158# define JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(identifier) \ 159 identifier 160#else 161# define JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(identifier) \ 162 JITTER_CONCATENATE_TWO(_, identifier) 163#endif // word size 164 165 166/* Open the definition of a global with the given name, without changing 167 section. Generate a label with the given name. */ 168.macro jitter_global_begin name 169#if defined (JITTER_HOST_OS_IS_ELF) 170 .balign 16 171 .globl \name 172 .type \name, STT_OBJECT 173\name: 174#elif defined (JITTER_HOST_OS_IS_COFF) 175 .balign 16 176 .globl \name 177 .def JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(\name); .scl 2; .type 32; 178 .endef 179JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(\name): 180#else 181# error "unsupported binary format: this configuration should not use assembly" 182#endif // binary format conditional 183.endm 184 185/* Close the definition of a global with the given name, without changing 186 section. */ 187.macro jitter_global_end name 188#if defined (JITTER_HOST_OS_IS_ELF) 189 /* Nothing needed. */ 190#elif defined (JITTER_HOST_OS_IS_COFF) 191 /* Nothing needed. */ 192#else 193# error "unsupported binary format: this configuration should not use assembly" 194#endif // binary format conditional 195.endm 196 197 198 199 200/* Arrays. 201 * ************************************************************************** */ 202 203/* Declare the jitter_native_snippet_sizes symbol in the .data subsection 1, 204 the jitter_native_snippet_pointers symbol in the .data subsection 2 and the 205 jitter_native_snippet_names symbol in the .data subsection 3 (also using the 206 .data subsection 4 to store internal data); by using the Gas macro 207 jitter_snippet the subsections will be filled, respectively, with word-sized 208 (in the Jitter sense) elements holding the size of each snippet and with 209 word-sized elements (again in the Jitter sense) holding pointers to the 210 beginning of each snippet, and with pointers (again Jitter-word-sized) to 211 snippet names as strings. 212 Every array element is added in the order of jitter_snippet calls. The three 213 symbols will be visible from C as objects of type const jitter_uint [], 214 const char * const [] and const char* const [], which will be convenient 215 for implementing jitter_snippet_size, jitter_snippet_code and jitter_snippet_name . 216 The three arrays are meant to be indexed with enum jitter_snippet_to_patch 217 objects, whose cases must follow the same order as the jitter_native calls 218 here. */ 219.macro jitter_arrays 220/* Define the array jitter_native_snippet_sizes in .data subsection 1 , making it 221 visible from C. */ 222jitter_asm_enter_section .data, 1 223 jitter_global_begin jitter_native_snippet_sizes 224jitter_asm_exit_section 225/* Define the array jitter_native_snippet_pointers in .data subsection 2 , making 226 it visible from C. */ 227jitter_asm_enter_section .data, 2 228 jitter_global_begin jitter_native_snippet_pointers 229jitter_asm_exit_section 230/* Define the array jitter_native_snippet_names in .data subsection 3 , making it 231 visible from C. */ 232jitter_asm_enter_section .data, 3 233 jitter_global_begin jitter_native_snippet_names 234jitter_asm_exit_section 235.endm 236 237/* A simple Gas macro emitting the given label with the prefix "jitter_native_", 238 followed by up to twenty instructions (or generically "lines"), plus 239 a Jitter-word-sized datum with the same name as the function followed by 240 "_size" holding the snippet size in bytes. */ 241.macro jitter_snippet snippet_name, \ 242 insn1, insn2=<>, insn3=<>, insn4=<>, insn5=<>, insn6=<>, \ 243 insn7=<>, insn8=<>, insn9=<>, insn10=<>, insn11=<>, insn12=<>, \ 244 insn13=<>, insn14=<>, insn15=<>, insn16=<>, insn17=<>, \ 245 insn18=<>, insn19=<>, insn20=<> 246/* Emit the snippet in the current section. Use an alignment sufficient for 247 all architectures; Gas refuses to emit misaligned instructions on some 248 platforms. */ 249 .balign 16 250jitter_native_&\snippet_name&: 251 \insn1 252 \insn2 253 \insn3 254 \insn4 255 \insn5 256 \insn6 257 \insn7 258 \insn8 259 \insn9 260 \insn10 261 \insn11 262 \insn12 263 \insn13 264 \insn14 265 \insn15 266 \insn16 267 \insn17 268 \insn18 269 \insn19 270 \insn20 271jitter_native_&\snippet_name&_end: 272/* Add a word-sized datum containing the procedure size in .data subsection 1 ; 273 it will be one element of jitter_native_snippet_sizes . */ 274jitter_asm_enter_section .data, 1 275 jitter_asm_word (jitter_native_&\snippet_name&_end - jitter_native_&\snippet_name&) 276jitter_asm_exit_section 277/* Add a datum containing a pointer to the snippet beginning in .data 278 subsection 2 . */ 279jitter_asm_enter_section .data, 2 280 jitter_asm_word jitter_native_&\snippet_name 281jitter_asm_exit_section 282/* Add a datum containing the procedure name in .data subsection 4 . */ 283jitter_asm_enter_section .data, 4 284 jitter_native_&\snippet_name&_name: 285 .ascii "\snippet_name" 286 .byte 0x0 287jitter_asm_exit_section 288/* Add a datum containing a pointer to the the procedure name in .data 289 subsection 3 . */ 290jitter_asm_enter_section .data, 3 291 jitter_asm_word jitter_native_&\snippet_name&_name 292jitter_asm_exit_section 293.endm 294 295#endif // #if defined (JITTER_HAVE_ASSEMBLY) && defined (JITTER_HAVE_KNOWN_BINARY_FORMAT) 296 297#endif // #ifndef MACHINE_COMMON_S_ 298