登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
13
Star
20
Fork
177
src-openEuler
/
glibc
代码
Issues
11
Pull Requests
2
Wiki
统计
流水线
服务
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
memcpy,memmove优化代码
待办的
#ID29SB
任务
longwei
创建于
2025-10-16 20:09
使用说明: 将下面文件放在同一目录后执行make,会生成memcpy_sve.so 执行程序前将so加载 LD_PRELOAD=/PATH/TO/memcpy_sve.so ./test dwarf2.h: ``` /* Declarations and definitions of codes relating to the DWARF2 symbolic debugging information format. Copyright (C) 1992-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef _DWARF2_H #define _DWARF2_H 1 /* This file is derived from the DWARF specification (a public document) Revision 2.0.0 (July 27, 1993) developed by the UNIX International Programming Languages Special Interest Group (UI/PLSIG) and distributed by UNIX International. Copies of this specification are available from UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */ /* This file is shared between GCC and GDB, and should not contain prototypes. */ #ifndef __ASSEMBLER__ /* Tag names and codes. */ enum dwarf_tag { DW_TAG_padding = 0x00, DW_TAG_array_type = 0x01, DW_TAG_class_type = 0x02, DW_TAG_entry_point = 0x03, DW_TAG_enumeration_type = 0x04, DW_TAG_formal_parameter = 0x05, DW_TAG_imported_declaration = 0x08, DW_TAG_label = 0x0a, DW_TAG_lexical_block = 0x0b, DW_TAG_member = 0x0d, DW_TAG_pointer_type = 0x0f, DW_TAG_reference_type = 0x10, DW_TAG_compile_unit = 0x11, DW_TAG_string_type = 0x12, DW_TAG_structure_type = 0x13, DW_TAG_subroutine_type = 0x15, DW_TAG_typedef = 0x16, DW_TAG_union_type = 0x17, DW_TAG_unspecified_parameters = 0x18, DW_TAG_variant = 0x19, DW_TAG_common_block = 0x1a, DW_TAG_common_inclusion = 0x1b, DW_TAG_inheritance = 0x1c, DW_TAG_inlined_subroutine = 0x1d, DW_TAG_module = 0x1e, DW_TAG_ptr_to_member_type = 0x1f, DW_TAG_set_type = 0x20, DW_TAG_subrange_type = 0x21, DW_TAG_with_stmt = 0x22, DW_TAG_access_declaration = 0x23, DW_TAG_base_type = 0x24, DW_TAG_catch_block = 0x25, DW_TAG_const_type = 0x26, DW_TAG_constant = 0x27, DW_TAG_enumerator = 0x28, DW_TAG_file_type = 0x29, DW_TAG_friend = 0x2a, DW_TAG_namelist = 0x2b, DW_TAG_namelist_item = 0x2c, DW_TAG_packed_type = 0x2d, DW_TAG_subprogram = 0x2e, DW_TAG_template_type_param = 0x2f, DW_TAG_template_value_param = 0x30, DW_TAG_thrown_type = 0x31, DW_TAG_try_block = 0x32, DW_TAG_variant_part = 0x33, DW_TAG_variable = 0x34, DW_TAG_volatile_type = 0x35, /* SGI/MIPS Extensions */ DW_TAG_MIPS_loop = 0x4081, /* GNU extensions */ DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */ DW_TAG_function_template = 0x4102, /* for C++ */ DW_TAG_class_template = 0x4103, /* for C++ */ DW_TAG_GNU_BINCL = 0x4104, DW_TAG_GNU_EINCL = 0x4105 }; #define DW_TAG_lo_user 0x4080 #define DW_TAG_hi_user 0xffff /* flag that tells whether entry has a child or not */ #define DW_children_no 0 #define DW_children_yes 1 /* Form names and codes. */ enum dwarf_form { DW_FORM_addr = 0x01, DW_FORM_block2 = 0x03, DW_FORM_block4 = 0x04, DW_FORM_data2 = 0x05, DW_FORM_data4 = 0x06, DW_FORM_data8 = 0x07, DW_FORM_string = 0x08, DW_FORM_block = 0x09, DW_FORM_block1 = 0x0a, DW_FORM_data1 = 0x0b, DW_FORM_flag = 0x0c, DW_FORM_sdata = 0x0d, DW_FORM_strp = 0x0e, DW_FORM_udata = 0x0f, DW_FORM_ref_addr = 0x10, DW_FORM_ref1 = 0x11, DW_FORM_ref2 = 0x12, DW_FORM_ref4 = 0x13, DW_FORM_ref8 = 0x14, DW_FORM_ref_udata = 0x15, DW_FORM_indirect = 0x16 }; /* Attribute names and codes. */ enum dwarf_attribute { DW_AT_sibling = 0x01, DW_AT_location = 0x02, DW_AT_name = 0x03, DW_AT_ordering = 0x09, DW_AT_subscr_data = 0x0a, DW_AT_byte_size = 0x0b, DW_AT_bit_offset = 0x0c, DW_AT_bit_size = 0x0d, DW_AT_element_list = 0x0f, DW_AT_stmt_list = 0x10, DW_AT_low_pc = 0x11, DW_AT_high_pc = 0x12, DW_AT_language = 0x13, DW_AT_member = 0x14, DW_AT_discr = 0x15, DW_AT_discr_value = 0x16, DW_AT_visibility = 0x17, DW_AT_import = 0x18, DW_AT_string_length = 0x19, DW_AT_common_reference = 0x1a, DW_AT_comp_dir = 0x1b, DW_AT_const_value = 0x1c, DW_AT_containing_type = 0x1d, DW_AT_default_value = 0x1e, DW_AT_inline = 0x20, DW_AT_is_optional = 0x21, DW_AT_lower_bound = 0x22, DW_AT_producer = 0x25, DW_AT_prototyped = 0x27, DW_AT_return_addr = 0x2a, DW_AT_start_scope = 0x2c, DW_AT_stride_size = 0x2e, DW_AT_upper_bound = 0x2f, DW_AT_abstract_origin = 0x31, DW_AT_accessibility = 0x32, DW_AT_address_class = 0x33, DW_AT_artificial = 0x34, DW_AT_base_types = 0x35, DW_AT_calling_convention = 0x36, DW_AT_count = 0x37, DW_AT_data_member_location = 0x38, DW_AT_decl_column = 0x39, DW_AT_decl_file = 0x3a, DW_AT_decl_line = 0x3b, DW_AT_declaration = 0x3c, DW_AT_discr_list = 0x3d, DW_AT_encoding = 0x3e, DW_AT_external = 0x3f, DW_AT_frame_base = 0x40, DW_AT_friend = 0x41, DW_AT_identifier_case = 0x42, DW_AT_macro_info = 0x43, DW_AT_namelist_items = 0x44, DW_AT_priority = 0x45, DW_AT_segment = 0x46, DW_AT_specification = 0x47, DW_AT_static_link = 0x48, DW_AT_type = 0x49, DW_AT_use_location = 0x4a, DW_AT_variable_parameter = 0x4b, DW_AT_virtuality = 0x4c, DW_AT_vtable_elem_location = 0x4d, /* SGI/MIPS Extensions */ DW_AT_MIPS_fde = 0x2001, DW_AT_MIPS_loop_begin = 0x2002, DW_AT_MIPS_tail_loop_begin = 0x2003, DW_AT_MIPS_epilog_begin = 0x2004, DW_AT_MIPS_loop_unroll_factor = 0x2005, DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, DW_AT_MIPS_stride = 0x2008, DW_AT_MIPS_abstract_name = 0x2009, DW_AT_MIPS_clone_origin = 0x200a, DW_AT_MIPS_has_inlines = 0x200b, /* GNU extensions. */ DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106 }; #define DW_AT_lo_user 0x2000 /* implementation-defined range start */ #define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */ /* Location atom names and codes. */ enum dwarf_location_atom { DW_OP_addr = 0x03, DW_OP_deref = 0x06, DW_OP_const1u = 0x08, DW_OP_const1s = 0x09, DW_OP_const2u = 0x0a, DW_OP_const2s = 0x0b, DW_OP_const4u = 0x0c, DW_OP_const4s = 0x0d, DW_OP_const8u = 0x0e, DW_OP_const8s = 0x0f, DW_OP_constu = 0x10, DW_OP_consts = 0x11, DW_OP_dup = 0x12, DW_OP_drop = 0x13, DW_OP_over = 0x14, DW_OP_pick = 0x15, DW_OP_swap = 0x16, DW_OP_rot = 0x17, DW_OP_xderef = 0x18, DW_OP_abs = 0x19, DW_OP_and = 0x1a, DW_OP_div = 0x1b, DW_OP_minus = 0x1c, DW_OP_mod = 0x1d, DW_OP_mul = 0x1e, DW_OP_neg = 0x1f, DW_OP_not = 0x20, DW_OP_or = 0x21, DW_OP_plus = 0x22, DW_OP_plus_uconst = 0x23, DW_OP_shl = 0x24, DW_OP_shr = 0x25, DW_OP_shra = 0x26, DW_OP_xor = 0x27, DW_OP_bra = 0x28, DW_OP_eq = 0x29, DW_OP_ge = 0x2a, DW_OP_gt = 0x2b, DW_OP_le = 0x2c, DW_OP_lt = 0x2d, DW_OP_ne = 0x2e, DW_OP_skip = 0x2f, DW_OP_lit0 = 0x30, DW_OP_lit1 = 0x31, DW_OP_lit2 = 0x32, DW_OP_lit3 = 0x33, DW_OP_lit4 = 0x34, DW_OP_lit5 = 0x35, DW_OP_lit6 = 0x36, DW_OP_lit7 = 0x37, DW_OP_lit8 = 0x38, DW_OP_lit9 = 0x39, DW_OP_lit10 = 0x3a, DW_OP_lit11 = 0x3b, DW_OP_lit12 = 0x3c, DW_OP_lit13 = 0x3d, DW_OP_lit14 = 0x3e, DW_OP_lit15 = 0x3f, DW_OP_lit16 = 0x40, DW_OP_lit17 = 0x41, DW_OP_lit18 = 0x42, DW_OP_lit19 = 0x43, DW_OP_lit20 = 0x44, DW_OP_lit21 = 0x45, DW_OP_lit22 = 0x46, DW_OP_lit23 = 0x47, DW_OP_lit24 = 0x48, DW_OP_lit25 = 0x49, DW_OP_lit26 = 0x4a, DW_OP_lit27 = 0x4b, DW_OP_lit28 = 0x4c, DW_OP_lit29 = 0x4d, DW_OP_lit30 = 0x4e, DW_OP_lit31 = 0x4f, DW_OP_reg0 = 0x50, DW_OP_reg1 = 0x51, DW_OP_reg2 = 0x52, DW_OP_reg3 = 0x53, DW_OP_reg4 = 0x54, DW_OP_reg5 = 0x55, DW_OP_reg6 = 0x56, DW_OP_reg7 = 0x57, DW_OP_reg8 = 0x58, DW_OP_reg9 = 0x59, DW_OP_reg10 = 0x5a, DW_OP_reg11 = 0x5b, DW_OP_reg12 = 0x5c, DW_OP_reg13 = 0x5d, DW_OP_reg14 = 0x5e, DW_OP_reg15 = 0x5f, DW_OP_reg16 = 0x60, DW_OP_reg17 = 0x61, DW_OP_reg18 = 0x62, DW_OP_reg19 = 0x63, DW_OP_reg20 = 0x64, DW_OP_reg21 = 0x65, DW_OP_reg22 = 0x66, DW_OP_reg23 = 0x67, DW_OP_reg24 = 0x68, DW_OP_reg25 = 0x69, DW_OP_reg26 = 0x6a, DW_OP_reg27 = 0x6b, DW_OP_reg28 = 0x6c, DW_OP_reg29 = 0x6d, DW_OP_reg30 = 0x6e, DW_OP_reg31 = 0x6f, DW_OP_breg0 = 0x70, DW_OP_breg1 = 0x71, DW_OP_breg2 = 0x72, DW_OP_breg3 = 0x73, DW_OP_breg4 = 0x74, DW_OP_breg5 = 0x75, DW_OP_breg6 = 0x76, DW_OP_breg7 = 0x77, DW_OP_breg8 = 0x78, DW_OP_breg9 = 0x79, DW_OP_breg10 = 0x7a, DW_OP_breg11 = 0x7b, DW_OP_breg12 = 0x7c, DW_OP_breg13 = 0x7d, DW_OP_breg14 = 0x7e, DW_OP_breg15 = 0x7f, DW_OP_breg16 = 0x80, DW_OP_breg17 = 0x81, DW_OP_breg18 = 0x82, DW_OP_breg19 = 0x83, DW_OP_breg20 = 0x84, DW_OP_breg21 = 0x85, DW_OP_breg22 = 0x86, DW_OP_breg23 = 0x87, DW_OP_breg24 = 0x88, DW_OP_breg25 = 0x89, DW_OP_breg26 = 0x8a, DW_OP_breg27 = 0x8b, DW_OP_breg28 = 0x8c, DW_OP_breg29 = 0x8d, DW_OP_breg30 = 0x8e, DW_OP_breg31 = 0x8f, DW_OP_regx = 0x90, DW_OP_fbreg = 0x91, DW_OP_bregx = 0x92, DW_OP_piece = 0x93, DW_OP_deref_size = 0x94, DW_OP_xderef_size = 0x95, DW_OP_nop = 0x96 }; #define DW_OP_lo_user 0x80 /* implementation-defined range start */ #define DW_OP_hi_user 0xff /* implementation-defined range end */ /* Type encodings. */ enum dwarf_type { DW_ATE_void = 0x0, DW_ATE_address = 0x1, DW_ATE_boolean = 0x2, DW_ATE_complex_float = 0x3, DW_ATE_float = 0x4, DW_ATE_signed = 0x5, DW_ATE_signed_char = 0x6, DW_ATE_unsigned = 0x7, DW_ATE_unsigned_char = 0x8 }; #define DW_ATE_lo_user 0x80 #define DW_ATE_hi_user 0xff /* Array ordering names and codes. */ enum dwarf_array_dim_ordering { DW_ORD_row_major = 0, DW_ORD_col_major = 1 }; /* access attribute */ enum dwarf_access_attribute { DW_ACCESS_public = 1, DW_ACCESS_protected = 2, DW_ACCESS_private = 3 }; /* visibility */ enum dwarf_visibility_attribute { DW_VIS_local = 1, DW_VIS_exported = 2, DW_VIS_qualified = 3 }; /* virtuality */ enum dwarf_virtuality_attribute { DW_VIRTUALITY_none = 0, DW_VIRTUALITY_virtual = 1, DW_VIRTUALITY_pure_virtual = 2 }; /* case sensitivity */ enum dwarf_id_case { DW_ID_case_sensitive = 0, DW_ID_up_case = 1, DW_ID_down_case = 2, DW_ID_case_insensitive = 3 }; /* calling convention */ enum dwarf_calling_convention { DW_CC_normal = 0x1, DW_CC_program = 0x2, DW_CC_nocall = 0x3 }; #define DW_CC_lo_user 0x40 #define DW_CC_hi_user 0xff /* inline attribute */ enum dwarf_inline_attribute { DW_INL_not_inlined = 0, DW_INL_inlined = 1, DW_INL_declared_not_inlined = 2, DW_INL_declared_inlined = 3 }; /* discriminant lists */ enum dwarf_discrim_list { DW_DSC_label = 0, DW_DSC_range = 1 }; /* line number opcodes */ enum dwarf_line_number_ops { DW_LNS_extended_op = 0, DW_LNS_copy = 1, DW_LNS_advance_pc = 2, DW_LNS_advance_line = 3, DW_LNS_set_file = 4, DW_LNS_set_column = 5, DW_LNS_negate_stmt = 6, DW_LNS_set_basic_block = 7, DW_LNS_const_add_pc = 8, DW_LNS_fixed_advance_pc = 9 }; /* line number extended opcodes */ enum dwarf_line_number_x_ops { DW_LNE_end_sequence = 1, DW_LNE_set_address = 2, DW_LNE_define_file = 3 }; /* call frame information */ enum dwarf_call_frame_info { DW_CFA_advance_loc = 0x40, DW_CFA_offset = 0x80, DW_CFA_restore = 0xc0, DW_CFA_nop = 0x00, DW_CFA_set_loc = 0x01, DW_CFA_advance_loc1 = 0x02, DW_CFA_advance_loc2 = 0x03, DW_CFA_advance_loc4 = 0x04, DW_CFA_offset_extended = 0x05, DW_CFA_restore_extended = 0x06, DW_CFA_undefined = 0x07, DW_CFA_same_value = 0x08, DW_CFA_register = 0x09, DW_CFA_remember_state = 0x0a, DW_CFA_restore_state = 0x0b, DW_CFA_def_cfa = 0x0c, DW_CFA_def_cfa_register = 0x0d, DW_CFA_def_cfa_offset = 0x0e, DW_CFA_def_cfa_expression = 0x0f, DW_CFA_expression = 0x10, /* Dwarf 2.1 */ DW_CFA_offset_extended_sf = 0x11, DW_CFA_def_cfa_sf = 0x12, DW_CFA_def_cfa_offset_sf = 0x13, /* SGI/MIPS specific */ DW_CFA_MIPS_advance_loc8 = 0x1d, /* GNU extensions */ DW_CFA_GNU_window_save = 0x2d, DW_CFA_GNU_args_size = 0x2e, DW_CFA_GNU_negative_offset_extended = 0x2f }; #define DW_CIE_ID 0xffffffff #define DW_CIE_VERSION 1 #define DW_CFA_extended 0 #define DW_CFA_low_user 0x1c #define DW_CFA_high_user 0x3f #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 #define DW_ADDR_none 0 /* Source language names and codes. */ enum dwarf_source_language { DW_LANG_C89 = 0x0001, DW_LANG_C = 0x0002, DW_LANG_Ada83 = 0x0003, DW_LANG_C_plus_plus = 0x0004, DW_LANG_Cobol74 = 0x0005, DW_LANG_Cobol85 = 0x0006, DW_LANG_Fortran77 = 0x0007, DW_LANG_Fortran90 = 0x0008, DW_LANG_Pascal83 = 0x0009, DW_LANG_Modula2 = 0x000a, DW_LANG_Java = 0x000b, DW_LANG_Mips_Assembler = 0x8001 }; #define DW_LANG_lo_user 0x8000 /* implementation-defined range start */ #define DW_LANG_hi_user 0xffff /* implementation-defined range start */ /* Names and codes for macro information. */ enum dwarf_macinfo_record_type { DW_MACINFO_define = 1, DW_MACINFO_undef = 2, DW_MACINFO_start_file = 3, DW_MACINFO_end_file = 4, DW_MACINFO_vendor_ext = 255 }; #endif /* !ASSEMBLER */ /* @@@ For use with GNU frame unwind information. */ #define DW_EH_PE_absptr 0x00 #define DW_EH_PE_omit 0xff #define DW_EH_PE_uleb128 0x01 #define DW_EH_PE_udata2 0x02 #define DW_EH_PE_udata4 0x03 #define DW_EH_PE_udata8 0x04 #define DW_EH_PE_sleb128 0x09 #define DW_EH_PE_sdata2 0x0A #define DW_EH_PE_sdata4 0x0B #define DW_EH_PE_sdata8 0x0C #define DW_EH_PE_signed 0x08 #define DW_EH_PE_pcrel 0x10 #define DW_EH_PE_textrel 0x20 #define DW_EH_PE_datarel 0x30 #define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_aligned 0x50 #define DW_EH_PE_indirect 0x80 #endif /* dwarf2.h */ ``` sysdep-generic.h ``` /* Generic asm macros used on many machines. Copyright (C) 1991-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef C_LABEL /* Define a macro we can use to construct the asm name for a C symbol. */ # define C_LABEL(name) name##: #endif #ifdef __ASSEMBLER__ /* Mark the end of function named SYM. This is used on some platforms to generate correct debugging information. */ # ifndef END # define END(sym) # endif # ifndef JUMPTARGET # define JUMPTARGET(sym) sym # endif #endif /* Macros to generate eh_frame unwind information. */ #ifdef __ASSEMBLER__ # define cfi_startproc .cfi_startproc # define cfi_endproc .cfi_endproc # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off # define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg # define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off # define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off # define cfi_offset(reg, off) .cfi_offset reg, off # define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off # define cfi_register(r1, r2) .cfi_register r1, r2 # define cfi_return_column(reg) .cfi_return_column reg # define cfi_restore(reg) .cfi_restore reg # define cfi_same_value(reg) .cfi_same_value reg # define cfi_undefined(reg) .cfi_undefined reg # define cfi_remember_state .cfi_remember_state # define cfi_restore_state .cfi_restore_state # define cfi_window_save .cfi_window_save # define cfi_personality(enc, exp) .cfi_personality enc, exp # define cfi_lsda(enc, exp) .cfi_lsda enc, exp #else /* ! ASSEMBLER */ # define CFI_STRINGIFY(Name) CFI_STRINGIFY2 (Name) # define CFI_STRINGIFY2(Name) #Name # define CFI_STARTPROC ".cfi_startproc" # define CFI_ENDPROC ".cfi_endproc" # define CFI_DEF_CFA(reg, off) \ ".cfi_def_cfa " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_DEF_CFA_REGISTER(reg) \ ".cfi_def_cfa_register " CFI_STRINGIFY(reg) # define CFI_DEF_CFA_OFFSET(off) \ ".cfi_def_cfa_offset " CFI_STRINGIFY(off) # define CFI_ADJUST_CFA_OFFSET(off) \ ".cfi_adjust_cfa_offset " CFI_STRINGIFY(off) # define CFI_OFFSET(reg, off) \ ".cfi_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_REL_OFFSET(reg, off) \ ".cfi_rel_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_REGISTER(r1, r2) \ ".cfi_register " CFI_STRINGIFY(r1) "," CFI_STRINGIFY(r2) # define CFI_RETURN_COLUMN(reg) \ ".cfi_return_column " CFI_STRINGIFY(reg) # define CFI_RESTORE(reg) \ ".cfi_restore " CFI_STRINGIFY(reg) # define CFI_UNDEFINED(reg) \ ".cfi_undefined " CFI_STRINGIFY(reg) # define CFI_REMEMBER_STATE \ ".cfi_remember_state" # define CFI_RESTORE_STATE \ ".cfi_restore_state" # define CFI_WINDOW_SAVE \ ".cfi_window_save" # define CFI_PERSONALITY(enc, exp) \ ".cfi_personality " CFI_STRINGIFY(enc) "," CFI_STRINGIFY(exp) # define CFI_LSDA(enc, exp) \ ".cfi_lsda " CFI_STRINGIFY(enc) "," CFI_STRINGIFY(exp) #endif #include "dwarf2.h" ``` sysdep.h ``` /* Copyright (C) 1997-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef _AARCH64_SYSDEP_H #define _AARCH64_SYSDEP_H #include "sysdep-generic.h" #ifdef __LP64__ # define AARCH64_R(NAME) R_AARCH64_ ## NAME # define PTR_REG(n) x##n # define PTR_LOG_SIZE 3 # define PTR_ARG(n) # define SIZE_ARG(n) #else # define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME # define PTR_REG(n) w##n # define PTR_LOG_SIZE 2 # define PTR_ARG(n) mov w##n, w##n # define SIZE_ARG(n) mov w##n, w##n #endif #define PTR_SIZE (1<<PTR_LOG_SIZE) #ifndef __ASSEMBLER__ /* Strip pointer authentication code from pointer p. */ static inline void * strip_pac (void *p) { register void *ra asm ("x30") = (p); asm ("hint 7 // xpaclri" : "+r"(ra)); return ra; } /* This is needed when glibc is built with -mbranch-protection=pac-ret with a gcc that is affected by PR target/94891. */ # if HAVE_AARCH64_PAC_RET # undef RETURN_ADDRESS # define RETURN_ADDRESS(n) strip_pac (__builtin_return_address (n)) # endif #endif #ifdef __ASSEMBLER__ /* Syntactic details of assembler. */ #define ASM_SIZE_DIRECTIVE(name) .size name,.-name /* Branch Target Identitication support. */ #if HAVE_AARCH64_BTI # define BTI_C hint 34 # define BTI_J hint 36 #else # define BTI_C nop # define BTI_J nop #endif /* Return address signing support (pac-ret). */ #define PACIASP hint 25 #define AUTIASP hint 29 /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ #define FEATURE_1_AND 0xc0000000 #define FEATURE_1_BTI 1 #define FEATURE_1_PAC 2 /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ #define GNU_PROPERTY(type, value) \ .section .note.gnu.property, "a"; \ .p2align 3; \ .word 4; \ .word 16; \ .word 5; \ .asciz "GNU"; \ .word type; \ .word 4; \ .word value; \ .word 0; \ .text /* Add GNU property note with the supported features to all asm code where sysdep.h is included. */ #if HAVE_AARCH64_BTI && HAVE_AARCH64_PAC_RET GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC) #elif HAVE_AARCH64_BTI GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI) #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT /* Define an entry point visible from C. */ #define ENTRY_ALIGN(name, align) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align align; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT /* Define an entry point visible from C with a specified alignment and pre-padding with NOPs. This can be used to ensure that a critical loop within a function is cache line aligned. Note this version does not adjust the padding if CALL_MCOUNT is defined. */ #define ENTRY_ALIGN_AND_PAD(name, align, padding) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align align; \ .rep padding - 1; /* -1 for bti c. */ \ nop; \ .endr; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) /* If compiled for profiling, call `mcount' at the start of each function. */ #ifdef PROF # define CALL_MCOUNT \ str x30, [sp, #-80]!; \ cfi_adjust_cfa_offset (80); \ cfi_rel_offset (x30, 0); \ stp x0, x1, [sp, #16]; \ cfi_rel_offset (x0, 16); \ cfi_rel_offset (x1, 24); \ stp x2, x3, [sp, #32]; \ cfi_rel_offset (x2, 32); \ cfi_rel_offset (x3, 40); \ stp x4, x5, [sp, #48]; \ cfi_rel_offset (x4, 48); \ cfi_rel_offset (x5, 56); \ stp x6, x7, [sp, #64]; \ cfi_rel_offset (x6, 64); \ cfi_rel_offset (x7, 72); \ mov x0, x30; \ bl mcount; \ ldp x0, x1, [sp, #16]; \ cfi_restore (x0); \ cfi_restore (x1); \ ldp x2, x3, [sp, #32]; \ cfi_restore (x2); \ cfi_restore (x3); \ ldp x4, x5, [sp, #48]; \ cfi_restore (x4); \ cfi_restore (x5); \ ldp x6, x7, [sp, #64]; \ cfi_restore (x6); \ cfi_restore (x7); \ ldr x30, [sp], #80; \ cfi_adjust_cfa_offset (-80); \ cfi_restore (x30); #else # define CALL_MCOUNT /* Do nothing. */ #endif /* Local label name for asm code. */ #ifndef L # define L(name) .L##name #endif /* Load or store to/from a pc-relative EXPR into/from R, using T. Note R and T are register numbers and not register names. */ #define LDST_PCREL(OP, R, T, EXPR) \ adrp x##T, EXPR; \ OP PTR_REG (R), [x##T, #:lo12:EXPR]; \ /* Load or store to/from a got-relative EXPR into/from R, using T. Note R and T are register numbers and not register names. */ #define LDST_GLOBAL(OP, R, T, EXPR) \ adrp x##T, :got:EXPR; \ ldr PTR_REG (T), [x##T, #:got_lo12:EXPR]; \ OP PTR_REG (R), [x##T]; /* Load an immediate into R. Note R is a register number and not a register name. */ #ifdef __LP64__ # define MOVL(R, NAME) \ movz PTR_REG (R), #:abs_g3:NAME; \ movk PTR_REG (R), #:abs_g2_nc:NAME; \ movk PTR_REG (R), #:abs_g1_nc:NAME; \ movk PTR_REG (R), #:abs_g0_nc:NAME; #else # define MOVL(R, NAME) \ movz PTR_REG (R), #:abs_g1:NAME; \ movk PTR_REG (R), #:abs_g0_nc:NAME; #endif /* Since C identifiers are not normally prefixed with an underscore on this system, the asm identifier `syscall_error' intrudes on the C name space. Make sure we use an innocuous name. */ #define syscall_error __syscall_error #define mcount _mcount #endif /* __ASSEMBLER__ */ #endif /* _AARCH64_SYSDEP_H */ ``` memcpy_sve.S ``` #define _GNU_SOURCE #include "sysdep.h" #define dstin x0 #define src x1 #define count x2 #define dst x3 #define srcend x4 #define dstend x5 #define tmp1 x6 #define vlen x6 #define A_q q0 #define B_q q1 #define C_q q2 #define D_q q3 #define E_q q4 #define F_q q5 #define G_q q6 #define H_q q7 #ifndef C_SYMBOL_NAME # define C_SYMBOL_NAME(name) name #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) .arch armv8.2-a+sve ENTRY (memcpy) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp count, 128 b.hi L(copy_long) cntb vlen cmp count, vlen, lsl 1 b.hi L(copy32_128) whilelo p0.b, xzr, count whilelo p1.b, vlen, count ld1b z0.b, p0/z, [src, 0, mul vl] ld1b z1.b, p1/z, [src, 1, mul vl] st1b z0.b, p0, [dstin, 0, mul vl] st1b z1.b, p1, [dstin, 1, mul vl] ret /* Medium copies: 33..128 bytes. */ L(copy32_128): add srcend, src, count add dstend, dstin, count ldp A_q, B_q, [src] ldp C_q, D_q, [srcend, -32] cmp count, 64 b.hi L(copy128) stp A_q, B_q, [dstin] stp C_q, D_q, [dstend, -32] ret /* Copy 65..128 bytes. */ L(copy128): ldp E_q, F_q, [src, 32] cmp count, 96 b.ls L(copy96) ldp G_q, H_q, [srcend, -64] stp G_q, H_q, [dstend, -64] L(copy96): stp A_q, B_q, [dstin] stp E_q, F_q, [dstin, 32] stp C_q, D_q, [dstend, -32] ret .p2align 4 /* Copy more than 128 bytes. */ L(copy_long): add srcend, src, count add dstend, dstin, count /* Copy 32 bytes and then align src to 32-byte alignment. */ ldp G_q, H_q, [src] and tmp1, src, 31 bic src, src, 31 sub dst, dstin, tmp1 add count, count, tmp1 /* Count is now 32 too large. */ ldp A_q, B_q, [src, 32] stp G_q, H_q, [dstin] ldp C_q, D_q, [src, 64] subs count, count, 128 + 32 /* Test and readjust count. */ b.ls L(copy64_from_end) L(loop64): stp A_q, B_q, [dst, 32] ldp A_q, B_q, [src, 96] stp C_q, D_q, [dst, 64] ldp C_q, D_q, [src, 128] add src, src, 64 add dst, dst, 64 subs count, count, 64 b.hi L(loop64) /* Write the last iteration and copy 64 bytes from the end. */ L(copy64_from_end): ldp E_q, F_q, [srcend, -64] stp A_q, B_q, [dst, 32] ldp A_q, B_q, [srcend, -32] stp C_q, D_q, [dst, 64] stp E_q, F_q, [dstend, -64] stp A_q, B_q, [dstend, -32] ret END (memcpy) ENTRY (memmove2) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp count, 128 b.hi L(move_long) cntb vlen cmp count, vlen, lsl 1 b.hi L(copy32_128) whilelo p0.b, xzr, count whilelo p1.b, vlen, count ld1b z0.b, p0/z, [src, 0, mul vl] ld1b z1.b, p1/z, [src, 1, mul vl] st1b z0.b, p0, [dstin, 0, mul vl] st1b z1.b, p1, [dstin, 1, mul vl] ret .p2align 4 L(move_long): add srcend, src, count add dstend, dstin, count /* Only use backward copy if there is an overlap. */ sub tmp1, dstin, src cbz tmp1, L(return) cmp tmp1, count b.hs L(copy_long) /* Large backwards copy for overlapping copies. Copy 16 bytes and then align srcend to 16-byte alignment. */ ldp G_q, H_q, [srcend, -32] and tmp1, srcend, 31 bic srcend, srcend, 31 sub count, count, tmp1 ldp A_q, B_q, [srcend, -32] stp G_q, H_q, [dstend, -32] ldp C_q, D_q, [srcend, -64] sub dstend, dstend, tmp1 subs count, count, 128 b.ls L(copy64_from_start) L(loop64_backwards): stp A_q, B_q, [dstend, -32] ldp A_q, B_q, [srcend, -96] stp C_q, D_q, [dstend, -64]! ldp C_q, D_q, [srcend, -128] sub srcend, srcend, 64 subs count, count, 64 b.hi L(loop64_backwards) /* Write the last iteration and copy 64 bytes from the start. */ L(copy64_from_start): ldp E_q, F_q, [src, 32] stp A_q, B_q, [dstend, -32] ldp A_q, B_q, [src] stp C_q, D_q, [dstend, -64] stp E_q, F_q, [dstin, 32] stp A_q, B_q, [dstin] L(return): ret END (memmove2) ``` ``` /* memcmp - compare memory Copyright (C) 2013-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library. If not, see <https://www.gnu.org/licenses/>. */ #include "sysdep.h" /* Assumptions: * * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. */ #define src1 x0 #define src2 x1 #define limit x2 #define result w0 #define data1 x3 #define data1w w3 #define data2 x4 #define data2w w4 #define data3 x5 #define data3w w5 #define data4 x6 #define data4w w6 #define tmp x6 #define src1end x7 #define src2end x8 #ifndef C_SYMBOL_NAME # define C_SYMBOL_NAME(name) name #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) ENTRY (memcmp) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp limit, #128 b.hs __memcmp_aarch64_sve cmp limit, 16 b.lo L(less16) ldp data1, data3, [src1] ldp data2, data4, [src2] ccmp data1, data2, 0, ne ccmp data3, data4, 0, eq b.ne L(return2) add src1end, src1, limit add src2end, src2, limit cmp limit, 32 b.ls L(last_bytes) cmp limit, 160 b.hs L(loop_align) sub limit, limit, 32 .p2align 4 L(loop32): ldp data1, data3, [src1, 16] ldp data2, data4, [src2, 16] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) cmp limit, 16 b.ls L(last_bytes) ldp data1, data3, [src1, 32] ldp data2, data4, [src2, 32] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) add src1, src1, 32 add src2, src2, 32 L(last64): subs limit, limit, 32 b.hi L(loop32) /* Compare last 1-16 bytes using unaligned access. */ L(last_bytes): ldp data1, data3, [src1end, -16] ldp data2, data4, [src2end, -16] L(return2): cmp data1, data2 csel data1, data1, data3, ne csel data2, data2, data4, ne /* Compare data bytes and set return value to 0, -1 or 1. */ L(return): #ifndef __AARCH64EB__ rev data1, data1 rev data2, data2 #endif cmp data1, data2 cset result, ne cneg result, result, lo ret .p2align 4 L(less16): add src1end, src1, limit add src2end, src2, limit tbz limit, 3, L(less8) ldr data1, [src1] ldr data2, [src2] ldr data3, [src1end, -8] ldr data4, [src2end, -8] b L(return2) .p2align 4 L(less8): tbz limit, 2, L(less4) ldr data1w, [src1] ldr data2w, [src2] ldr data3w, [src1end, -4] ldr data4w, [src2end, -4] b L(return2) L(less4): tbz limit, 1, L(less2) ldrh data1w, [src1] ldrh data2w, [src2] cmp data1w, data2w b.ne L(return) L(less2): mov result, 0 tbz limit, 0, L(return_zero) ldrb data1w, [src1end, -1] ldrb data2w, [src2end, -1] sub result, data1w, data2w L(return_zero): ret L(loop_align): ldp data1, data3, [src1, 16] ldp data2, data4, [src2, 16] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) /* Align src2 and adjust src1, src2 and limit. */ and tmp, src2, 15 sub tmp, tmp, 16 sub src2, src2, tmp add limit, limit, tmp sub src1, src1, tmp sub limit, limit, 64 + 16 .p2align 4 L(loop64): ldr q0, [src1, 16] ldr q1, [src2, 16] subs limit, limit, 64 ldr q2, [src1, 32] ldr q3, [src2, 32] eor v0.16b, v0.16b, v1.16b eor v1.16b, v2.16b, v3.16b ldr q2, [src1, 48] ldr q3, [src2, 48] umaxp v0.16b, v0.16b, v1.16b ldr q4, [src1, 64]! ldr q5, [src2, 64]! eor v1.16b, v2.16b, v3.16b eor v2.16b, v4.16b, v5.16b umaxp v1.16b, v1.16b, v2.16b umaxp v0.16b, v0.16b, v1.16b umaxp v0.16b, v0.16b, v0.16b fmov tmp, d0 ccmp tmp, 0, 0, hi b.eq L(loop64) /* If equal, process last 1-64 bytes using scalar loop. */ add limit, limit, 64 + 16 cbz tmp, L(last64) /* Determine the 8-byte aligned offset of the first difference. */ #ifdef __AARCH64EB__ rev16 tmp, tmp #endif rev tmp, tmp clz tmp, tmp bic tmp, tmp, 7 sub tmp, tmp, 48 ldr data1, [src1, tmp] ldr data2, [src2, tmp] #ifndef __AARCH64EB__ rev data1, data1 rev data2, data2 #endif mov result, 1 cmp data1, data2 cneg result, result, lo ret /* *************** SVE implementation *************** */ .arch armv8.2-a+sve .text .type __memcmp_aarch64_sve, %function .p2align 4 __memcmp_aarch64_sve: mov x3, 0 // off = 0 0: whilelo p0.b, x3, x2 // p0 = (off < limit) b.none 9f ld1b z0.b, p0/z, [x0, x3] ld1b z1.b, p0/z, [x1, x3] incb x3 // off += svcntb() cmpne p1.b, p0/z, z0.b, z1.b b.none 0b // found mismatch brkb p1.b, p0/z, p1.b lasta w0, p1, z0.b lasta w1, p1, z1.b sub x0, x0, x1 ret 9: mov x0, 0 ret .size __memcmp_aarch64_sve, . - __memcmp_aarch64_sve END (memcmp) ``` Makefile ``` CC=gcc CFLAGS= -Wall -O3 -fPIC -shared LDFLAGS=-ldl .PHONY=all clean all: memcpy_sve.so memcpy_sve.so: memcpy_sve.S memcmp.S $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) clean: rm -f memcpy_sve.so ```
使用说明: 将下面文件放在同一目录后执行make,会生成memcpy_sve.so 执行程序前将so加载 LD_PRELOAD=/PATH/TO/memcpy_sve.so ./test dwarf2.h: ``` /* Declarations and definitions of codes relating to the DWARF2 symbolic debugging information format. Copyright (C) 1992-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef _DWARF2_H #define _DWARF2_H 1 /* This file is derived from the DWARF specification (a public document) Revision 2.0.0 (July 27, 1993) developed by the UNIX International Programming Languages Special Interest Group (UI/PLSIG) and distributed by UNIX International. Copies of this specification are available from UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */ /* This file is shared between GCC and GDB, and should not contain prototypes. */ #ifndef __ASSEMBLER__ /* Tag names and codes. */ enum dwarf_tag { DW_TAG_padding = 0x00, DW_TAG_array_type = 0x01, DW_TAG_class_type = 0x02, DW_TAG_entry_point = 0x03, DW_TAG_enumeration_type = 0x04, DW_TAG_formal_parameter = 0x05, DW_TAG_imported_declaration = 0x08, DW_TAG_label = 0x0a, DW_TAG_lexical_block = 0x0b, DW_TAG_member = 0x0d, DW_TAG_pointer_type = 0x0f, DW_TAG_reference_type = 0x10, DW_TAG_compile_unit = 0x11, DW_TAG_string_type = 0x12, DW_TAG_structure_type = 0x13, DW_TAG_subroutine_type = 0x15, DW_TAG_typedef = 0x16, DW_TAG_union_type = 0x17, DW_TAG_unspecified_parameters = 0x18, DW_TAG_variant = 0x19, DW_TAG_common_block = 0x1a, DW_TAG_common_inclusion = 0x1b, DW_TAG_inheritance = 0x1c, DW_TAG_inlined_subroutine = 0x1d, DW_TAG_module = 0x1e, DW_TAG_ptr_to_member_type = 0x1f, DW_TAG_set_type = 0x20, DW_TAG_subrange_type = 0x21, DW_TAG_with_stmt = 0x22, DW_TAG_access_declaration = 0x23, DW_TAG_base_type = 0x24, DW_TAG_catch_block = 0x25, DW_TAG_const_type = 0x26, DW_TAG_constant = 0x27, DW_TAG_enumerator = 0x28, DW_TAG_file_type = 0x29, DW_TAG_friend = 0x2a, DW_TAG_namelist = 0x2b, DW_TAG_namelist_item = 0x2c, DW_TAG_packed_type = 0x2d, DW_TAG_subprogram = 0x2e, DW_TAG_template_type_param = 0x2f, DW_TAG_template_value_param = 0x30, DW_TAG_thrown_type = 0x31, DW_TAG_try_block = 0x32, DW_TAG_variant_part = 0x33, DW_TAG_variable = 0x34, DW_TAG_volatile_type = 0x35, /* SGI/MIPS Extensions */ DW_TAG_MIPS_loop = 0x4081, /* GNU extensions */ DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */ DW_TAG_function_template = 0x4102, /* for C++ */ DW_TAG_class_template = 0x4103, /* for C++ */ DW_TAG_GNU_BINCL = 0x4104, DW_TAG_GNU_EINCL = 0x4105 }; #define DW_TAG_lo_user 0x4080 #define DW_TAG_hi_user 0xffff /* flag that tells whether entry has a child or not */ #define DW_children_no 0 #define DW_children_yes 1 /* Form names and codes. */ enum dwarf_form { DW_FORM_addr = 0x01, DW_FORM_block2 = 0x03, DW_FORM_block4 = 0x04, DW_FORM_data2 = 0x05, DW_FORM_data4 = 0x06, DW_FORM_data8 = 0x07, DW_FORM_string = 0x08, DW_FORM_block = 0x09, DW_FORM_block1 = 0x0a, DW_FORM_data1 = 0x0b, DW_FORM_flag = 0x0c, DW_FORM_sdata = 0x0d, DW_FORM_strp = 0x0e, DW_FORM_udata = 0x0f, DW_FORM_ref_addr = 0x10, DW_FORM_ref1 = 0x11, DW_FORM_ref2 = 0x12, DW_FORM_ref4 = 0x13, DW_FORM_ref8 = 0x14, DW_FORM_ref_udata = 0x15, DW_FORM_indirect = 0x16 }; /* Attribute names and codes. */ enum dwarf_attribute { DW_AT_sibling = 0x01, DW_AT_location = 0x02, DW_AT_name = 0x03, DW_AT_ordering = 0x09, DW_AT_subscr_data = 0x0a, DW_AT_byte_size = 0x0b, DW_AT_bit_offset = 0x0c, DW_AT_bit_size = 0x0d, DW_AT_element_list = 0x0f, DW_AT_stmt_list = 0x10, DW_AT_low_pc = 0x11, DW_AT_high_pc = 0x12, DW_AT_language = 0x13, DW_AT_member = 0x14, DW_AT_discr = 0x15, DW_AT_discr_value = 0x16, DW_AT_visibility = 0x17, DW_AT_import = 0x18, DW_AT_string_length = 0x19, DW_AT_common_reference = 0x1a, DW_AT_comp_dir = 0x1b, DW_AT_const_value = 0x1c, DW_AT_containing_type = 0x1d, DW_AT_default_value = 0x1e, DW_AT_inline = 0x20, DW_AT_is_optional = 0x21, DW_AT_lower_bound = 0x22, DW_AT_producer = 0x25, DW_AT_prototyped = 0x27, DW_AT_return_addr = 0x2a, DW_AT_start_scope = 0x2c, DW_AT_stride_size = 0x2e, DW_AT_upper_bound = 0x2f, DW_AT_abstract_origin = 0x31, DW_AT_accessibility = 0x32, DW_AT_address_class = 0x33, DW_AT_artificial = 0x34, DW_AT_base_types = 0x35, DW_AT_calling_convention = 0x36, DW_AT_count = 0x37, DW_AT_data_member_location = 0x38, DW_AT_decl_column = 0x39, DW_AT_decl_file = 0x3a, DW_AT_decl_line = 0x3b, DW_AT_declaration = 0x3c, DW_AT_discr_list = 0x3d, DW_AT_encoding = 0x3e, DW_AT_external = 0x3f, DW_AT_frame_base = 0x40, DW_AT_friend = 0x41, DW_AT_identifier_case = 0x42, DW_AT_macro_info = 0x43, DW_AT_namelist_items = 0x44, DW_AT_priority = 0x45, DW_AT_segment = 0x46, DW_AT_specification = 0x47, DW_AT_static_link = 0x48, DW_AT_type = 0x49, DW_AT_use_location = 0x4a, DW_AT_variable_parameter = 0x4b, DW_AT_virtuality = 0x4c, DW_AT_vtable_elem_location = 0x4d, /* SGI/MIPS Extensions */ DW_AT_MIPS_fde = 0x2001, DW_AT_MIPS_loop_begin = 0x2002, DW_AT_MIPS_tail_loop_begin = 0x2003, DW_AT_MIPS_epilog_begin = 0x2004, DW_AT_MIPS_loop_unroll_factor = 0x2005, DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, DW_AT_MIPS_stride = 0x2008, DW_AT_MIPS_abstract_name = 0x2009, DW_AT_MIPS_clone_origin = 0x200a, DW_AT_MIPS_has_inlines = 0x200b, /* GNU extensions. */ DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106 }; #define DW_AT_lo_user 0x2000 /* implementation-defined range start */ #define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */ /* Location atom names and codes. */ enum dwarf_location_atom { DW_OP_addr = 0x03, DW_OP_deref = 0x06, DW_OP_const1u = 0x08, DW_OP_const1s = 0x09, DW_OP_const2u = 0x0a, DW_OP_const2s = 0x0b, DW_OP_const4u = 0x0c, DW_OP_const4s = 0x0d, DW_OP_const8u = 0x0e, DW_OP_const8s = 0x0f, DW_OP_constu = 0x10, DW_OP_consts = 0x11, DW_OP_dup = 0x12, DW_OP_drop = 0x13, DW_OP_over = 0x14, DW_OP_pick = 0x15, DW_OP_swap = 0x16, DW_OP_rot = 0x17, DW_OP_xderef = 0x18, DW_OP_abs = 0x19, DW_OP_and = 0x1a, DW_OP_div = 0x1b, DW_OP_minus = 0x1c, DW_OP_mod = 0x1d, DW_OP_mul = 0x1e, DW_OP_neg = 0x1f, DW_OP_not = 0x20, DW_OP_or = 0x21, DW_OP_plus = 0x22, DW_OP_plus_uconst = 0x23, DW_OP_shl = 0x24, DW_OP_shr = 0x25, DW_OP_shra = 0x26, DW_OP_xor = 0x27, DW_OP_bra = 0x28, DW_OP_eq = 0x29, DW_OP_ge = 0x2a, DW_OP_gt = 0x2b, DW_OP_le = 0x2c, DW_OP_lt = 0x2d, DW_OP_ne = 0x2e, DW_OP_skip = 0x2f, DW_OP_lit0 = 0x30, DW_OP_lit1 = 0x31, DW_OP_lit2 = 0x32, DW_OP_lit3 = 0x33, DW_OP_lit4 = 0x34, DW_OP_lit5 = 0x35, DW_OP_lit6 = 0x36, DW_OP_lit7 = 0x37, DW_OP_lit8 = 0x38, DW_OP_lit9 = 0x39, DW_OP_lit10 = 0x3a, DW_OP_lit11 = 0x3b, DW_OP_lit12 = 0x3c, DW_OP_lit13 = 0x3d, DW_OP_lit14 = 0x3e, DW_OP_lit15 = 0x3f, DW_OP_lit16 = 0x40, DW_OP_lit17 = 0x41, DW_OP_lit18 = 0x42, DW_OP_lit19 = 0x43, DW_OP_lit20 = 0x44, DW_OP_lit21 = 0x45, DW_OP_lit22 = 0x46, DW_OP_lit23 = 0x47, DW_OP_lit24 = 0x48, DW_OP_lit25 = 0x49, DW_OP_lit26 = 0x4a, DW_OP_lit27 = 0x4b, DW_OP_lit28 = 0x4c, DW_OP_lit29 = 0x4d, DW_OP_lit30 = 0x4e, DW_OP_lit31 = 0x4f, DW_OP_reg0 = 0x50, DW_OP_reg1 = 0x51, DW_OP_reg2 = 0x52, DW_OP_reg3 = 0x53, DW_OP_reg4 = 0x54, DW_OP_reg5 = 0x55, DW_OP_reg6 = 0x56, DW_OP_reg7 = 0x57, DW_OP_reg8 = 0x58, DW_OP_reg9 = 0x59, DW_OP_reg10 = 0x5a, DW_OP_reg11 = 0x5b, DW_OP_reg12 = 0x5c, DW_OP_reg13 = 0x5d, DW_OP_reg14 = 0x5e, DW_OP_reg15 = 0x5f, DW_OP_reg16 = 0x60, DW_OP_reg17 = 0x61, DW_OP_reg18 = 0x62, DW_OP_reg19 = 0x63, DW_OP_reg20 = 0x64, DW_OP_reg21 = 0x65, DW_OP_reg22 = 0x66, DW_OP_reg23 = 0x67, DW_OP_reg24 = 0x68, DW_OP_reg25 = 0x69, DW_OP_reg26 = 0x6a, DW_OP_reg27 = 0x6b, DW_OP_reg28 = 0x6c, DW_OP_reg29 = 0x6d, DW_OP_reg30 = 0x6e, DW_OP_reg31 = 0x6f, DW_OP_breg0 = 0x70, DW_OP_breg1 = 0x71, DW_OP_breg2 = 0x72, DW_OP_breg3 = 0x73, DW_OP_breg4 = 0x74, DW_OP_breg5 = 0x75, DW_OP_breg6 = 0x76, DW_OP_breg7 = 0x77, DW_OP_breg8 = 0x78, DW_OP_breg9 = 0x79, DW_OP_breg10 = 0x7a, DW_OP_breg11 = 0x7b, DW_OP_breg12 = 0x7c, DW_OP_breg13 = 0x7d, DW_OP_breg14 = 0x7e, DW_OP_breg15 = 0x7f, DW_OP_breg16 = 0x80, DW_OP_breg17 = 0x81, DW_OP_breg18 = 0x82, DW_OP_breg19 = 0x83, DW_OP_breg20 = 0x84, DW_OP_breg21 = 0x85, DW_OP_breg22 = 0x86, DW_OP_breg23 = 0x87, DW_OP_breg24 = 0x88, DW_OP_breg25 = 0x89, DW_OP_breg26 = 0x8a, DW_OP_breg27 = 0x8b, DW_OP_breg28 = 0x8c, DW_OP_breg29 = 0x8d, DW_OP_breg30 = 0x8e, DW_OP_breg31 = 0x8f, DW_OP_regx = 0x90, DW_OP_fbreg = 0x91, DW_OP_bregx = 0x92, DW_OP_piece = 0x93, DW_OP_deref_size = 0x94, DW_OP_xderef_size = 0x95, DW_OP_nop = 0x96 }; #define DW_OP_lo_user 0x80 /* implementation-defined range start */ #define DW_OP_hi_user 0xff /* implementation-defined range end */ /* Type encodings. */ enum dwarf_type { DW_ATE_void = 0x0, DW_ATE_address = 0x1, DW_ATE_boolean = 0x2, DW_ATE_complex_float = 0x3, DW_ATE_float = 0x4, DW_ATE_signed = 0x5, DW_ATE_signed_char = 0x6, DW_ATE_unsigned = 0x7, DW_ATE_unsigned_char = 0x8 }; #define DW_ATE_lo_user 0x80 #define DW_ATE_hi_user 0xff /* Array ordering names and codes. */ enum dwarf_array_dim_ordering { DW_ORD_row_major = 0, DW_ORD_col_major = 1 }; /* access attribute */ enum dwarf_access_attribute { DW_ACCESS_public = 1, DW_ACCESS_protected = 2, DW_ACCESS_private = 3 }; /* visibility */ enum dwarf_visibility_attribute { DW_VIS_local = 1, DW_VIS_exported = 2, DW_VIS_qualified = 3 }; /* virtuality */ enum dwarf_virtuality_attribute { DW_VIRTUALITY_none = 0, DW_VIRTUALITY_virtual = 1, DW_VIRTUALITY_pure_virtual = 2 }; /* case sensitivity */ enum dwarf_id_case { DW_ID_case_sensitive = 0, DW_ID_up_case = 1, DW_ID_down_case = 2, DW_ID_case_insensitive = 3 }; /* calling convention */ enum dwarf_calling_convention { DW_CC_normal = 0x1, DW_CC_program = 0x2, DW_CC_nocall = 0x3 }; #define DW_CC_lo_user 0x40 #define DW_CC_hi_user 0xff /* inline attribute */ enum dwarf_inline_attribute { DW_INL_not_inlined = 0, DW_INL_inlined = 1, DW_INL_declared_not_inlined = 2, DW_INL_declared_inlined = 3 }; /* discriminant lists */ enum dwarf_discrim_list { DW_DSC_label = 0, DW_DSC_range = 1 }; /* line number opcodes */ enum dwarf_line_number_ops { DW_LNS_extended_op = 0, DW_LNS_copy = 1, DW_LNS_advance_pc = 2, DW_LNS_advance_line = 3, DW_LNS_set_file = 4, DW_LNS_set_column = 5, DW_LNS_negate_stmt = 6, DW_LNS_set_basic_block = 7, DW_LNS_const_add_pc = 8, DW_LNS_fixed_advance_pc = 9 }; /* line number extended opcodes */ enum dwarf_line_number_x_ops { DW_LNE_end_sequence = 1, DW_LNE_set_address = 2, DW_LNE_define_file = 3 }; /* call frame information */ enum dwarf_call_frame_info { DW_CFA_advance_loc = 0x40, DW_CFA_offset = 0x80, DW_CFA_restore = 0xc0, DW_CFA_nop = 0x00, DW_CFA_set_loc = 0x01, DW_CFA_advance_loc1 = 0x02, DW_CFA_advance_loc2 = 0x03, DW_CFA_advance_loc4 = 0x04, DW_CFA_offset_extended = 0x05, DW_CFA_restore_extended = 0x06, DW_CFA_undefined = 0x07, DW_CFA_same_value = 0x08, DW_CFA_register = 0x09, DW_CFA_remember_state = 0x0a, DW_CFA_restore_state = 0x0b, DW_CFA_def_cfa = 0x0c, DW_CFA_def_cfa_register = 0x0d, DW_CFA_def_cfa_offset = 0x0e, DW_CFA_def_cfa_expression = 0x0f, DW_CFA_expression = 0x10, /* Dwarf 2.1 */ DW_CFA_offset_extended_sf = 0x11, DW_CFA_def_cfa_sf = 0x12, DW_CFA_def_cfa_offset_sf = 0x13, /* SGI/MIPS specific */ DW_CFA_MIPS_advance_loc8 = 0x1d, /* GNU extensions */ DW_CFA_GNU_window_save = 0x2d, DW_CFA_GNU_args_size = 0x2e, DW_CFA_GNU_negative_offset_extended = 0x2f }; #define DW_CIE_ID 0xffffffff #define DW_CIE_VERSION 1 #define DW_CFA_extended 0 #define DW_CFA_low_user 0x1c #define DW_CFA_high_user 0x3f #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 #define DW_ADDR_none 0 /* Source language names and codes. */ enum dwarf_source_language { DW_LANG_C89 = 0x0001, DW_LANG_C = 0x0002, DW_LANG_Ada83 = 0x0003, DW_LANG_C_plus_plus = 0x0004, DW_LANG_Cobol74 = 0x0005, DW_LANG_Cobol85 = 0x0006, DW_LANG_Fortran77 = 0x0007, DW_LANG_Fortran90 = 0x0008, DW_LANG_Pascal83 = 0x0009, DW_LANG_Modula2 = 0x000a, DW_LANG_Java = 0x000b, DW_LANG_Mips_Assembler = 0x8001 }; #define DW_LANG_lo_user 0x8000 /* implementation-defined range start */ #define DW_LANG_hi_user 0xffff /* implementation-defined range start */ /* Names and codes for macro information. */ enum dwarf_macinfo_record_type { DW_MACINFO_define = 1, DW_MACINFO_undef = 2, DW_MACINFO_start_file = 3, DW_MACINFO_end_file = 4, DW_MACINFO_vendor_ext = 255 }; #endif /* !ASSEMBLER */ /* @@@ For use with GNU frame unwind information. */ #define DW_EH_PE_absptr 0x00 #define DW_EH_PE_omit 0xff #define DW_EH_PE_uleb128 0x01 #define DW_EH_PE_udata2 0x02 #define DW_EH_PE_udata4 0x03 #define DW_EH_PE_udata8 0x04 #define DW_EH_PE_sleb128 0x09 #define DW_EH_PE_sdata2 0x0A #define DW_EH_PE_sdata4 0x0B #define DW_EH_PE_sdata8 0x0C #define DW_EH_PE_signed 0x08 #define DW_EH_PE_pcrel 0x10 #define DW_EH_PE_textrel 0x20 #define DW_EH_PE_datarel 0x30 #define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_aligned 0x50 #define DW_EH_PE_indirect 0x80 #endif /* dwarf2.h */ ``` sysdep-generic.h ``` /* Generic asm macros used on many machines. Copyright (C) 1991-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef C_LABEL /* Define a macro we can use to construct the asm name for a C symbol. */ # define C_LABEL(name) name##: #endif #ifdef __ASSEMBLER__ /* Mark the end of function named SYM. This is used on some platforms to generate correct debugging information. */ # ifndef END # define END(sym) # endif # ifndef JUMPTARGET # define JUMPTARGET(sym) sym # endif #endif /* Macros to generate eh_frame unwind information. */ #ifdef __ASSEMBLER__ # define cfi_startproc .cfi_startproc # define cfi_endproc .cfi_endproc # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off # define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg # define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off # define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off # define cfi_offset(reg, off) .cfi_offset reg, off # define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off # define cfi_register(r1, r2) .cfi_register r1, r2 # define cfi_return_column(reg) .cfi_return_column reg # define cfi_restore(reg) .cfi_restore reg # define cfi_same_value(reg) .cfi_same_value reg # define cfi_undefined(reg) .cfi_undefined reg # define cfi_remember_state .cfi_remember_state # define cfi_restore_state .cfi_restore_state # define cfi_window_save .cfi_window_save # define cfi_personality(enc, exp) .cfi_personality enc, exp # define cfi_lsda(enc, exp) .cfi_lsda enc, exp #else /* ! ASSEMBLER */ # define CFI_STRINGIFY(Name) CFI_STRINGIFY2 (Name) # define CFI_STRINGIFY2(Name) #Name # define CFI_STARTPROC ".cfi_startproc" # define CFI_ENDPROC ".cfi_endproc" # define CFI_DEF_CFA(reg, off) \ ".cfi_def_cfa " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_DEF_CFA_REGISTER(reg) \ ".cfi_def_cfa_register " CFI_STRINGIFY(reg) # define CFI_DEF_CFA_OFFSET(off) \ ".cfi_def_cfa_offset " CFI_STRINGIFY(off) # define CFI_ADJUST_CFA_OFFSET(off) \ ".cfi_adjust_cfa_offset " CFI_STRINGIFY(off) # define CFI_OFFSET(reg, off) \ ".cfi_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_REL_OFFSET(reg, off) \ ".cfi_rel_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off) # define CFI_REGISTER(r1, r2) \ ".cfi_register " CFI_STRINGIFY(r1) "," CFI_STRINGIFY(r2) # define CFI_RETURN_COLUMN(reg) \ ".cfi_return_column " CFI_STRINGIFY(reg) # define CFI_RESTORE(reg) \ ".cfi_restore " CFI_STRINGIFY(reg) # define CFI_UNDEFINED(reg) \ ".cfi_undefined " CFI_STRINGIFY(reg) # define CFI_REMEMBER_STATE \ ".cfi_remember_state" # define CFI_RESTORE_STATE \ ".cfi_restore_state" # define CFI_WINDOW_SAVE \ ".cfi_window_save" # define CFI_PERSONALITY(enc, exp) \ ".cfi_personality " CFI_STRINGIFY(enc) "," CFI_STRINGIFY(exp) # define CFI_LSDA(enc, exp) \ ".cfi_lsda " CFI_STRINGIFY(enc) "," CFI_STRINGIFY(exp) #endif #include "dwarf2.h" ``` sysdep.h ``` /* Copyright (C) 1997-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ #ifndef _AARCH64_SYSDEP_H #define _AARCH64_SYSDEP_H #include "sysdep-generic.h" #ifdef __LP64__ # define AARCH64_R(NAME) R_AARCH64_ ## NAME # define PTR_REG(n) x##n # define PTR_LOG_SIZE 3 # define PTR_ARG(n) # define SIZE_ARG(n) #else # define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME # define PTR_REG(n) w##n # define PTR_LOG_SIZE 2 # define PTR_ARG(n) mov w##n, w##n # define SIZE_ARG(n) mov w##n, w##n #endif #define PTR_SIZE (1<<PTR_LOG_SIZE) #ifndef __ASSEMBLER__ /* Strip pointer authentication code from pointer p. */ static inline void * strip_pac (void *p) { register void *ra asm ("x30") = (p); asm ("hint 7 // xpaclri" : "+r"(ra)); return ra; } /* This is needed when glibc is built with -mbranch-protection=pac-ret with a gcc that is affected by PR target/94891. */ # if HAVE_AARCH64_PAC_RET # undef RETURN_ADDRESS # define RETURN_ADDRESS(n) strip_pac (__builtin_return_address (n)) # endif #endif #ifdef __ASSEMBLER__ /* Syntactic details of assembler. */ #define ASM_SIZE_DIRECTIVE(name) .size name,.-name /* Branch Target Identitication support. */ #if HAVE_AARCH64_BTI # define BTI_C hint 34 # define BTI_J hint 36 #else # define BTI_C nop # define BTI_J nop #endif /* Return address signing support (pac-ret). */ #define PACIASP hint 25 #define AUTIASP hint 29 /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ #define FEATURE_1_AND 0xc0000000 #define FEATURE_1_BTI 1 #define FEATURE_1_PAC 2 /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ #define GNU_PROPERTY(type, value) \ .section .note.gnu.property, "a"; \ .p2align 3; \ .word 4; \ .word 16; \ .word 5; \ .asciz "GNU"; \ .word type; \ .word 4; \ .word value; \ .word 0; \ .text /* Add GNU property note with the supported features to all asm code where sysdep.h is included. */ #if HAVE_AARCH64_BTI && HAVE_AARCH64_PAC_RET GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC) #elif HAVE_AARCH64_BTI GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI) #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT /* Define an entry point visible from C. */ #define ENTRY_ALIGN(name, align) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align align; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT /* Define an entry point visible from C with a specified alignment and pre-padding with NOPs. This can be used to ensure that a critical loop within a function is cache line aligned. Note this version does not adjust the padding if CALL_MCOUNT is defined. */ #define ENTRY_ALIGN_AND_PAD(name, align, padding) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align align; \ .rep padding - 1; /* -1 for bti c. */ \ nop; \ .endr; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) /* If compiled for profiling, call `mcount' at the start of each function. */ #ifdef PROF # define CALL_MCOUNT \ str x30, [sp, #-80]!; \ cfi_adjust_cfa_offset (80); \ cfi_rel_offset (x30, 0); \ stp x0, x1, [sp, #16]; \ cfi_rel_offset (x0, 16); \ cfi_rel_offset (x1, 24); \ stp x2, x3, [sp, #32]; \ cfi_rel_offset (x2, 32); \ cfi_rel_offset (x3, 40); \ stp x4, x5, [sp, #48]; \ cfi_rel_offset (x4, 48); \ cfi_rel_offset (x5, 56); \ stp x6, x7, [sp, #64]; \ cfi_rel_offset (x6, 64); \ cfi_rel_offset (x7, 72); \ mov x0, x30; \ bl mcount; \ ldp x0, x1, [sp, #16]; \ cfi_restore (x0); \ cfi_restore (x1); \ ldp x2, x3, [sp, #32]; \ cfi_restore (x2); \ cfi_restore (x3); \ ldp x4, x5, [sp, #48]; \ cfi_restore (x4); \ cfi_restore (x5); \ ldp x6, x7, [sp, #64]; \ cfi_restore (x6); \ cfi_restore (x7); \ ldr x30, [sp], #80; \ cfi_adjust_cfa_offset (-80); \ cfi_restore (x30); #else # define CALL_MCOUNT /* Do nothing. */ #endif /* Local label name for asm code. */ #ifndef L # define L(name) .L##name #endif /* Load or store to/from a pc-relative EXPR into/from R, using T. Note R and T are register numbers and not register names. */ #define LDST_PCREL(OP, R, T, EXPR) \ adrp x##T, EXPR; \ OP PTR_REG (R), [x##T, #:lo12:EXPR]; \ /* Load or store to/from a got-relative EXPR into/from R, using T. Note R and T are register numbers and not register names. */ #define LDST_GLOBAL(OP, R, T, EXPR) \ adrp x##T, :got:EXPR; \ ldr PTR_REG (T), [x##T, #:got_lo12:EXPR]; \ OP PTR_REG (R), [x##T]; /* Load an immediate into R. Note R is a register number and not a register name. */ #ifdef __LP64__ # define MOVL(R, NAME) \ movz PTR_REG (R), #:abs_g3:NAME; \ movk PTR_REG (R), #:abs_g2_nc:NAME; \ movk PTR_REG (R), #:abs_g1_nc:NAME; \ movk PTR_REG (R), #:abs_g0_nc:NAME; #else # define MOVL(R, NAME) \ movz PTR_REG (R), #:abs_g1:NAME; \ movk PTR_REG (R), #:abs_g0_nc:NAME; #endif /* Since C identifiers are not normally prefixed with an underscore on this system, the asm identifier `syscall_error' intrudes on the C name space. Make sure we use an innocuous name. */ #define syscall_error __syscall_error #define mcount _mcount #endif /* __ASSEMBLER__ */ #endif /* _AARCH64_SYSDEP_H */ ``` memcpy_sve.S ``` #define _GNU_SOURCE #include "sysdep.h" #define dstin x0 #define src x1 #define count x2 #define dst x3 #define srcend x4 #define dstend x5 #define tmp1 x6 #define vlen x6 #define A_q q0 #define B_q q1 #define C_q q2 #define D_q q3 #define E_q q4 #define F_q q5 #define G_q q6 #define H_q q7 #ifndef C_SYMBOL_NAME # define C_SYMBOL_NAME(name) name #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) .arch armv8.2-a+sve ENTRY (memcpy) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp count, 128 b.hi L(copy_long) cntb vlen cmp count, vlen, lsl 1 b.hi L(copy32_128) whilelo p0.b, xzr, count whilelo p1.b, vlen, count ld1b z0.b, p0/z, [src, 0, mul vl] ld1b z1.b, p1/z, [src, 1, mul vl] st1b z0.b, p0, [dstin, 0, mul vl] st1b z1.b, p1, [dstin, 1, mul vl] ret /* Medium copies: 33..128 bytes. */ L(copy32_128): add srcend, src, count add dstend, dstin, count ldp A_q, B_q, [src] ldp C_q, D_q, [srcend, -32] cmp count, 64 b.hi L(copy128) stp A_q, B_q, [dstin] stp C_q, D_q, [dstend, -32] ret /* Copy 65..128 bytes. */ L(copy128): ldp E_q, F_q, [src, 32] cmp count, 96 b.ls L(copy96) ldp G_q, H_q, [srcend, -64] stp G_q, H_q, [dstend, -64] L(copy96): stp A_q, B_q, [dstin] stp E_q, F_q, [dstin, 32] stp C_q, D_q, [dstend, -32] ret .p2align 4 /* Copy more than 128 bytes. */ L(copy_long): add srcend, src, count add dstend, dstin, count /* Copy 32 bytes and then align src to 32-byte alignment. */ ldp G_q, H_q, [src] and tmp1, src, 31 bic src, src, 31 sub dst, dstin, tmp1 add count, count, tmp1 /* Count is now 32 too large. */ ldp A_q, B_q, [src, 32] stp G_q, H_q, [dstin] ldp C_q, D_q, [src, 64] subs count, count, 128 + 32 /* Test and readjust count. */ b.ls L(copy64_from_end) L(loop64): stp A_q, B_q, [dst, 32] ldp A_q, B_q, [src, 96] stp C_q, D_q, [dst, 64] ldp C_q, D_q, [src, 128] add src, src, 64 add dst, dst, 64 subs count, count, 64 b.hi L(loop64) /* Write the last iteration and copy 64 bytes from the end. */ L(copy64_from_end): ldp E_q, F_q, [srcend, -64] stp A_q, B_q, [dst, 32] ldp A_q, B_q, [srcend, -32] stp C_q, D_q, [dst, 64] stp E_q, F_q, [dstend, -64] stp A_q, B_q, [dstend, -32] ret END (memcpy) ENTRY (memmove2) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp count, 128 b.hi L(move_long) cntb vlen cmp count, vlen, lsl 1 b.hi L(copy32_128) whilelo p0.b, xzr, count whilelo p1.b, vlen, count ld1b z0.b, p0/z, [src, 0, mul vl] ld1b z1.b, p1/z, [src, 1, mul vl] st1b z0.b, p0, [dstin, 0, mul vl] st1b z1.b, p1, [dstin, 1, mul vl] ret .p2align 4 L(move_long): add srcend, src, count add dstend, dstin, count /* Only use backward copy if there is an overlap. */ sub tmp1, dstin, src cbz tmp1, L(return) cmp tmp1, count b.hs L(copy_long) /* Large backwards copy for overlapping copies. Copy 16 bytes and then align srcend to 16-byte alignment. */ ldp G_q, H_q, [srcend, -32] and tmp1, srcend, 31 bic srcend, srcend, 31 sub count, count, tmp1 ldp A_q, B_q, [srcend, -32] stp G_q, H_q, [dstend, -32] ldp C_q, D_q, [srcend, -64] sub dstend, dstend, tmp1 subs count, count, 128 b.ls L(copy64_from_start) L(loop64_backwards): stp A_q, B_q, [dstend, -32] ldp A_q, B_q, [srcend, -96] stp C_q, D_q, [dstend, -64]! ldp C_q, D_q, [srcend, -128] sub srcend, srcend, 64 subs count, count, 64 b.hi L(loop64_backwards) /* Write the last iteration and copy 64 bytes from the start. */ L(copy64_from_start): ldp E_q, F_q, [src, 32] stp A_q, B_q, [dstend, -32] ldp A_q, B_q, [src] stp C_q, D_q, [dstend, -64] stp E_q, F_q, [dstin, 32] stp A_q, B_q, [dstin] L(return): ret END (memmove2) ``` ``` /* memcmp - compare memory Copyright (C) 2013-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library. If not, see <https://www.gnu.org/licenses/>. */ #include "sysdep.h" /* Assumptions: * * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. */ #define src1 x0 #define src2 x1 #define limit x2 #define result w0 #define data1 x3 #define data1w w3 #define data2 x4 #define data2w w4 #define data3 x5 #define data3w w5 #define data4 x6 #define data4w w6 #define tmp x6 #define src1end x7 #define src2end x8 #ifndef C_SYMBOL_NAME # define C_SYMBOL_NAME(name) name #endif /* Define an entry point visible from C. */ #define ENTRY(name) \ .globl C_SYMBOL_NAME(name); \ .type C_SYMBOL_NAME(name),%function; \ .p2align 6; \ C_LABEL(name) \ cfi_startproc; \ BTI_C; \ CALL_MCOUNT #undef END #define END(name) \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) ENTRY (memcmp) PTR_ARG (0) PTR_ARG (1) SIZE_ARG (2) cmp limit, #128 b.hs __memcmp_aarch64_sve cmp limit, 16 b.lo L(less16) ldp data1, data3, [src1] ldp data2, data4, [src2] ccmp data1, data2, 0, ne ccmp data3, data4, 0, eq b.ne L(return2) add src1end, src1, limit add src2end, src2, limit cmp limit, 32 b.ls L(last_bytes) cmp limit, 160 b.hs L(loop_align) sub limit, limit, 32 .p2align 4 L(loop32): ldp data1, data3, [src1, 16] ldp data2, data4, [src2, 16] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) cmp limit, 16 b.ls L(last_bytes) ldp data1, data3, [src1, 32] ldp data2, data4, [src2, 32] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) add src1, src1, 32 add src2, src2, 32 L(last64): subs limit, limit, 32 b.hi L(loop32) /* Compare last 1-16 bytes using unaligned access. */ L(last_bytes): ldp data1, data3, [src1end, -16] ldp data2, data4, [src2end, -16] L(return2): cmp data1, data2 csel data1, data1, data3, ne csel data2, data2, data4, ne /* Compare data bytes and set return value to 0, -1 or 1. */ L(return): #ifndef __AARCH64EB__ rev data1, data1 rev data2, data2 #endif cmp data1, data2 cset result, ne cneg result, result, lo ret .p2align 4 L(less16): add src1end, src1, limit add src2end, src2, limit tbz limit, 3, L(less8) ldr data1, [src1] ldr data2, [src2] ldr data3, [src1end, -8] ldr data4, [src2end, -8] b L(return2) .p2align 4 L(less8): tbz limit, 2, L(less4) ldr data1w, [src1] ldr data2w, [src2] ldr data3w, [src1end, -4] ldr data4w, [src2end, -4] b L(return2) L(less4): tbz limit, 1, L(less2) ldrh data1w, [src1] ldrh data2w, [src2] cmp data1w, data2w b.ne L(return) L(less2): mov result, 0 tbz limit, 0, L(return_zero) ldrb data1w, [src1end, -1] ldrb data2w, [src2end, -1] sub result, data1w, data2w L(return_zero): ret L(loop_align): ldp data1, data3, [src1, 16] ldp data2, data4, [src2, 16] cmp data1, data2 ccmp data3, data4, 0, eq b.ne L(return2) /* Align src2 and adjust src1, src2 and limit. */ and tmp, src2, 15 sub tmp, tmp, 16 sub src2, src2, tmp add limit, limit, tmp sub src1, src1, tmp sub limit, limit, 64 + 16 .p2align 4 L(loop64): ldr q0, [src1, 16] ldr q1, [src2, 16] subs limit, limit, 64 ldr q2, [src1, 32] ldr q3, [src2, 32] eor v0.16b, v0.16b, v1.16b eor v1.16b, v2.16b, v3.16b ldr q2, [src1, 48] ldr q3, [src2, 48] umaxp v0.16b, v0.16b, v1.16b ldr q4, [src1, 64]! ldr q5, [src2, 64]! eor v1.16b, v2.16b, v3.16b eor v2.16b, v4.16b, v5.16b umaxp v1.16b, v1.16b, v2.16b umaxp v0.16b, v0.16b, v1.16b umaxp v0.16b, v0.16b, v0.16b fmov tmp, d0 ccmp tmp, 0, 0, hi b.eq L(loop64) /* If equal, process last 1-64 bytes using scalar loop. */ add limit, limit, 64 + 16 cbz tmp, L(last64) /* Determine the 8-byte aligned offset of the first difference. */ #ifdef __AARCH64EB__ rev16 tmp, tmp #endif rev tmp, tmp clz tmp, tmp bic tmp, tmp, 7 sub tmp, tmp, 48 ldr data1, [src1, tmp] ldr data2, [src2, tmp] #ifndef __AARCH64EB__ rev data1, data1 rev data2, data2 #endif mov result, 1 cmp data1, data2 cneg result, result, lo ret /* *************** SVE implementation *************** */ .arch armv8.2-a+sve .text .type __memcmp_aarch64_sve, %function .p2align 4 __memcmp_aarch64_sve: mov x3, 0 // off = 0 0: whilelo p0.b, x3, x2 // p0 = (off < limit) b.none 9f ld1b z0.b, p0/z, [x0, x3] ld1b z1.b, p0/z, [x1, x3] incb x3 // off += svcntb() cmpne p1.b, p0/z, z0.b, z1.b b.none 0b // found mismatch brkb p1.b, p0/z, p1.b lasta w0, p1, z0.b lasta w1, p1, z1.b sub x0, x0, x1 ret 9: mov x0, 0 ret .size __memcmp_aarch64_sve, . - __memcmp_aarch64_sve END (memcmp) ``` Makefile ``` CC=gcc CFLAGS= -Wall -O3 -fPIC -shared LDFLAGS=-ldl .PHONY=all clean all: memcpy_sve.so memcpy_sve.so: memcpy_sve.S memcmp.S $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) clean: rm -f memcpy_sve.so ```
评论 (
1
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已拒绝
负责人
未设置
标签
sig/Computing
未设置
项目
未立项任务
未立项任务
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (30)
标签 (59)
master
openEuler-24.03-LTS-SP1
openEuler-24.03-LTS-SP2
openEuler-24.03-LTS-Next
openEuler-24.03-LTS-SP3
openEuler-24.03-LTS
openEuler-20.03-LTS-SP4
openEuler-25.09
openEuler-22.03-LTS-SP4
openEuler-22.03-LTS-SP3
openEuler-22.03-LTS-SP1
openEuler-25.03
openEuler-24.09
openEuler-22.03-LTS-SP2
openEuler-22.03-LTS-Next
openEuler-22.03-LTS
openEuler-20.03-LTS-SP1
openEuler-20.03-LTS-SP3
openEuler-23.09
openEuler-23.03
openEuler-22.03-LTS-LoongArch
openEuler-22.09
openEuler-20.03-LTS-Next
openEuler-20.03-LTS
openEuler-20.03-LTS-SP2
openEuler-21.09
openEuler-21.03
openEuler-20.09
openEuler1.0
openEuler1.0-base
openEuler-25.09-release
openEuler-22.03-LTS-SP3-update-20250815
openEuler-24.03-LTS-SP2-update-20250815
openEuler-24.03-LTS-update-20250815
openEuler-22.03-LTS-SP4-update-20250815
openEuler-24.03-LTS-SP1-update-20250815
openEuler-20.03-LTS-SP4-update-20250815
openEuler-24.03-LTS-SP2-release
openEuler-20.03-LTS-SP4-update-20250606
openEuler-22.03-LTS-SP3-update-20250606
openEuler-22.03-LTS-SP4-update-20250606
openEuler-24.03-LTS-update-20250606
openEuler-24.03-LTS-SP1-update-20250606
openEuler-25.03-release
openEuler-22.03-LTS-SP3-update-20250307
openEuler-22.03-LTS-SP4-update-20250307
openEuler-20.03-LTS-SP4-update-20250307
openEuler-24.03-LTS-SP1-update-20250221
openEuler-24.03-LTS-update-20250221
openEuler-24.03-LTS-SP1-release
openEuler-24.03-LTS-update-20241213
openEuler-22.03-LTS-SP4-update-20241213
openEuler-22.03-LTS-SP3-update-20241213
openEuler-22.03-LTS-SP1-update-20241213
openEuler-22.03-LTS-SP4-update-20241206
openEuler-22.03-LTS-SP3-update-20241206
openEuler-22.03-LTS-SP1-update-20241206
openEuler-22.03-LTS-SP1-update-20241129
openEuler-22.03-LTS-SP3-update-20241129
openEuler-22.03-LTS-SP4-update-20241129
openEuler-22.03-LTS-SP4-update-20241122
openEuler-22.03-LTS-SP3-update-20241122
openEuler-22.03-LTS-SP4-update-20241108
openEuler-22.03-LTS-SP3-update-20241108
openEuler-22.03-LTS-SP1-update-20241108
openEuler-22.03-LTS-SP4-update-before-20241025
openEuler-22.03-LTS-SP4-before-20241025
openEuler-24.03-LTS-update-before-20241025
openEuler-22.03-LTS-SP4-release
openEuler-24.09-release
openEuler-22.03-LTS-SP4_update20240819
openEuler-24.03-LTS-release
openEuler-22.03-LTS-SP3-release
openEuler-23.09-rc5
openEuler-22.03-LTS-SP1-release
openEuler-22.09-release
openEuler-22.09-rc5
openEuler-22.09-20220829
openEuler-22.03-LTS-20220331
openEuler-22.03-LTS-round5
openEuler-22.03-LTS-round3
openEuler-22.03-LTS-round2
openEuler-22.03-LTS-round1
openEuler-20.03-LTS-SP3-release
openEuler-20.03-LTS-SP2-20210624
openEuler-21.03-20210330
openEuler-20.09-20200929
openEuler-20.03-LTS-20200606
openEuler-20.03-LTS-tag
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
预计工期
(小时)
参与者(1)
1
https://gitee.com/src-openeuler/glibc.git
git@gitee.com:src-openeuler/glibc.git
src-openeuler
glibc
glibc
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册