#!/bin/sh # # link vmlinux # # vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and # $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories # in the kernel tree, others are specified in arch/$(ARCH)/Makefile. # Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first. # # vmlinux # ^ # | # +-< $(KBUILD_VMLINUX_INIT) # | +--< init/version.o + more # | # +--< $(KBUILD_VMLINUX_MAIN) # | +--< drivers/built-in.o mm/built-in.o + more # | # +-< ${kallsymso} (see description in KALLSYMS section) # # vmlinux version (uname -v) cannot be updated during normal # descending-into-subdirs phase since we do not yet know if we need to # update vmlinux. # Therefore this step is delayed until just before final link of vmlinux. # # System.map is generated to document addresses of all kernel symbols # Error out on error set -e # Nice output in kbuild format # Will be supressed by "make -s" proc info { if test $(quiet) != "silent_" { printf " %-7s %s\n" $(1) $(2) } } # Link of vmlinux.o used for section mismatch analysis # ${1} output file proc modpost_link { $(LD) $(LDFLAGS) -r -o $(1) $(KBUILD_VMLINUX_INIT) \ --start-group $(KBUILD_VMLINUX_MAIN) --end-group } # Link of vmlinux # ${1} - optional extra .o files # ${2} - output file proc vmlinux_link { var lds = ""$(objtree)/$(KBUILD_LDS)"" if test $(SRCARCH) != "um" { $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $(2) \ -T $(lds) $(KBUILD_VMLINUX_INIT) \ --start-group $(KBUILD_VMLINUX_MAIN) --end-group $(1) } else { $(CC) $(CFLAGS_vmlinux) -o $(2) \ -Wl,-T,$(lds) $(KBUILD_VMLINUX_INIT) \ -Wl,--start-group \ $(KBUILD_VMLINUX_MAIN) \ -Wl,--end-group \ -lutil -lrt -lpthread $(1) rm -f linux } } # Create ${2} .o file with all symbols from the ${1} object file proc kallsyms { info KSYM $(2) var kallsymopt = ''; if test -n $(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX) { kallsymopt := ""$(kallsymopt) --symbol-prefix=_"" } if test -n $(CONFIG_KALLSYMS_ALL) { kallsymopt := ""$(kallsymopt) --all-symbols"" } if test -n $(CONFIG_KALLSYMS_ABSOLUTE_PERCPU) { kallsymopt := ""$(kallsymopt) --absolute-percpu"" } if test -n $(CONFIG_KALLSYMS_BASE_RELATIVE) { kallsymopt := ""$(kallsymopt) --base-relative"" } var aflags = ""$(KBUILD_AFLAGS) $(KBUILD_AFLAGS_KERNEL) \ $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS)"" var afile = ""$[basename $(2) .o].S"" $(NM) -n $(1) | scripts/kallsyms $(kallsymopt) > $(afile) $(CC) $(aflags) -c -o $(2) $(afile) } # Create map file with all symbols from ${1} # See mksymap for additional details proc mksysmap { $(CONFIG_SHELL) "$(srctree)/scripts/mksysmap" $(1) $(2) } proc sortextable { $(objtree)/scripts/sortextable $(1) } # Delete output files in case of error proc cleanup { rm -f .old_version rm -f .tmp_System.map rm -f .tmp_kallsyms* rm -f .tmp_version rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux rm -f vmlinux.o } proc on_exit { if test $Status -ne 0 { cleanup } } trap on_exit EXIT proc on_signals { exit 1 } trap on_signals HUP INT QUIT TERM # # # Use "make V=1" to debug this script matchstr $(KBUILD_VERBOSE) { *1* { set -x } } if test $1 = "clean" { cleanup exit 0 } # We need access to CONFIG_ symbols matchstr $(KCONFIG_CONFIG) { */* { source "${KCONFIG_CONFIG}" } * { # Force using a file from the current directory source "./${KCONFIG_CONFIG}" } } #link vmlinux.o info LD vmlinux.o modpost_link vmlinux.o # modpost vmlinux.o to check for section mismatches $(MAKE) -f "$(srctree)/scripts/Makefile.modpost" vmlinux.o # Update version info GEN .version if test ! -r .version { rm -f .version; echo 1 >.version; } else { mv .version .old_version; expr 0$[cat .old_version] + 1 >.version; }; # final build of init/ $(MAKE) -f "$(srctree)/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="$(GCC_PLUGINS_CFLAGS)" global kallsymso := ''"" global kallsyms_vmlinux := ''"" if test -n $(CONFIG_KALLSYMS) { # kallsyms support # Generate section listing all symbols and add it into vmlinux # It's a three step process: # 1) Link .tmp_vmlinux1 so it has all symbols and sections, # but __kallsyms is empty. # Running kallsyms on that gives us .tmp_kallsyms1.o with # the right size # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of # the right size, but due to the added section, some # addresses have shifted. # From here, we generate a correct .tmp_kallsyms2.o # 2a) We may use an extra pass as this has been necessary to # woraround some alignment related bugs. # KALLSYMS_EXTRA_PASS=1 is used to trigger this. # 3) The correct ${kallsymso} is linked into the final vmlinux. # # a) Verify that the System.map from vmlinux matches the map from # ${kallsymso}. global kallsymso := '.tmp_kallsyms2.o' global kallsyms_vmlinux := '.tmp_vmlinux2' # step 1 vmlinux_link "" .tmp_vmlinux1 kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o # step 2 vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o # step 2a if test -n $(KALLSYMS_EXTRA_PASS) { global kallsymso := '.tmp_kallsyms3.o' global kallsyms_vmlinux := '.tmp_vmlinux3' vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o } } info LD vmlinux vmlinux_link $(kallsymso) vmlinux if test -n $(CONFIG_BUILDTIME_EXTABLE_SORT) { info SORTEX vmlinux sortextable vmlinux } info SYSMAP System.map mksysmap vmlinux System.map # step a (see comment above) if test -n $(CONFIG_KALLSYMS) { mksysmap $(kallsyms_vmlinux) .tmp_System.map if ! cmp -s System.map .tmp_System.map { echo >&2 Inconsistent kallsyms data> !2 Inconsistent kallsyms data echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround> !2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround exit 1 } } # We made a new kernel - delete old version file rm -f .old_version (CommandList children: [ (C {(set)} {(-e)}) (FuncDef name: info body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ (${ VSub_Name quiet))} {(KW_Bang "!") (Lit_Other "=")} {(DQ (silent_))} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(printf)} {(DQ (" %-7s %s") (EscapedLiteralPart token:))} {(${ VSub_Number 1)} {(${ VSub_Number 2)} ) ] spids: [-1 120] ) ] spids: [-1 139] ) ] spids: [97] ) spids: [93 96] ) (FuncDef name: modpost_link body: (BraceGroup children: [ (C {(${ VSub_Name LD)} {(${ VSub_Name LDFLAGS)} {(-r)} {(-o)} {(${ VSub_Number 1)} {(${ VSub_Name KBUILD_VMLINUX_INIT)} {(--start-group)} {(${ VSub_Name KBUILD_VMLINUX_MAIN)} {(--end-group)} ) ] spids: [154] ) spids: [150 153] ) (FuncDef name: vmlinux_link body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:lds) op: Equal rhs: {(DQ (${ VSub_Name objtree) (/) (${ VSub_Name KBUILD_LDS))} spids: [208] ) ] spids: [206] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ (${ VSub_Name SRCARCH))} {(KW_Bang "!") (Lit_Other "=")} {(DQ (um))} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(${ VSub_Name LD)} {(${ VSub_Name LDFLAGS)} {(${ VSub_Name LDFLAGS_vmlinux)} {(-o)} {(${ VSub_Number 2)} {(-T)} {(${ VSub_Name lds)} {(${ VSub_Name KBUILD_VMLINUX_INIT)} {(--start-group)} {(${ VSub_Name KBUILD_VMLINUX_MAIN)} {(--end-group)} {(${ VSub_Number 1)} ) ] spids: [-1 241] ) ] else_action: [ (C {(${ VSub_Name CC)} {(${ VSub_Name CFLAGS_vmlinux)} {(-o)} {(${ VSub_Number 2)} {(-Wl) (Lit_Comma ",") (-T) (Lit_Comma ",") (${ VSub_Name lds)} {(${ VSub_Name KBUILD_VMLINUX_INIT)} {(-Wl) (Lit_Comma ",") (--start-group)} {(${ VSub_Name KBUILD_VMLINUX_MAIN)} {(-Wl) (Lit_Comma ",") (--end-group)} {(-lutil)} {(-lrt)} {(-lpthread)} {(${ VSub_Number 1)} ) (C {(rm)} {(-f)} {(linux)}) ] spids: [289 358] ) ] spids: [203] ) spids: [199 202] ) (FuncDef name: kallsyms body: (BraceGroup children: [ (C {(info)} {(KSYM)} {(${ VSub_Number 2)}) (Sentence child: (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:kallsymopt) op:Equal spids:[385])] spids: [383] ) terminator: ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymopt) op: Equal rhs: {(DQ (${ VSub_Name kallsymopt) (" --symbol-prefix=_"))} spids: [408] ) ] spids: [408] ) ] spids: [-1 405] ) ] spids: [-1 417] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_KALLSYMS_ALL))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymopt) op: Equal rhs: {(DQ (${ VSub_Name kallsymopt) (" --all-symbols"))} spids: [439] ) ] spids: [439] ) ] spids: [-1 436] ) ] spids: [-1 448] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_KALLSYMS_ABSOLUTE_PERCPU))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymopt) op: Equal rhs: {(DQ (${ VSub_Name kallsymopt) (" --absolute-percpu"))} spids: [470] ) ] spids: [470] ) ] spids: [-1 467] ) ] spids: [-1 479] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_KALLSYMS_BASE_RELATIVE))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymopt) op: Equal rhs: {(DQ (${ VSub_Name kallsymopt) (" --base-relative"))} spids: [501] ) ] spids: [501] ) ] spids: [-1 498] ) ] spids: [-1 510] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:aflags) op: Equal rhs: { (DQ (${ VSub_Name KBUILD_AFLAGS) (" ") (${ VSub_Name KBUILD_AFLAGS_KERNEL) (" ") ("\t\t ") (${ VSub_Name NOSTDINC_FLAGS) (" ") (${ VSub_Name LINUXINCLUDE) (" ") (${ VSub_Name KBUILD_CPPFLAGS) ) } spids: [516] ) ] spids: [514] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:afile) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(basename)} {(${ VSub_Number 2)} {(.o)})] ) left_token: spids: [547 555] ) (.S) ) } spids: [545] ) ] spids: [543] ) (Pipeline children: [ (C {(${ VSub_Name NM)} {(-n)} {(${ VSub_Number 1)}) (SimpleCommand words: [{(scripts/kallsyms)} {(${ VSub_Name kallsymopt)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(${ VSub_Name afile)} spids: [579] ) ] ) ] negated: False ) (C {(${ VSub_Name CC)} {(${ VSub_Name aflags)} {(-c)} {(-o)} {(${ VSub_Number 2)} {(${ VSub_Name afile)} ) ] spids: [371] ) spids: [367 370] ) (FuncDef name: mksysmap body: (BraceGroup children: [ (C {(${ VSub_Name CONFIG_SHELL)} {(DQ (${ VSub_Name srctree) (/scripts/mksysmap))} {(${ VSub_Number 1)} {(${ VSub_Number 2)} ) ] spids: [619] ) spids: [615 618] ) (FuncDef name: sortextable body: (BraceGroup children: [(C {(${ VSub_Name objtree) (/scripts/sortextable)} {(${ VSub_Number 1)})] spids: [648] ) spids: [644 647] ) (FuncDef name: cleanup body: (BraceGroup children: [ (C {(rm)} {(-f)} {(.old_version)}) (C {(rm)} {(-f)} {(.tmp_System.map)}) (C {(rm)} {(-f)} {(.tmp_kallsyms) (Lit_Other "*")}) (C {(rm)} {(-f)} {(.tmp_version)}) (C {(rm)} {(-f)} {(.tmp_vmlinux) (Lit_Other "*")}) (C {(rm)} {(-f)} {(System.map)}) (C {(rm)} {(-f)} {(vmlinux)}) (C {(rm)} {(-f)} {(vmlinux.o)}) ] spids: [670] ) spids: [666 669] ) (FuncDef name: on_exit body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {($ VSub_QMark "$?")} {(-ne)} {(0)} {(Lit_Other "]")}) terminator: ) ] action: [(C {(cleanup)})] spids: [-1 753] ) ] spids: [-1 759] ) ] spids: [737] ) spids: [733 736] ) (C {(trap)} {(on_exit)} {(EXIT)}) (FuncDef name: on_signals body: (BraceGroup children:[(C {(exit)} {(1)})] spids:[774]) spids: [770 773] ) (C {(trap)} {(on_signals)} {(HUP)} {(INT)} {(QUIT)} {(TERM)}) (Case to_match: {(DQ (${ VSub_Name KBUILD_VERBOSE))} arms: [ (case_arm pat_list: [{(Lit_Other "*") (1) (Lit_Other "*")}] action: [(C {(set)} {(-x)})] spids: [815 818 826 -1] ) ] spids: [805 813 828] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Number "$1"))} {(Lit_Other "=")} {(DQ (clean))} {(Lit_Other "]")} ) terminator: ) ] action: [(C {(cleanup)}) (C {(exit)} {(0)})] spids: [-1 848] ) ] spids: [-1 858] ) (Case to_match: {(DQ (${ VSub_Name KCONFIG_CONFIG))} arms: [ (case_arm pat_list: [{(Lit_Other "*") (/) (Lit_Other "*")}] action: [(C {(.)} {(DQ (${ VSub_Name KCONFIG_CONFIG))})] spids: [874 877 889 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [(C {(.)} {(DQ (./) (${ VSub_Name KCONFIG_CONFIG))})] spids: [891 892 -1 908] ) ] spids: [864 872 908] ) (C {(info)} {(LD)} {(vmlinux.o)}) (C {(modpost_link)} {(vmlinux.o)}) (C {(${ VSub_Name MAKE)} {(-f)} {(DQ (${ VSub_Name srctree) (/scripts/Makefile.modpost))} {(vmlinux.o)} ) (C {(info)} {(GEN)} {(.version)}) (Sentence child: (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(KW_Bang "!")} {(-r)} {(.version)} {(Lit_Other "]")}) terminator: ) ] action: [ (Sentence child: (C {(rm)} {(-f)} {(.version)}) terminator: ) (Sentence child: (SimpleCommand words: [{(echo)} {(1)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(.version)} spids:[981])] ) terminator: ) ] spids: [-1 966] ) ] else_action: [ (Sentence child: (C {(mv)} {(.version)} {(.old_version)}) terminator: ) (Sentence child: (SimpleCommand words: [ {(expr)} {(0) (CommandSubPart command_list: (CommandList children:[(C {(cat)} {(.old_version)})]) left_token: spids: [999 1003] ) } {(Lit_Other "+")} {(1)} ] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(.version)} spids:[1009])] ) terminator: ) ] spids: [985 1013] ) terminator: ) (C {(${ VSub_Name MAKE)} {(-f)} {(DQ (${ VSub_Name srctree) (/scripts/Makefile.build))} {(Lit_VarLike "obj=") (init)} {(Lit_VarLike "GCC_PLUGINS_CFLAGS=") (DQ (${ VSub_Name GCC_PLUGINS_CFLAGS))} ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:kallsymso) op:Equal rhs:{(DQ )} spids:[1044])] spids: [1044] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:kallsyms_vmlinux) op:Equal rhs:{(DQ )} spids:[1048])] spids: [1048] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_KALLSYMS))} {(Lit_Other "]")}) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymso) op: Equal rhs: {(.tmp_kallsyms2.o)} spids: [1144] ) ] spids: [1144] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsyms_vmlinux) op: Equal rhs: {(.tmp_vmlinux2)} spids: [1148] ) ] spids: [1148] ) (C {(vmlinux_link)} {(DQ )} {(.tmp_vmlinux1)}) (C {(kallsyms)} {(.tmp_vmlinux1)} {(.tmp_kallsyms1.o)}) (C {(vmlinux_link)} {(.tmp_kallsyms1.o)} {(.tmp_vmlinux2)}) (C {(kallsyms)} {(.tmp_vmlinux2)} {(.tmp_kallsyms2.o)}) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name KALLSYMS_EXTRA_PASS))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsymso) op: Equal rhs: {(.tmp_kallsyms3.o)} spids: [1214] ) ] spids: [1214] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:kallsyms_vmlinux) op: Equal rhs: {(.tmp_vmlinux3)} spids: [1218] ) ] spids: [1218] ) (C {(vmlinux_link)} {(.tmp_kallsyms2.o)} {(.tmp_vmlinux3)}) (C {(kallsyms)} {(.tmp_vmlinux3)} {(.tmp_kallsyms3.o)}) ] spids: [-1 1211] ) ] spids: [-1 1238] ) ] spids: [-1 1067] ) ] spids: [-1 1240] ) (C {(info)} {(LD)} {(vmlinux)}) (C {(vmlinux_link)} {(DQ (${ VSub_Name kallsymso))} {(vmlinux)}) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_BUILDTIME_EXTABLE_SORT))} {(Lit_Other "]")} ) terminator: ) ] action: [(C {(info)} {(SORTEX)} {(vmlinux)}) (C {(sortextable)} {(vmlinux)})] spids: [-1 1275] ) ] spids: [-1 1289] ) (C {(info)} {(SYSMAP)} {(System.map)}) (C {(mksysmap)} {(vmlinux)} {(System.map)}) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name CONFIG_KALLSYMS))} {(Lit_Other "]")}) terminator: ) ] action: [ (C {(mksysmap)} {(${ VSub_Name kallsyms_vmlinux)} {(.tmp_System.map)}) (If arms: [ (if_arm cond: [ (Sentence child: (Pipeline children: [(C {(cmp)} {(-s)} {(System.map)} {(.tmp_System.map)})] negated: True ) terminator: ) ] action: [ (SimpleCommand words: [{(echo)} {(Inconsistent)} {(kallsyms)} {(data)}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[1354])] ) (SimpleCommand words: [ {(echo)} {(Try)} {(DQ ("make KALLSYMS_EXTRA_PASS=1"))} {(as)} {(a)} {(workaround)} ] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[1366])] ) (C {(exit)} {(1)}) ] spids: [-1 1349] ) ] spids: [-1 1387] ) ] spids: [-1 1323] ) ] spids: [-1 1389] ) (C {(rm)} {(-f)} {(.old_version)}) ] )