elf obj load: skip zero-sized sections early
Andriy Gapon
avg at freebsd.org
Wed Jul 7 08:35:59 UTC 2010
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", at progbits
.p2align 7
.previous
.section set_pcpu,"aw", at progbits
.p2align 7
.previous
...
#NO_APP
...
.globl pcpu_entry_dpcpu_nvram1
.section set_pcpu,"aw", at 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
More information about the freebsd-hackers
mailing list