15db71995Sopenharmony_ci/* 25db71995Sopenharmony_ci * Copyright (c) 2017-2021 The Khronos Group Inc. 35db71995Sopenharmony_ci * Copyright (c) 2017-2021 Valve Corporation 45db71995Sopenharmony_ci * Copyright (c) 2017-2021 LunarG, Inc. 55db71995Sopenharmony_ci * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 65db71995Sopenharmony_ci * 75db71995Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 85db71995Sopenharmony_ci * you may not use this file except in compliance with the License. 95db71995Sopenharmony_ci * You may obtain a copy of the License at 105db71995Sopenharmony_ci * 115db71995Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 125db71995Sopenharmony_ci * 135db71995Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 145db71995Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 155db71995Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 165db71995Sopenharmony_ci * See the License for the specific language governing permissions and 175db71995Sopenharmony_ci * limitations under the License. 185db71995Sopenharmony_ci * 195db71995Sopenharmony_ci * Author: Lenny Komow <lenny@lunarg.com> 205db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com> 215db71995Sopenharmony_ci */ 225db71995Sopenharmony_ci 235db71995Sopenharmony_ci// This code generates an assembly file which provides offsets to get struct members from assembly code. 245db71995Sopenharmony_ci 255db71995Sopenharmony_ci// __USE_MINGW_ANSI_STDIO is needed to use the %zu format specifier with mingw-w64. 265db71995Sopenharmony_ci// Otherwise the compiler will complain about an unknown format specifier. 275db71995Sopenharmony_ci#if defined(__MINGW32__) && !defined(__USE_MINGW_ANSI_STDIO) 285db71995Sopenharmony_ci#define __USE_MINGW_ANSI_STDIO 1 295db71995Sopenharmony_ci#endif 305db71995Sopenharmony_ci 315db71995Sopenharmony_ci#include <stdio.h> 325db71995Sopenharmony_ci#include "loader_common.h" 335db71995Sopenharmony_ci#include "log.h" 345db71995Sopenharmony_ci 355db71995Sopenharmony_ci#if defined(__GNUC__) || defined(__clang__) 365db71995Sopenharmony_civoid produce_asm_define() { 375db71995Sopenharmony_ci // GCC and clang make it easy to print easy to regex for values 385db71995Sopenharmony_ci __asm__("# VULKAN_LOADER_ERROR_BIT = %c0" : : "i"(VULKAN_LOADER_ERROR_BIT)); 395db71995Sopenharmony_ci __asm__("# PTR_SIZE = %c0" : : "i"(sizeof(void *))); 405db71995Sopenharmony_ci __asm__("# CHAR_PTR_SIZE = %c0" : : "i"(sizeof(char *))); 415db71995Sopenharmony_ci __asm__("# FUNCTION_OFFSET_INSTANCE = %c0" : : "i"(offsetof(struct loader_instance, phys_dev_ext_disp_functions))); 425db71995Sopenharmony_ci __asm__("# PHYS_DEV_OFFSET_INST_DISPATCH = %c0" : : "i"(offsetof(struct loader_instance_dispatch_table, phys_dev_ext))); 435db71995Sopenharmony_ci __asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = %c0" : : "i"(offsetof(struct loader_physical_device_tramp, phys_dev))); 445db71995Sopenharmony_ci __asm__("# ICD_TERM_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, this_icd_term))); 455db71995Sopenharmony_ci __asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, phys_dev))); 465db71995Sopenharmony_ci __asm__("# INSTANCE_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, this_instance))); 475db71995Sopenharmony_ci __asm__("# DISPATCH_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, phys_dev_ext))); 485db71995Sopenharmony_ci __asm__("# EXT_OFFSET_DEVICE_DISPATCH = %c0" : : "i"(offsetof(struct loader_dev_dispatch_table, ext_dispatch))); 495db71995Sopenharmony_ci} 505db71995Sopenharmony_ci#elif defined(_WIN32) 515db71995Sopenharmony_ci// MSVC will print the name of the value and the value in hex 525db71995Sopenharmony_ci// Must disable optimization for this translation unit, otherwise the compiler strips out the variables 535db71995Sopenharmony_cistatic const uint32_t PTR_SIZE = sizeof(void *); 545db71995Sopenharmony_cistatic const uint32_t CHAR_PTR_SIZE = sizeof(char *); 555db71995Sopenharmony_cistatic const uint32_t FUNCTION_OFFSET_INSTANCE = offsetof(struct loader_instance, phys_dev_ext_disp_functions); 565db71995Sopenharmony_cistatic const uint32_t PHYS_DEV_OFFSET_INST_DISPATCH = offsetof(struct loader_instance_dispatch_table, phys_dev_ext); 575db71995Sopenharmony_cistatic const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = offsetof(struct loader_physical_device_tramp, phys_dev); 585db71995Sopenharmony_cistatic const uint32_t ICD_TERM_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, this_icd_term); 595db71995Sopenharmony_cistatic const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, phys_dev); 605db71995Sopenharmony_cistatic const uint32_t INSTANCE_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, this_instance); 615db71995Sopenharmony_cistatic const uint32_t DISPATCH_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, phys_dev_ext); 625db71995Sopenharmony_cistatic const uint32_t EXT_OFFSET_DEVICE_DISPATCH = offsetof(struct loader_dev_dispatch_table, ext_dispatch); 635db71995Sopenharmony_ci#else 645db71995Sopenharmony_ci#warning asm_offset.c variable declarations need to be defined for this platform 655db71995Sopenharmony_ci#endif 665db71995Sopenharmony_ci 675db71995Sopenharmony_ci#if !defined(_MSC_VER) || (_MSC_VER >= 1900) 685db71995Sopenharmony_ci#define SIZE_T_FMT "%-8zu" 695db71995Sopenharmony_ci#elif defined(__GNUC__) || defined(__clang__) 705db71995Sopenharmony_ci#define SIZE_T_FMT "%-8lu" 715db71995Sopenharmony_ci#else 725db71995Sopenharmony_ci#warning asm_offset.c SIZE_T_FMT must be defined for this platform 735db71995Sopenharmony_ci#endif 745db71995Sopenharmony_ci 755db71995Sopenharmony_cistruct ValueInfo { 765db71995Sopenharmony_ci const char *name; 775db71995Sopenharmony_ci size_t value; 785db71995Sopenharmony_ci const char *comment; 795db71995Sopenharmony_ci}; 805db71995Sopenharmony_ci 815db71995Sopenharmony_ci// This file can both be executed to produce gen_defines.asm and contains all the relevant data which 825db71995Sopenharmony_ci// the parse_asm_values.py script needs to write gen_defines.asm, necessary for cross compilation 835db71995Sopenharmony_ciint main(int argc, char **argv) { 845db71995Sopenharmony_ci const char *assembler = NULL; 855db71995Sopenharmony_ci for (int i = 0; i < argc; ++i) { 865db71995Sopenharmony_ci if (!strcmp(argv[i], "MASM")) { 875db71995Sopenharmony_ci assembler = "MASM"; 885db71995Sopenharmony_ci } else if (!strcmp(argv[i], "GAS")) { 895db71995Sopenharmony_ci assembler = "GAS"; 905db71995Sopenharmony_ci } 915db71995Sopenharmony_ci } 925db71995Sopenharmony_ci if (assembler == NULL) { 935db71995Sopenharmony_ci return 1; 945db71995Sopenharmony_ci } 955db71995Sopenharmony_ci 965db71995Sopenharmony_ci struct ValueInfo values[] = { 975db71995Sopenharmony_ci // clang-format off 985db71995Sopenharmony_ci { .name = "VULKAN_LOADER_ERROR_BIT", .value = (size_t) VULKAN_LOADER_ERROR_BIT, 995db71995Sopenharmony_ci .comment = "The numerical value of the enum value 'VULKAN_LOADER_ERROR_BIT'" }, 1005db71995Sopenharmony_ci { .name = "PTR_SIZE", .value = sizeof(void*), 1015db71995Sopenharmony_ci .comment = "The size of a pointer" }, 1025db71995Sopenharmony_ci { .name = "CHAR_PTR_SIZE", .value = sizeof(char *), 1035db71995Sopenharmony_ci .comment = "The size of a 'const char *' struct" }, 1045db71995Sopenharmony_ci { .name = "FUNCTION_OFFSET_INSTANCE", .value = offsetof(struct loader_instance, phys_dev_ext_disp_functions), 1055db71995Sopenharmony_ci .comment = "The offset of 'phys_dev_ext_disp_functions' within a 'loader_instance' struct" }, 1065db71995Sopenharmony_ci { .name = "PHYS_DEV_OFFSET_INST_DISPATCH", .value = offsetof(struct loader_instance_dispatch_table, phys_dev_ext), 1075db71995Sopenharmony_ci .comment = "The offset of 'phys_dev_ext' within in 'loader_instance_dispatch_table' struct" }, 1085db71995Sopenharmony_ci { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TRAMP", .value = offsetof(struct loader_physical_device_tramp, phys_dev), 1095db71995Sopenharmony_ci .comment = "The offset of 'phys_dev' within a 'loader_physical_device_tramp' struct" }, 1105db71995Sopenharmony_ci { .name = "ICD_TERM_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, this_icd_term), 1115db71995Sopenharmony_ci .comment = "The offset of 'this_icd_term' within a 'loader_physical_device_term' struct" }, 1125db71995Sopenharmony_ci { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, phys_dev), 1135db71995Sopenharmony_ci .comment = "The offset of 'phys_dev' within a 'loader_physical_device_term' struct" }, 1145db71995Sopenharmony_ci { .name = "INSTANCE_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, this_instance), 1155db71995Sopenharmony_ci .comment = "The offset of 'this_instance' within a 'loader_icd_term' struct" }, 1165db71995Sopenharmony_ci { .name = "DISPATCH_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, phys_dev_ext), 1175db71995Sopenharmony_ci .comment = "The offset of 'phys_dev_ext' within a 'loader_icd_term' struct" }, 1185db71995Sopenharmony_ci { .name = "EXT_OFFSET_DEVICE_DISPATCH", .value = offsetof(struct loader_dev_dispatch_table, ext_dispatch), 1195db71995Sopenharmony_ci .comment = "The offset of 'ext_dispatch' within a 'loader_dev_dispatch_table' struct" }, 1205db71995Sopenharmony_ci // clang-format on 1215db71995Sopenharmony_ci }; 1225db71995Sopenharmony_ci 1235db71995Sopenharmony_ci FILE *file = loader_fopen("gen_defines.asm", "w"); 1245db71995Sopenharmony_ci fprintf(file, "\n"); 1255db71995Sopenharmony_ci if (!strcmp(assembler, "MASM")) { 1265db71995Sopenharmony_ci for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { 1275db71995Sopenharmony_ci fprintf(file, "%-32s equ " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment); 1285db71995Sopenharmony_ci } 1295db71995Sopenharmony_ci } else if (!strcmp(assembler, "GAS")) { 1305db71995Sopenharmony_ci#if defined(__x86_64__) || defined(__i386__) 1315db71995Sopenharmony_ci const char *comment_delimiter = "#"; 1325db71995Sopenharmony_ci#if defined(__x86_64__) 1335db71995Sopenharmony_ci fprintf(file, ".set X86_64, 1\n"); 1345db71995Sopenharmony_ci#endif // defined(__x86_64__) 1355db71995Sopenharmony_ci#elif defined(__aarch64__) 1365db71995Sopenharmony_ci const char *comment_delimiter = "//"; 1375db71995Sopenharmony_ci fprintf(file, ".set AARCH_64, 1\n"); 1385db71995Sopenharmony_ci#else 1395db71995Sopenharmony_ci // Default comment delimiter 1405db71995Sopenharmony_ci const char *comment_delimiter = "#"; 1415db71995Sopenharmony_ci#endif 1425db71995Sopenharmony_ci for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { 1435db71995Sopenharmony_ci fprintf(file, ".set %-32s, " SIZE_T_FMT "%s %s\n", values[i].name, values[i].value, comment_delimiter, 1445db71995Sopenharmony_ci values[i].comment); 1455db71995Sopenharmony_ci } 1465db71995Sopenharmony_ci } 1475db71995Sopenharmony_ci return fclose(file); 1485db71995Sopenharmony_ci} 149