Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 07 Jul 2010 11:35:52 +0300
From:      Andriy Gapon <avg@freebsd.org>
To:        "Bjoern A. Zeeb" <bzeeb-lists@lists.zabbadoz.net>, freebsd-hackers@freebsd.org
Cc:        Konstantin Belousov <kib@freebsd.org>, Navdeep Parhar <np@freebsd.org>, Peter Wemm <peter@freebsd.org>
Subject:   Re: elf obj load: skip zero-sized sections early
Message-ID:  <4C343C68.8010302@freebsd.org>
In-Reply-To: <4C321409.2070500@freebsd.org>
References:  <4C246CD0.3020606@freebsd.org> <20100702082754.S14969@maildrop.int.zabbadoz.net> <4C320E6E.4040007@freebsd.org> <20100705171155.K14969@maildrop.int.zabbadoz.net> <4C321409.2070500@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

What do you think about something like the following?

diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index 1ee7717..ddfdefc 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -53,14 +53,17 @@
 extern uintptr_t *__start_set_pcpu;
 extern uintptr_t *__stop_set_pcpu;

-__asm__(
-#ifdef __arm__
-	".section set_pcpu, \"aw\", %progbits\n"
+#if defined(__arm__)
+#define _PROGBITS "%progbits"
 #else
-	".section set_pcpu, \"aw\", @progbits\n"
+#define _PROGBITS "@progbits"
 #endif
-	"\t.p2align " __XSTRING(CACHE_LINE_SHIFT) "\n"
-	"\t.previous");
+#define	_CUSTOM_SECTION(name, flags, align)				\
+	__asm__(							\
+		".section	" __XSTRING(name)			\
+			",\"" __XSTRING(flags) "\"," _PROGBITS "\n"	\
+		"\t.p2align " __XSTRING(align) "\n"			\
+		"\t.previous")

 /*
  * Array of dynamic pcpu base offsets.  Indexed by id.
@@ -82,7 +85,10 @@ extern uintptr_t dpcpu_off[];
  */
 #define	DPCPU_NAME(n)		pcpu_entry_##n
 #define	DPCPU_DECLARE(t, n)	extern t DPCPU_NAME(n)
-#define	DPCPU_DEFINE(t, n)	t DPCPU_NAME(n) __section("set_pcpu") __used
+
+#define	DPCPU_DEFINE(t, n)						\
+	_CUSTOM_SECTION(set_pcpu, aw, CACHE_LINE_SHIFT);		\
+	t DPCPU_NAME(n) __section("set_pcpu") __used

 /*
  * Accessors with a given base.


The diff looks a little bit messier than the resulting macros :-)
So I am pasting them too, just for your convenience:

#if defined(__arm__)
#define _PROGBITS "%progbits"
#else
#define _PROGBITS "@progbits"
#endif
#define _CUSTOM_SECTION(name, flags, align)                             \
        __asm__(                                                        \
                ".section       " __XSTRING(name)                       \
                        ",\"" __XSTRING(flags) "\"," _PROGBITS "\n"     \
                "\t.p2align " __XSTRING(align) "\n"                     \
                "\t.previous")
...
#define DPCPU_DEFINE(t, n)                                              \
        _CUSTOM_SECTION(set_pcpu, aw, CACHE_LINE_SHIFT);                \
        t DPCPU_NAME(n) __section("set_pcpu") __used


Not sure if _CUSTOM_SECTION is an overkill here or a useful/reusable thing.

The idea is to tie '.section' directive to DPCPU_DEFINE macro, so that [empty]
set_pcpu section is not created by merely including pcpu.h.

Multiple DPCPU_DEFINE instances would cause multiple '.section' directives for
set_pcpu, but that doesn't cause any problem.
Here's an example of how this case looks in gcc-generated assembly (with two
DPCPU_DEFINE instances):

#APP
        .section        set_pcpu,"aw",@progbits
        .p2align 7
        .previous
        .section        set_pcpu,"aw",@progbits
        .p2align 7
        .previous
...
#NO_APP
...
.globl pcpu_entry_dpcpu_nvram1
        .section        set_pcpu,"aw",@progbits
        .align 8
        .type   pcpu_entry_dpcpu_nvram1, @object
        .size   pcpu_entry_dpcpu_nvram1, 8
pcpu_entry_dpcpu_nvram1:
        .zero   8
.globl pcpu_entry_dpcpu_nvram2
        .align 8
        .type   pcpu_entry_dpcpu_nvram2, @object
        .size   pcpu_entry_dpcpu_nvram2, 8
pcpu_entry_dpcpu_nvram2:
        .zero   8
        .data
...

Here's objdump of the resulting module:
objdump -x -w nvram.ko | fgrep set_pcpu
  5 set_pcpu      00000010  0000000000000000  0000000000000000  00000380  2**7
CONTENTS, ALLOC, LOAD, DATA
0000000000000000 l     O set_pcpu       0000000000000008 pcpu_entry_dpcpu_nvram1
0000000000000008 l     O set_pcpu       0000000000000008 pcpu_entry_dpcpu_nvram2
0000000000000000 l    d  set_pcpu       0000000000000000

Looks good to me.

-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C343C68.8010302>