/*********************************************************************** * tools/nxflat/dyncall_skeleton_arm.def * * SPDX-License-Identifier: Apache-2.0 * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ***********************************************************************/ /******************************************************************* * File Prologue *******************************************************************/ static const char file_prologue[] = "/*******************************************************************\n" " *\n" " * This file contains the dynamic call logic that performs the thunk\n" " * for outound calls from one module to another.\n" " *\n" " * ARM register quick reference:\n" " *\n" " * Name Number ARM Procedure Calling Standard Role\n" " *\n" " * a1 r0 argument 1/integer result/scratch register/argc\n" " * a2 r1 argument 2/scratch register/argv\n" " * a3 r2 argument 3/scratch register/envp\n" " * a4 r3 argument 4/scratch register\n" " * v1 r4 register variable\n" " * v2 r5 register variable\n" " * v3 r6 register variable\n" " * v4 r7 register variable\n" " * v5 r8 register variable\n" " * sb/v6 r9 static base/register variable\n" " * sl/v7 r10 stack limit/stack chunk handle/reg. variable\n" " * fp r11 frame pointer\n" " * ip r12 scratch register/new-sb in inter-link-unit calls\n" " * sp r13 lower end of current stack frame\n" " * lr r14 link address/scratch register\n" " * pc r15 program counter\n" " *******************************************************************/\n\n" "/*******************************************************************\n" " * Included Files\n" " *******************************************************************/\n\n" "/*******************************************************************\n" " * Definitions\n" " *******************************************************************/\n\n" "/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */\n" "#ifndef __ARM_ARCH\n" "# ifdef __ARM_ARCH_2__\n" "# define __ARM_ARCH 2\n" "# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)\n" "# define __ARM_ARCH 3\n" "# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)\n" "# define __ARM_ARCH 4\n" "# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \\\n" " || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \\\n" " || defined(__ARM_ARCH_5TEJ__)\n" "# define __ARM_ARCH 5\n" "# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \\\n" " || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \\\n" " || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)\n" "# define __ARM_ARCH 6\n" "# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \\\n" " || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \\\n" " || defined(__ARM_ARCH_7EM__)\n" "# define __ARM_ARCH 7\n" "# else\n" "# error unknown arm architecture\n" "# endif\n" "#endif\n\n" "#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)\n" "# define ARCH_HAS_BX\n" "#endif\n" "#if __ARM_ARCH > 4\n" "# define ARCH_HAS_BLX\n" "#endif\n" "#if defined(ARCH_HAS_BX)\n" "#define BX(x) bx\t##x\n" "#else\n" "#define BX(x) mov\tpc, ##x\n" "#endif\n\n"; static const char import_prologue[] = ""; /******************************************************************* * Import Function Name String Table *******************************************************************/ static const char import_name_strtab_prologue[] = "\n/*******************************************************************\n" " * Import Function Names\n" " *******************************************************************/\n\n" "/* These are the names of all of the functions that are imported.\n" " * Notice that all data associated with the library names is retained\n" " * in the .text section." " */\n\n" "\t.text\n" "\t.align\t0\n"; #define MKIMPSTRTABARG(fn,i) (i), (i), (i), (fn), (i), (i) static const char import_name_strtab_format[] = "\n\t.local\t__dynimport%04d\n" "\t.type\t__dynimport%04d, object\n\n" "__dynimport%04d:\n" "\t.asciz\t\"%s\"\n" "\t.size\t__dynimport%04d, .-__dynimport%04d\n"; /******************************************************************* * Dynamic Call Information *******************************************************************/ static const char dynimport_decl_prologue[] = "\n/*******************************************************************\n" " * Imported Symbol Table (an array of type struct flat_import)\n" " *******************************************************************/\n\n" "/* Notice that, unlike most other arrays in this file, this array\n" " * is declared to reside in .data. Because of this, there will be\n" " * per-process instances of this table.\n" " */\n\n" "\t.data\n" "\t.align\t2\n\n" "\t.global\t__dynimport_begin\n" "\t.type\t__dynimport_begin, object\n" "\t.global\t__dynimport_end\n" "\t.type\t__dynimport_end, object\n\n"; #define MKINFODECLARGS(fn, i) (i), (fn), (i) static const char dynimport_decl_format[] = "\t.local\t__dyninfo%04d\t/* Dynamic info for imported symbol %s */\n" "\t.type\t__dyninfo%04d, object\n"; static const char dynimport_array_prologue[] = "\n__dynimport_begin:\n"; #define MKINFOARGS(fn, i) (i), (fn), (i), (i), (i) static const char dynimport_array_format[] = "__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n" "\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n" "\t.word\t0\t\t/* Resolved address of imported function */\n" "\t.size\t__dyninfo%04d, .-__dyninfo%04d\n"; static const char dynimport_array_epilogue[] = "__dynimport_end:\n" "\t.size\t__dynimport_begin, __dynimport_end-__dynimport_begin\n"; static const char dyncall_decl_prologue[] = "\n/*******************************************************************\n" " * Dynamic Call Logic\n" " *******************************************************************/\n\n" "\t.text\n" "\t.align\t2\n"; #define MKCALLARGS(fn, i) (fn), (fn), (fn), (fn), (i), (i), (i), (fn), (fn) #ifndef __NO_GOT__ static const char dyncall_format[] = "\n/* Dynamic call logic for imported symbol %s */\n\n" "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" "\tldr\tip,.Ldyn%04d\n" "\tadd\tip,ip," NXFLAT_PIC_REG "\n" "\tldr\tip,[ip,#4]\n" "\tBX(ip)\n" ".Ldyn%04d:\n" "\t.word\t__dyninfo%04d(GOTOFF)\n" "\t.size\t%s, .-%s\n"; static const char nonreturning_dyncall_format[] = "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n" "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" "\tldr\tip,.Ldyn%04d\n" "\tadd\tip,ip," NXFLAT_PIC_REG "\n" "\tldr\tip,[ip,#4]\n" "\tBX(ip)\n" ".Ldyn%04d:\n" "\t.word\t__dyninfo%04d(GOTOFF)\n" "\t.size\t%s, .-%s\n"; #else static const char dyncall_format[] = "\n/* Dynamic call logic for imported symbol %s */\n\n" "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" "\tldr\tip,.Ldyn%04d\n" "\tadd\tip,ip," NXFLAT_PIC_REG "\n" "\tldr\tip,[ip,#4]\n" "\tBX(ip)\n" ".Ldyn%04d:\n" "\t.word\t__dyninfo%04d\n" "\t.size\t%s, .-%s\n"; static const char nonreturning_dyncall_format[] = "\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n" "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" "\tldr\tip,.Ldyn%04d\n" "\tadd\tip,ip," NXFLAT_PIC_REG "\n" "\tldr\tip,[ip,#4]\n" "\tBX(ip)\n" ".Ldyn%04d:\n" "\t.word\t__dyninfo%04d\n" "\t.size\t%s, .-%s\n"; #endif /******************************************************************* * File Epilogue *******************************************************************/ static const char file_epilogue[] = "\t.end\n";