OSDev http://osdev.su/ |
|
Патч gcc-4.5.1 для naked функций http://osdev.su/viewtopic.php?f=6&t=331 |
Страница 1 из 1 |
Автор: | NEbO [ 21 авг 2010, 10:18 ] |
Заголовок сообщения: | Патч gcc-4.5.1 для naked функций |
Сделал патч для того, чтобы gcc поддерживал __attribute__((naked)) на платформе i386. Тупо генерирует фунцкию без пролога и эпилога (в т.ч. и без ret, как и в большинстве компиляторов). Возможно, кому-нибудь пригодится, например, для создания хендлеров для прерываний. Особенности: 1. внутри naked функций нельзя вызывать функции с параметрами, передающимися через стек, поскольку gcc кладет параметры в положительном смещении от esp. Например, нельзя: Код: void f2(int k) { kprintf("%i\n", k); } __attribute__((naked)) void f1() { f2(3); asm("ret"); } при передаче параметра 3 в функцию f2 gcc затрет код возврата... зато, можно f2 объявить как __attribute__((regparm(1))) и все будет нормально (только при этом необходимо применить оптимизацию, например, в виде -O2 или -Os). 2. нельзя применять -fomit-frame-pointer, поскольку в таком случае и локальные переменные окажутся выше esp. Решение проблем: - для прерываний создать отдельный модуль, который будет компилироваться без -fomit-frame-pointer. - передавать параметры через регистры во все функции которые вызываются из naked функций, и использовать при этом -O2. P.S. если кто может помочь с ключом компилятора, чтоб параметры в функцию пушились, буду благодарен. )) P.P.S. файлом патч выложить не удалось, поэтому выкладываю текстом: (применение: в директории gcc-4.5.1: patch -Np1 -i ../gcc-4.5.1_naked.patch) Код: diff -cr gcc.orig/gcc/config/i386/i386.c gcc/gcc/config/i386/i386.c
*** gcc.orig/gcc/config/i386/i386.c Thu Jul 22 06:42:02 2010 --- gcc/gcc/config/i386/i386.c Thu Aug 19 17:24:05 2010 *************** *** 4842,4847 **** --- 4842,4855 ---- return false; } + static bool + ix86_function_naked (const_tree fntype) + { + if (lookup_attribute ("naked", DECL_ATTRIBUTES (fntype))) + return true; + return false; + } + static enum calling_abi ix86_function_abi (const_tree fndecl) { *************** *** 8478,8483 **** --- 8486,8494 ---- struct ix86_frame frame; HOST_WIDE_INT allocate; int gen_frame_pointer = frame_pointer_needed; + + if (ix86_function_naked (current_function_decl)) + return ; ix86_finalize_stack_realign_flags (); *************** *** 8978,8983 **** --- 8989,8997 ---- HOST_WIDE_INT offset, red_offset; struct machine_cfa_state cfa_state_save = *ix86_cfa_state; bool using_drap; + + if (ix86_function_naked (current_function_decl)) + return ; ix86_finalize_stack_realign_flags (); *************** *** 26117,26122 **** --- 26131,26152 ---- return NULL_TREE; } + static tree + ix86_handle_naked_attribute (tree *node, tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) + { + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + *no_add_attrs = true; + return NULL_TREE; + } + + return NULL_TREE; + } + static bool ix86_ms_bitfield_layout_p (const_tree record_type) { *************** *** 28988,28993 **** --- 29018,29024 ---- { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute }, { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute }, /* End element. */ + { "naked", 0, 0, true, false, false, ix86_handle_naked_attribute }, { NULL, 0, 0, false, false, false, NULL } }; diff -cr gcc.orig/gcc/function.c gcc/gcc/function.c *** gcc.orig/gcc/function.c Fri Feb 26 15:58:57 2010 --- gcc/gcc/function.c Thu Aug 19 17:11:26 2010 *************** *** 5212,5224 **** start_sequence (); epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG); seq = gen_epilogue (); ! emit_jump_insn (seq); ! ! /* Retain a map of the epilogue insns. */ ! record_insns (seq, NULL, &epilogue_insn_hash); ! set_insn_locators (seq, epilogue_locator); ! seq = get_insns (); end_sequence (); insert_insn_on_edge (seq, e); --- 5212,5228 ---- start_sequence (); epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG); seq = gen_epilogue (); ! ! if (seq) ! { ! emit_jump_insn (seq); ! /* Retain a map of the epilogue insns. */ ! record_insns (seq, NULL, &epilogue_insn_hash); ! set_insn_locators (seq, epilogue_locator); ! } ! ! seq = get_insns (); end_sequence (); insert_insn_on_edge (seq, e); |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |