jasoncc.github.io

Random Signals on Some Low-level Stuff.

View on GitHub

Kernel and Modules Build

About init/main.o

init/main.o includes a file path which is helpful when extracting kernel build information from vmlinuz, vmlinux, or main.o.

In fact, the file path is added by the C preprocessor, CPP, while replacing the macro __FILE__. In init/main.c, start_kernel() invokes WARN(). WARN() invokes __WARN_printf(), which invokes warn_slowpath_fmt() and passes file path __FILE__. Also, BUG() is replaced by a code snippet including a file path in case of CONFIG_DEBUG_BUGVERBOSE was set.

//...
#define __WARN_printf(arg...)   warn_slowpath_fmt(__FILE__, __LINE__, arg)
//...
#ifndef WARN
#define WARN(condition, format...) ({       \
	int __ret_warn_on = !!(condition);  \
	if (unlikely(__ret_warn_on))        \
		__WARN_printf(format);      \
	unlikely(__ret_warn_on);            \
})
#endif

It can be figured out by getting assembler output. (like the following on Fedora 26)

gcc -Wp,-MD,init/.main.o.d  -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/7/include \
-I/auto/homeX/caij9/src/repos/kernel/linux-stable/arch/x86/include \
-Iarch/x86/include/generated/uapi -Iarch/x86/include/generated \
-I/auto/homeX/caij9/src/repos/kernel/linux-stable/include -Iinclude \
-I/auto/homeX/caij9/src/repos/kernel/linux-stable/arch/x86/include/uapi \
-Iarch/x86/include/generated/uapi \
-I/auto/homeX/caij9/src/repos/kernel/linux-stable/include/uapi -Iinclude/generated/uapi \
-include /auto/homeX/caij9/src/repos/kernel/linux-stable/include/linux/kconfig.h \
-I/auto/homeX/caij9/src/repos/kernel/linux-stable/init -Iinit -D__KERNEL__ -Wall -Wundef \
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE \
-mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 \
-mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone \
-mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args \
-DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 \
-DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 \
-DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe \
-Wno-sign-compare -fno-asynchronous-unwind-tables -fno-delete-null-pointer-checks \
-Wno-maybe-uninitialized -Wno-frame-address -Wno-format-truncation -Wno-format-overflow \
-Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 \
-DCC_HAVE_ASM_GOTO -Wframe-larger-than=2048 -fno-stack-protector \
-Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer \
-fno-optimize-sibling-calls -fno-var-tracking-assignments -g -Wdeclaration-after-statement \
-Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int \
-Werror=strict-prototypes -Werror=date-time \
-D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(main)" \
-D"KBUILD_MODNAME=KBUILD_STR(main)" -Wa,-aslh \
-c -o init/main.o init/main.c > <PATH_TO_OUTPUT>.s

-Wa: Pass option to the assembler.

-aslh: Ask assembler to include assembly code.

In this case, the string of the file path is allocated in section “.rodata.str1.8”.

177                 .section .rodata.str1.8    <= section
178 001f 00         .align 8
179                .LC3:
180 0020 2F617574   .string "/auto/homeX/caij9/src/repos/kernel/builds/linux-4.4.y/jason_test/main.c"                <== string at offset 20h
180      6F2F686F
180      6D65322F
180      6361696A
180      392F7372
... ...
680 064d E8000000   call perf_event_init
680      00
681
682                .linefile 807"/auto/homeX/caij9/src/repos/kernel/linux-stable/arch/x86/include/asm/paravirt.h"1
695
696 0659 0FBAE009   btl $9,%eax
697 065d 7318       jnc .L113
698 065f 48C7C200   movq $.LC13,%rdx
698      000000
699 0666 BE550200   movl $597,%esi
699      00
700 066b 48C7C700   movq $.LC3,%rdi     <== passed as the 1st argument.
700      000000
701 0672 E8000000   call warn_slowpath_fmt
701      00
... ...

Note that the default options compiling init/main.o include option -g which also leads to generate a string of the file path in section .debug_str.

back