aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@kernel.org>2016-06-03 14:01:13 -0700
committerLuis R. Rodriguez <mcgrof@kernel.org>2016-06-03 17:03:55 -0700
commitcb570919776e36d6571427e3a31ad7d13b2a6b75 (patch)
treeac66f0aecfeed1436aea4b2fef6cf60f35aefbcd
parentf28fa79d5ed863b961b99a790192cff083600b9e (diff)
downloadlinker-tables-20160603-dev-v3.tar.gz
sections.h: add generic section declaration20160603-dev-v3
Quite a few generalizations between section tables and ranges: o Replace the *SECTION_TBL*() macros with generic *SECTION_TYPE*() macros. This lets us be more agnostic between the linker tables and section ranges and also lets us add other possible section types in the future in a more generic fashion. o Generalize the arbitrary order of "any" as SECTION_ORDER_ANY, any special section type not needing order can use this. The section ranges are an example. o Keep sort for section ranges on vmlinux.lds.S, otherwise the start and end declaration will not work. By keeping the sort and using "any" for in between items we're able to extend section ranges without modifying the linker script. o Rename the special section for tables from .tbl to .tables o Use the special section for ranges as .ranges. o Require SECTION_TYPE_* name declarations for each new type of special section type. We start off with two: - SECTION_TYPE_RANGES this is for .tables - SECTION_TYPE_TABLES this is for .ranges These are postfixes for each special section type. By using these we can easily modify the special section postfix in header files in one place. o Due to the very explicit divide between section ranges and section tables we now need a separate entry for each in vmlinux.lds.S but we accept this for now as it helps with semantics in separation. Technically we could also just shove both section ranges and section tables under its own special section prefix, perhaps .types and then we can move both section ranges and section tables underneath, so we'd have, for example for .text: .text .text.types.* .text.types.tables .text.types.ranges While this saves us the need to add a new special section type under vmlinux.lds.S we may loose the ability to sort tables.* and/or we are forcing a sort for *all* special section types, thereby slowing down link time. o Since we modified tons of section stufff, we needed to fix the 'make clean' as otherwise we are left with old objects using the old .tbl section names. Tons of bike shedding opportunities here! We let the fun bike shedding discussions happen openly with the community. Run time tested: Initializing x86 bare metal world x86-init: Number of init entries: 7 Initializing kasan ... Early init for Kasan... Completed initializing kasan ! Initializing memory ... Completed initializing memory ! Initializing kprobes ... == OK: test_kprobe_0001 within range! == OK: test_kprobe_0002 not in range as expected! Completed initializing kprobes ! Initializing pci ... PCI fixup size: 1 Demo: Using LINKTABLE_FOR_EACH foo_fixup Demo: Using LINKTABLE_RUN_ALL foo_fixup Completed initializing pci ! Initializing beta ... Completed initializing beta ! Initializing alpha ... Completed initializing alpha ! Booting bare metal Calling start_kernel()... ACME: Initializing ... ACME: Finished init ... ! ACME: Running scheduled work Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
-rw-r--r--Makefile1
-rw-r--r--arch/x86/kernel/vmlinux.lds.S26
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/ranges.h23
-rw-r--r--include/linux/sections.h25
-rw-r--r--include/linux/tables.h12
6 files changed, 63 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index d41753d..b69ba24 100644
--- a/Makefile
+++ b/Makefile
@@ -62,4 +62,5 @@ main: $(OBJS)
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^
clean:
+ find ./ -name \*.o | xargs rm -f
rm -f main parse-bzimage *.o arch/x86/kernel/vmlinux.lds
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index e7378cc..a74b86c 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
notice and this notice are preserved. */
#include <linux/sections.h>
+#include <linux/tables.h>
+#include <linux/ranges.h>
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
@@ -61,10 +63,19 @@ SECTIONS
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
+ *(SORT(SECTION_RANGE_ALL(SECTION_TEXT)))
*(SORT(SECTION_TBL_ALL(SECTION_TEXT)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_INIT)))
*(SORT(SECTION_TBL_ALL(SECTION_INIT)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_INIT_CALL)))
*(SORT(SECTION_TBL_ALL(SECTION_INIT_CALL)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_EXIT)))
*(SORT(SECTION_TBL_ALL(SECTION_EXIT)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_EXIT_CALL)))
*(SORT(SECTION_TBL_ALL(SECTION_EXIT_CALL)))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
@@ -81,8 +92,14 @@ SECTIONS
{
*(.rodata)
*(SORT(.rodata.*))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_RODATA)))
*(SORT(SECTION_TBL_ALL(SECTION_RODATA)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_INIT_RODATA)))
*(SORT(SECTION_TBL_ALL(SECTION_INIT_RODATA)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_REF_RODATA)))
*(SORT(SECTION_TBL_ALL(SECTION_REF_RODATA)))
*(.gnu.linkonce.r.*)
}
@@ -162,10 +179,19 @@ SECTIONS
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_DATA)))
*(SORT(SECTION_TBL_ALL(SECTION_DATA)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_INIT_DATA)))
*(SORT(SECTION_TBL_ALL(SECTION_INIT_DATA)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_REF_DATA)))
*(SORT(SECTION_TBL_ALL(SECTION_REF_DATA)))
+
+ *(SORT(SECTION_RANGE_ALL(SECTION_EXIT_DATA)))
*(SORT(SECTION_TBL_ALL(SECTION_EXIT_DATA)))
+
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
diff --git a/include/linux/init.h b/include/linux/init.h
index 52566c5..14c6422 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -31,7 +31,7 @@ DECLARE_LINKTABLE_DATA(exitcall_t, exit_calls);
#define __initcall(fn) device_initcall(fn)
#define __exitcall(fn) \
- static LINKTABLE_INIT_DATA(exit_calls, any) \
+ static LINKTABLE_INIT_DATA(exit_calls, SECTION_ORDER_ANY) \
__exitcall_##fn = fn;
#endif
diff --git a/include/linux/ranges.h b/include/linux/ranges.h
index 549ae69..9e1f766 100644
--- a/include/linux/ranges.h
+++ b/include/linux/ranges.h
@@ -3,6 +3,13 @@
#include <linux/sections.h>
+#define SECTION_TYPE_RANGES ranges
+
+#ifndef __ASSEMBLY__
+
+#define SECTION_RANGE(section, name, level) \
+ SECTION_TYPE(section, SECTION_TYPE_RANGES, name, level)
+
/* Linker tables shalt not use this */
#define SECTION_ADDR_IN_RANGE(name, addr) \
(addr >= (unsigned long) LINUX_SECTION_START(name) && \
@@ -16,13 +23,13 @@
__attribute__((used, \
weak, \
__aligned__(LINUX_SECTION_ALIGN_FUNC), \
- section(SECTION_TBL(__section, name, ))))
+ section(SECTION_RANGE(__section, name, ))))
#define SECTION_RANGE_END(name, __section) \
const __typeof__(name[0]) \
__attribute__((used, \
__aligned__(LINUX_SECTION_ALIGN_FUNC), \
- section(SECTION_TBL(__section, name, ~))))
+ section(SECTION_RANGE(__section, name, ~))))
#define DEFINE_SECTION_RANGE(name, section) \
DECLARE_LINUX_SECTION_RO(char, name); \
@@ -31,13 +38,13 @@
SECTION_RANGE_END(name, section) VMLINUX_SYMBOL(name##__end)[0] = {};\
LTO_REFERENCE_INITCALL(name##__end);
-/*
- * We use the special "any" order, as section ranges need not care
- * about that.
- */
-#define SECTION_RANGE_ORDER any
#define __LINUX_SECTION(section, name) \
__attribute__((__aligned__(LINUX_SECTION_ALIGN_FUNC), \
- __section__(SECTION_TBL(section, name, SECTION_RANGE_ORDER))))
+ __section__(SECTION_RANGE(section, name, SECTION_ORDER_ANY))))
+
+#endif /* __ASSEMBLY__ */
+
+#define SECTION_RANGE_ALL(section) \
+ SECTION_TYPE_ALL(section,SECTION_TYPE_RANGES)
#endif /* _LINUX_RANGES_H */
diff --git a/include/linux/sections.h b/include/linux/sections.h
index ffcc504..2806bc7 100644
--- a/include/linux/sections.h
+++ b/include/linux/sections.h
@@ -62,28 +62,19 @@
#define DECLARE_LINUX_SECTION_RO(type, name) \
extern const type name[], name##__end[];
-#define __SECTION_TBL(section, name, level) \
- #section ".tbl." #name "." #level
+#define __SECTION_TYPE(section, type, name, level) \
+ #section "." #type "." #name "." #level
-#define SECTION_TBL(section, name, level) \
- __SECTION_TBL(section, name, level)
+#define SECTION_TYPE(section, type, name, level) \
+ __SECTION_TYPE(section, type, name, level)
+
+#define SECTION_ORDER_ANY any
#endif /* __ASSEMBLY__ */
/*
* This section is for use on linker scripts and helpers
*/
-
-/*
- *
- * Without this you end up with the section macro
- * as part of the name
- */
-#define ___SECTION_TBL(section, name) \
- section##.tbl.##name
-
-/* glob to capture all linker table uses for this section */
-#define SECTION_TBL_ALL(section) \
- ___SECTION_TBL(section,*)
-
+#define SECTION_TYPE_ALL(section, type) \
+ section##.##type.*
#endif /* _LINUX_SECTIONS_H */
diff --git a/include/linux/tables.h b/include/linux/tables.h
index 909b88c..1f1c91c 100644
--- a/include/linux/tables.h
+++ b/include/linux/tables.h
@@ -3,6 +3,13 @@
#include <linux/sections.h>
+#define SECTION_TYPE_TABLES tables
+
+#ifndef __ASSEMBLY__
+
+#define SECTION_TBL(section, name, level) \
+ SECTION_TYPE(section, SECTION_TYPE_TABLES, name, level)
+
/*
* Linux linker tables
*
@@ -152,4 +159,9 @@ do { \
err; \
})
+#endif /* __ASSEMBLY__ */
+
+#define SECTION_TBL_ALL(section) \
+ SECTION_TYPE_ALL(section,SECTION_TYPE_TABLES)
+
#endif /* _LINUX_LINKER_TABLES_H */