目录
code tree
# tree
.
├── init
│ ├── gen-ld.sh
│ ├── init.c
│ ├── init.h
│ ├── init-section.lds
│ ├── ld.lds
│ └── ld.lds.backup
├── main.c
├── makefile
├── module1
│ └── module1_init.c
└── module2
└── module2_init.c
3 directories, 10 files
source code
init.h
#ifndef __INIT_H
#define __INIT_H 1
#ifdef __INIT_LOG
#include <stdio.h>
#define init_log(fmt...) ({ \
int n = 0;\
n+=fprintf(stdout, "[INIT] %s %s:%d ", __FILE__, __func__, __LINE__);\
n+=fprintf(stdout, fmt);\
n;\
})
#else
#define init_log(fmt...)
#endif
#define _section(StrName) __attribute__((section(StrName)))
#define INIT_FN_SECTION ".rongtao.init.func"
#define _initfn _section(INIT_FN_SECTION)
#define INIT_ADD(func) init_call __initfn_##func _initfn = func
typedef int (*init_call)(void);
extern init_call init_start;
extern init_call init_end;
void do_initcalls(void);
#endif /*<__INIT_H>*/
init.c
#include <stdio.h>
#include "init.h"
void do_initcalls(void)
{
init_call *call_ptr = &init_start;
while (call_ptr && call_ptr < &init_end)
{
init_log ("call_ptr: %p\n", call_ptr);
(*call_ptr)();
++call_ptr;
};
}
gen-ld.sh
#!/bin/bash
file=ld.lds
words=init-section.lds
ld --verbose > $file
string="__bss_start"
line=`grep $string $file`
num=$(grep -n "$line" $file | awk -F ':' '{print $1}')
num=$(expr $num - 1)
numa=$num" r"
sed -i "$numa $words" $file
init-section.lds
/**************************************/
.rongtao.init.func : {
/* . = ALIGN(4);*/
init_start = .;
*(.rongtao.init.func*)
init_end = .;
}
/**************************************/
ld.lds
not show all of it, you can generate with gen-ld.sh
_edata = .; PROVIDE (edata = .);
. = .;
/**************************************/
.rongtao.init.func : {
/* . = ALIGN(4);*/
init_start = .;
*(.rongtao.init.func*)
init_end = .;
}
/**************************************/
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
main.c
#include <stdio.h>
#define __INIT_LOG
#include "init.h"
int main()
{
do_initcalls();
return 0;
}
module1_init.c
#include <stdio.h>
#define __INIT_LOG
#include "init.h"
int module1_init()
{
init_log("rongtao1\n");
}
INIT_ADD(module1_init);
module2_init.c
#include <stdio.h>
#define __INIT_LOG
#include "init.h"
int module2_init()
{
init_log("rongtao1\n");
}
INIT_ADD(module2_init);
makefile
LD:=init/ld.lds
SRC:=./init/init.c\
main.c \
module1/module1_init.c \
module2/module2_init.c
INCLUDE:= -I./init \
-I./ \
-I./module1\
-I./module2
all:${SRC} ${LD} ${DEPS}
gcc ${SRC} -Wl,-T${LD} ${INCLUDE}
clean:
rm -f a.out
来源:CSDN
作者:Koma_Wong
链接:https://blog.csdn.net/Rong_Toa/article/details/104063428