__attribute__((section("name"))) study again

北慕城南 提交于 2020-01-24 06:02:39

目录

code tree

source code

init.h

init.c

gen-ld.sh

init-section.lds

ld.lds

main.c

module1_init.c

module2_init.c

makefile


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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!