OSDev

для всех
Текущее время: 14 дек 2024, 06:53

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ 1 сообщение ] 
Автор Сообщение
 Заголовок сообщения: Патч gcc-4.5.1 для naked функций
СообщениеДобавлено: 21 авг 2010, 10:18 

Зарегистрирован: 19 авг 2010, 23:31
Сообщения: 1
Сделал патч для того, чтобы 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 сообщение ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB