Del Kernel al código Stand-Alone
Lo que hemos descubierto hasta ahora no solo es como funciona el kernel Linux,
pero también es una solucion para crear una lista de apuntadores
a funciones en tiempo de compilación las cuales deberan ser llamadas
en el orden que fueron inicializadas. Tomando el código de la seccion
anterior y haciendolo mas stand-alone y de propósito general, terminamos
en lo siguiente: (date cuenta como no se requirio del script del enlazador)
/*
* AUTHOR: Trevor Woerner
* START DATE: 14 August 2003 - 09:58:33 AM
* MODIFIED: 23 September 2003 - 01:23:56 AM
* FILENAME: mycalls.c
* PURPOSE: Compile-time table of function pointers
*
* Copyright (C) 2003 Trevor Woerner
*/
#include <stdio.h>
typedef void (*funcptr_t)(void);
extern funcptr_t __start_newsect, __stop_newsect;
#define data_attr __attribute__ ((section ("newsect")))
#define create_entry(fn) funcptr_t _##fn data_attr = fn
void my_init1 (void) { printf ("my_init1() #1\n"); }
void my_init2 (void) { printf ("my_init2() #2\n"); }
create_entry (my_init1);
create_entry (my_init2);
int
main (void)
{
funcptr_t *call_p;
call_p = &__start_newsect;
do {
printf ("call_p: %p\n", call_p);
(*call_p)();
++call_p;
} while (call_p < &__stop_newsect);
return 0;
}
|
el cual genera:
[trevor]$ ./mycalls
call_p: 0x8049488
my_init1() #1
call_p: 0x804948c
my_init2() #2
[trevor]$
|
08048230 g F .init 00000000 _init
08048230 l d .init 00000000
08048248 l d .plt 00000000
08048258 F *UND* 000000fb __libc_start_main@@GLIBC_2.0
08048268 F *UND* 00000039 printf@@GLIBC_2.0
08048278 g F .text 00000000 _start
08048278 l d .text 00000000
0804829c l F .text 00000000 call_gmon_start
080482c0 l F .text 00000000 __do_global_dtors_aux
080482fc l F .text 00000000 frame_dummy
08048328 g F .text 00000018 my_init1
08048340 g F .text 00000018 my_init2
08048358 g F .text 00000047 main
080483a0 g F .text 00000030 __libc_csu_init
080483d0 g F .text 00000034 __libc_csu_fini
08048404 l F .text 00000000 __do_global_ctors_aux
08048428 g F .fini 00000000 _fini
08048428 l d .fini 00000000
08048444 g O .rodata 00000004 _fp_hw
08048444 l d .rodata 00000000
08048448 g O .rodata 00000004 _IO_stdin_used
08048478 l O .eh_frame 00000000 __EH_FRAME_BEGIN__
08048478 l O .eh_frame 00000000 __FRAME_END__
08048478 l d .eh_frame 00000000
0804947c w .data 00000000 data_start
0804947c g *ABS* 00000000 __fini_array_end
0804947c g *ABS* 00000000 __fini_array_start
0804947c g *ABS* 00000000 __init_array_end
0804947c g *ABS* 00000000 __init_array_start
0804947c g .data 00000000 __data_start
0804947c l d .data 00000000
08049480 g O .data 00000000 .hidden __dso_handle
08049484 l O .data 00000000 p.0
08049488 g *ABS* 00000000 __start_newsect
08049488 g O newsect 00000004 _my_init1
08049488 l d newsect 00000000
0804948c g O newsect 00000004 _my_init2
08049490 g *ABS* 00000000 __stop_newsect
08049490 g O .dynamic 00000000 _DYNAMIC
08049490 l d .dynamic 00000000
08049558 l O .ctors 00000000 __CTOR_LIST__
08049558 l d .ctors 00000000
0804955c l O .ctors 00000000 __CTOR_END__
08049560 l O .dtors 00000000 __DTOR_LIST__
08049560 l d .dtors 00000000
08049564 l O .dtors 00000000 __DTOR_END__
08049568 l O .jcr 00000000 __JCR_END__
08049568 l O .jcr 00000000 __JCR_LIST__
08049568 l d .jcr 00000000
0804956c g O .got 00000000 _GLOBAL_OFFSET_TABLE_
0804956c l d .got 00000000
08049584 g *ABS* 00000000 __bss_start
08049584 g *ABS* 00000000 _edata
08049584 l O .bss 00000001 completed.1
08049584 l d .bss 00000000
08049588 g *ABS* 00000000 _end
|
Date cuenta también como las funciones
my_initN() fueron puestas en el segmento general
.text yo de verdad no le pongo cuidado donde terminan
(no como los chicos del kernel).