Skip to content

Instantly share code, notes, and snippets.

@ice799
Created November 19, 2012 02:41
Show Gist options
  • Select an option

  • Save ice799/4108687 to your computer and use it in GitHub Desktop.

Select an option

Save ice799/4108687 to your computer and use it in GitHub Desktop.

Revisions

  1. ice799 created this gist Nov 19, 2012.
    253 changes: 253 additions & 0 deletions machdep.S
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,253 @@
    /* machdep.S - machine dependent assembly routines for the GDB stub */
    /*
    * Copyright (C) 2006 Lubomir Kundrak
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    * This program 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 General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program; if not, write to the Free Software
    * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    */

    #include <grub/cpu/gdb.h>
    #include <grub/symbol.h>

    #define EC_PRESENT 1
    #define EC_ABSENT 0

    #define GRUB_GDB_STACKSIZE 40000

    #define SEP ,

    #ifdef __APPLE__
    .zerofill __DATA, __bss, LOCAL(grub_gdb_stack_end), GRUB_GDB_STACKSIZE, 4
    LOCAL(grub_gdb_stack) = LOCAL(grub_gdb_stack_end)
    #else
    /*
    * The .data index for the address vector.
    */

    #define VECTOR 1

    .bss
    .space GRUB_GDB_STACKSIZE
    VARIABLE(grub_gdb_stack)
    #endif

    /*
    * Supplemental macros for register saving/restoration
    * on exception handler entry/leave.
    */

    #ifdef __APPLE__
    .macro save32
    #define REG $0
    #define NDX $1
    #else
    .macro save32 reg ndx
    #define REG \reg
    #define NDX \ndx
    #endif
    movl REG, EXT_C(grub_gdb_regs)+(NDX * 4)
    .endm

    #undef REG
    #undef NDX

    #ifdef __APPLE__
    .macro save16
    #define REG $0
    #define NDX $1
    #else
    .macro save16 reg ndx
    #define REG \reg
    #define NDX \ndx
    #endif
    #ifdef __APPLE__
    xorl %eax, %eax
    #else
    movl $0, %eax
    #endif
    movw REG, EXT_C(grub_gdb_regs)+(NDX * 4)
    movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2)
    movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax
    .endm

    #undef REG
    #undef NDX

    #ifdef __APPLE__
    .macro load32
    #define NDX $0
    #define REG $1
    #else
    .macro load32 ndx reg
    #define REG \reg
    #define NDX \ndx
    #endif
    movl EXT_C(grub_gdb_regs)+(NDX * 4), REG
    .endm

    #undef REG
    #undef NDX

    #ifdef __APPLE__
    .macro load16
    #define NDX $0
    #define REG $1
    #else
    .macro load16 ndx reg
    #define NDX \ndx
    #define REG \reg
    #endif
    movw EXT_C(grub_gdb_regs)+(NDX * 4), REG
    .endm

    #undef REG
    #undef NDX

    .macro save_context
    save32 %eax, EAX

    save32 %ecx, ECX
    save32 %edx, EDX
    save32 %ebx, EBX
    save32 %ebp, EBP
    save32 %esi, ESI
    save32 %edi, EDI

    popl %ebx
    save32 %ebx, EIP
    popl %ebx
    save32 %ebx, CS
    popl %ebx
    save32 %ebx, EFLAGS

    save32 %esp, ESP

    save16 %ds, DS
    save16 %es, ES
    save16 %fs, FS
    save16 %gs, GS
    save16 %ss, SS
    .endm

    .macro load_context
    load16 SS, %ss
    load32 ESP, %esp

    load32 EBP, %ebp
    load32 ESI, %esi
    load32 EDI, %edi

    load16 DS, %ds
    load16 ES, %es
    load16 FS, %fs
    load16 GS, %gs

    load32 EFLAGS, %eax
    pushl %eax
    load32 CS, %eax
    pushl %eax
    load32 EIP, %eax
    pushl %eax

    load32 EBX, %ebx
    load32 EDX, %edx
    load32 ECX, %ecx
    load32 EAX, %eax
    .endm

    /*
    * This macro creates handlers for a given range of exception numbers
    * and adds their addresses to the grub_gdb_trapvec array.
    */

    #ifdef __APPLE__
    .macro ent
    #define EC $0
    #define BEG $1
    #define END $2
    #else
    .macro ent ec beg end=0
    #define EC \ec
    #define BEG \beg
    #define END \end
    #endif

    /*
    * Wrapper body itself.
    */

    .text
    1:
    .if EC
    #ifdef __APPLE__
    add $$4, %esp
    #else
    add $4, %esp
    #endif
    .endif

    save_context
    #ifdef __APPLE__
    mov $LOCAL(grub_gdb_stack), %esp
    #else
    mov $EXT_C(grub_gdb_stack), %esp
    #endif
    mov $(BEG), %eax /* trap number */
    call EXT_C(grub_gdb_trap)
    load_context
    iret

    /*
    * Address entry in trapvec array.
    */

    #ifdef __APPLE__
    .section __DATA, VECTOR
    #else
    .data VECTOR
    #endif
    .long 1b

    /*
    * Next... (recursion).
    */

    .if END-BEG > 0
    #ifdef __APPLE__
    ent EC, (BEG+1), END
    #else
    ent \ec "(\beg+1)" \end
    #endif
    .endif
    .endm

    /*
    * Here does the actual construction of the address array and handlers
    * take place.
    */
    #ifdef __APPLE__
    .section __DATA, VECTOR
    #else
    .data VECTOR
    #endif
    VARIABLE(grub_gdb_trapvec)
    ent EC_ABSENT, 0, 7
    ent EC_PRESENT, 8
    ent EC_ABSENT, 9
    ent EC_PRESENT, 10, 14
    /*
    * You may have to split this further or as(1)
    * will complain about nesting being too deep.
    */
    ent EC_ABSENT, 15, GRUB_GDB_LAST_TRAP