Unverified Commit 3b53e7f8 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13450 [OLK-6.6][Backport] tools/nolibc: add support for constructors and destructors

Merge Pull Request from: @lazy2528 
 
With the startup code moved to C, implementing support for
constructors and deconstructors is fairly easy to implement.

Examples for code size impact:

   text	   data	    bss	    dec	    hex	filename
  21837	    104	     88	  22029	   560d	nolibc-test.before
  22135	    120	     88	  22343	   5747	nolibc-test.after
  21970	    104	     88	  22162	   5692 nolibc-test.after-only-crt.h-changes

The sections are defined by [0].

[0] https://refspecs.linuxfoundation.org/elf/gabi4+/ch5.dynamic.html

#IB6FDC  
 
Link:https://gitee.com/openeuler/kernel/pulls/13450 
parents 01b9dbc5 86a3597c
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -13,12 +13,23 @@ const unsigned long *_auxv __attribute__((weak));
static void __stack_chk_init(void);
static void exit(int);

extern void (*const __preinit_array_start[])(void) __attribute__((weak));
extern void (*const __preinit_array_end[])(void) __attribute__((weak));

extern void (*const __init_array_start[])(void) __attribute__((weak));
extern void (*const __init_array_end[])(void) __attribute__((weak));

extern void (*const __fini_array_start[])(void) __attribute__((weak));
extern void (*const __fini_array_end[])(void) __attribute__((weak));

__attribute__((weak))
void _start_c(long *sp)
{
	long argc;
	char **argv;
	char **envp;
	int exitcode;
	void (* const *func)(void);
	const unsigned long *auxv;
	/* silence potential warning: conflicting types for 'main' */
	int _nolibc_main(int, char **, char **) __asm__ ("main");
@@ -55,8 +66,18 @@ void _start_c(long *sp)
		;
	_auxv = auxv;

	for (func = __preinit_array_start; func < __preinit_array_end; func++)
		(*func)();
	for (func = __init_array_start; func < __init_array_end; func++)
		(*func)();

	/* go to application */
	exit(_nolibc_main(argc, argv, envp));
	exitcode = _nolibc_main(argc, argv, envp);

	for (func = __fini_array_end; func > __fini_array_start;)
		(*--func)();

	exit(exitcode);
}

#endif /* _NOLIBC_CRT_H */
+17 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ static int test_argc;
/* will be used by some test cases as readable file, please don't write it */
static const char *argv0;

/* will be used by constructor tests */
static int constructor_test_value;

/* definition of a series of tests */
struct test {
	const char *name;              /* test name */
@@ -594,6 +597,19 @@ int expect_strne(const char *expr, int llen, const char *cmp)
#define CASE_TEST(name) \
	case __LINE__: llen += printf("%d %s", test, #name);

/* constructors validate that they are executed in definition order */
__attribute__((constructor))
static void constructor1(void)
{
	constructor_test_value = 1;
}

__attribute__((constructor))
static void constructor2(void)
{
	constructor_test_value *= 2;
}

int run_startup(int min, int max)
{
	int test;
@@ -630,6 +646,7 @@ int run_startup(int min, int max)
		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;
		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
		CASE_TEST(constructor);      EXPECT_EQ(1, constructor_test_value, 2); break;
		CASE_TEST(auxv_AT_PAGESZ);   EXPECT_GE(1, getauxval(AT_PAGESZ), 4096); break;
		case __LINE__:
			return ret; /* must be last */