Can GNU use prototypes of the structure and functions of a process in an assembly file (.s)?

As we know, assembly (.S) files will receive preprocessing before assembly, but I found that after preprocessing, the resulting assembly files may have prototypes of the structure / function. How will gnu work with these prototypes? Just ignored it?

For example, the following command:

gcc -E -o tmp.result arch / x86 / boot / copy.S -Iinclude / -Iarch / x86 / include /

and the resulting build file (tmp.result):

# 1 "arch/x86/boot/copy.S" # 1 "<built-in>" # 1 "<command-line>" # 1 "arch/x86/boot/copy.S" # 11 "arch/x86/boot/copy.S" # 1 "include/linux/linkage.h" 1 # 1 "include/linux/compiler.h" 1 # 5 "include/linux/linkage.h" 2 # 1 "include/linux/stringify.h" 1 # 6 "include/linux/linkage.h" 2 # 1 "include/linux/export.h" 1 # 26 "include/linux/export.h" struct kernel_symbol { unsigned long value; const char *name; }; # 7 "include/linux/linkage.h" 2 # 1 "arch/x86/include/asm/linkage.h" 1 # 8 "include/linux/linkage.h" 2 # 12 "arch/x86/boot/copy.S" 2 .code16 .text GLOBAL(memcpy) pushw %si pushw %di movw %ax, %di movw %dx, %si pushw %cx shrw $2, %cx rep; movsl popw %cx andw $3, %cx rep; movsb popw %di popw %si retl ENDPROC(memcpy) 

but when trying to compile this file:

like -o tmp.o tmp.result

produces the following error:

 include/linux/export.h: Assembler messages: include/linux/export.h:26: Error: no such instruction: `struct kernel_symbol' include/linux/export.h:27: Error: junk at end of line, first unrecognized character is `{' include/linux/export.h:28: Error: no such instruction: `unsigned long value' include/linux/export.h:29: Error: no such instruction: `const char *name' include/linux/export.h:30: Error: junk at end of line, first unrecognized character is `}' arch/x86/boot/copy.S:20: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:34: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:36: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:49: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:51: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:58: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:60: Error: invalid character '(' in mnemonic arch/x86/boot/copy.S:67: Error: invalid character '(' in mnemonic 

It seems that assembler cannot deal with the structure in tmp.result. How does Linux (.S) source code go through the assembly?

+5
source share
1 answer

as cannot handle struct and function prototypes - they are only for the C compiler and are mistakenly pulled into your preprocessing. In facts, if you look at the header that the definition of struct provides, you will see :

 #ifndef __ASSEMBLY__ struct kernel_symbol { unsigned long value; const char *name; }; 

So, it is believed that the header, which is considered to be included both from the assembly and from C, but you have not defined __ASSEMBLY__ to tell it that you include it in the assembly file.

Interestingly, gcc has a built-in __ASSEMBLER__ predefined macro to distinguish between inclusion in an assembly file or C file, but it seems that the kernel does not use it for historical reasons , relying instead on manually __ASSEMBLY__ when preassembling assembly files.

In short: in order to get the correct output from the preprocessor, you should do something like

 gcc -E -D__ASSEMBLY__ -o tmp.result arch/x86/boot/copy.S -Iinclude/ -Iarch/x86/include/ 

(disclaimer: I am not completely familiar with the process of building the kernel, in the above line there may be other problems with the paths included, or maybe the correct way would be to call cpp instead of gcc or something else - I don’t know)

+3
source

All Articles