Merge branch 'x86-build-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 build bits from Peter Anvin:
"Various build-related minor bits.

Most of this is work by David Woodhouse to be able to compile the
early boot code with clang/llvm; we have also managed to push an
actual -m16 option into gcc 4.9 so this makes us use that option if
available instead of hacking it.

The balance is a patch from Michael Davidson to the relocs program to
help manual debugging.

None of these should change the actual compiled binary with currently
released compilers"

* 'x86-build-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, build: Build 16-bit code with -m16 where possible
x86, boot: Fix word-size assumptions in has_eflag() inline asm
x86, boot: Use __attribute__((used)) to ensure videocard structs are emitted
x86: Remove duplication of 16-bit CFLAGS
x86, relocs: Add manual debug mode

+91 -43
+22
arch/x86/Makefile
··· 11 KBUILD_DEFCONFIG := $(ARCH)_defconfig 12 endif 13 14 # BITS is used as extension for files which are available in a 32 bit 15 # and a 64 bit version to simplify shared Makefiles. 16 # e.g.: obj-y += foo_$(BITS).o
··· 11 KBUILD_DEFCONFIG := $(ARCH)_defconfig 12 endif 13 14 + # How to compile the 16-bit code. Note we always compile for -march=i386; 15 + # that way we can complain to the user if the CPU is insufficient. 16 + # 17 + # The -m16 option is supported by GCC >= 4.9 and clang >= 3.5. For 18 + # older versions of GCC, we need to play evil and unreliable tricks to 19 + # attempt to ensure that our asm(".code16gcc") is first in the asm 20 + # output. 21 + CODE16GCC_CFLAGS := -m32 -include $(srctree)/arch/x86/boot/code16gcc.h \ 22 + $(call cc-option, -fno-toplevel-reorder,\ 23 + $(call cc-option, -fno-unit-at-a-time)) 24 + M16_CFLAGS := $(call cc-option, -m16, $(CODE16GCC_CFLAGS)) 25 + 26 + REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \ 27 + -DDISABLE_BRANCH_PROFILING \ 28 + -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ 29 + -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ 30 + -mno-mmx -mno-sse \ 31 + $(call cc-option, -ffreestanding) \ 32 + $(call cc-option, -fno-stack-protector) \ 33 + $(call cc-option, -mpreferred-stack-boundary=2) 34 + export REALMODE_CFLAGS 35 + 36 # BITS is used as extension for files which are available in a 32 bit 37 # and a 64 bit version to simplify shared Makefiles. 38 # e.g.: obj-y += foo_$(BITS).o
+1 -14
arch/x86/boot/Makefile
··· 51 52 # --------------------------------------------------------------------------- 53 54 - # How to compile the 16-bit code. Note we always compile for -march=i386, 55 - # that way we can complain to the user if the CPU is insufficient. 56 - KBUILD_CFLAGS := $(USERINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ \ 57 - -DDISABLE_BRANCH_PROFILING \ 58 - -Wall -Wstrict-prototypes \ 59 - -march=i386 -mregparm=3 \ 60 - -include $(srctree)/$(src)/code16gcc.h \ 61 - -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ 62 - -mno-mmx -mno-sse \ 63 - $(call cc-option, -ffreestanding) \ 64 - $(call cc-option, -fno-toplevel-reorder,\ 65 - $(call cc-option, -fno-unit-at-a-time)) \ 66 - $(call cc-option, -fno-stack-protector) \ 67 - $(call cc-option, -mpreferred-stack-boundary=2) 68 KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 69 GCOV_PROFILE := n 70
··· 51 52 # --------------------------------------------------------------------------- 53 54 + KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP 55 KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 56 GCOV_PROFILE := n 57
+20 -5
arch/x86/boot/cpuflags.c
··· 28 return fsw == 0 && (fcw & 0x103f) == 0x003f; 29 } 30 31 int has_eflag(unsigned long mask) 32 { 33 unsigned long f0, f1; 34 35 - asm volatile("pushf \n\t" 36 - "pushf \n\t" 37 "pop %0 \n\t" 38 "mov %0,%1 \n\t" 39 "xor %2,%1 \n\t" 40 "push %1 \n\t" 41 - "popf \n\t" 42 - "pushf \n\t" 43 "pop %1 \n\t" 44 - "popf" 45 : "=&r" (f0), "=&r" (f1) 46 : "ri" (mask)); 47
··· 28 return fsw == 0 && (fcw & 0x103f) == 0x003f; 29 } 30 31 + /* 32 + * For building the 16-bit code we want to explicitly specify 32-bit 33 + * push/pop operations, rather than just saying 'pushf' or 'popf' and 34 + * letting the compiler choose. But this is also included from the 35 + * compressed/ directory where it may be 64-bit code, and thus needs 36 + * to be 'pushfq' or 'popfq' in that case. 37 + */ 38 + #ifdef __x86_64__ 39 + #define PUSHF "pushfq" 40 + #define POPF "popfq" 41 + #else 42 + #define PUSHF "pushfl" 43 + #define POPF "popfl" 44 + #endif 45 + 46 int has_eflag(unsigned long mask) 47 { 48 unsigned long f0, f1; 49 50 + asm volatile(PUSHF " \n\t" 51 + PUSHF " \n\t" 52 "pop %0 \n\t" 53 "mov %0,%1 \n\t" 54 "xor %2,%1 \n\t" 55 "push %1 \n\t" 56 + POPF " \n\t" 57 + PUSHF " \n\t" 58 "pop %1 \n\t" 59 + POPF 60 : "=&r" (f0), "=&r" (f1) 61 : "ri" (mask)); 62
+1 -1
arch/x86/boot/video.h
··· 80 u16 xmode_n; /* Size of unprobed mode range */ 81 }; 82 83 - #define __videocard struct card_info __attribute__((section(".videocards"))) 84 extern struct card_info video_cards[], video_cards_end[]; 85 86 int mode_defined(u16 mode); /* video.c */
··· 80 u16 xmode_n; /* Size of unprobed mode range */ 81 }; 82 83 + #define __videocard struct card_info __attribute__((used,section(".videocards"))) 84 extern struct card_info video_cards[], video_cards_end[]; 85 86 int mode_defined(u16 mode); /* video.c */
+2 -15
arch/x86/realmode/rm/Makefile
··· 64 65 # --------------------------------------------------------------------------- 66 67 - # How to compile the 16-bit code. Note we always compile for -march=i386, 68 - # that way we can complain to the user if the CPU is insufficient. 69 - KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \ 70 - -I$(srctree)/arch/x86/boot \ 71 - -DDISABLE_BRANCH_PROFILING \ 72 - -Wall -Wstrict-prototypes \ 73 - -march=i386 -mregparm=3 \ 74 - -include $(srctree)/$(src)/../../boot/code16gcc.h \ 75 - -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ 76 - -mno-mmx -mno-sse \ 77 - $(call cc-option, -ffreestanding) \ 78 - $(call cc-option, -fno-toplevel-reorder,\ 79 - $(call cc-option, -fno-unit-at-a-time)) \ 80 - $(call cc-option, -fno-stack-protector) \ 81 - $(call cc-option, -mpreferred-stack-boundary=2) 82 KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 83 GCOV_PROFILE := n
··· 64 65 # --------------------------------------------------------------------------- 66 67 + KBUILD_CFLAGS := $(LINUXINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \ 68 + -I$(srctree)/arch/x86/boot 69 KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 70 GCOV_PROFILE := n
+29 -1
arch/x86/tools/relocs.c
··· 1025 } 1026 } 1027 1028 #if ELF_BITS == 64 1029 # define process process_64 1030 #else ··· 1055 #endif 1056 1057 void process(FILE *fp, int use_real_mode, int as_text, 1058 - int show_absolute_syms, int show_absolute_relocs) 1059 { 1060 regex_init(use_real_mode); 1061 read_ehdr(fp); ··· 1072 } 1073 if (show_absolute_relocs) { 1074 print_absolute_relocs(); 1075 return; 1076 } 1077 emit_relocs(as_text, use_real_mode);
··· 1025 } 1026 } 1027 1028 + /* 1029 + * As an aid to debugging problems with different linkers 1030 + * print summary information about the relocs. 1031 + * Since different linkers tend to emit the sections in 1032 + * different orders we use the section names in the output. 1033 + */ 1034 + static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, 1035 + const char *symname) 1036 + { 1037 + printf("%s\t%s\t%s\t%s\n", 1038 + sec_name(sec->shdr.sh_info), 1039 + rel_type(ELF_R_TYPE(rel->r_info)), 1040 + symname, 1041 + sec_name(sym->st_shndx)); 1042 + return 0; 1043 + } 1044 + 1045 + static void print_reloc_info(void) 1046 + { 1047 + printf("reloc section\treloc type\tsymbol\tsymbol section\n"); 1048 + walk_relocs(do_reloc_info); 1049 + } 1050 + 1051 #if ELF_BITS == 64 1052 # define process process_64 1053 #else ··· 1032 #endif 1033 1034 void process(FILE *fp, int use_real_mode, int as_text, 1035 + int show_absolute_syms, int show_absolute_relocs, 1036 + int show_reloc_info) 1037 { 1038 regex_init(use_real_mode); 1039 read_ehdr(fp); ··· 1048 } 1049 if (show_absolute_relocs) { 1050 print_absolute_relocs(); 1051 + return; 1052 + } 1053 + if (show_reloc_info) { 1054 + print_reloc_info(); 1055 return; 1056 } 1057 emit_relocs(as_text, use_real_mode);
+4 -3
arch/x86/tools/relocs.h
··· 29 }; 30 31 void process_32(FILE *fp, int use_real_mode, int as_text, 32 - int show_absolute_syms, int show_absolute_relocs); 33 void process_64(FILE *fp, int use_real_mode, int as_text, 34 - int show_absolute_syms, int show_absolute_relocs); 35 - 36 #endif /* RELOCS_H */
··· 29 }; 30 31 void process_32(FILE *fp, int use_real_mode, int as_text, 32 + int show_absolute_syms, int show_absolute_relocs, 33 + int show_reloc_info); 34 void process_64(FILE *fp, int use_real_mode, int as_text, 35 + int show_absolute_syms, int show_absolute_relocs, 36 + int show_reloc_info); 37 #endif /* RELOCS_H */
+12 -4
arch/x86/tools/relocs_common.c
··· 11 12 static void usage(void) 13 { 14 - die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); 15 } 16 17 int main(int argc, char **argv) 18 { 19 - int show_absolute_syms, show_absolute_relocs; 20 int as_text, use_real_mode; 21 const char *fname; 22 FILE *fp; ··· 26 27 show_absolute_syms = 0; 28 show_absolute_relocs = 0; 29 as_text = 0; 30 use_real_mode = 0; 31 fname = NULL; ··· 39 } 40 if (strcmp(arg, "--abs-relocs") == 0) { 41 show_absolute_relocs = 1; 42 continue; 43 } 44 if (strcmp(arg, "--text") == 0) { ··· 73 rewind(fp); 74 if (e_ident[EI_CLASS] == ELFCLASS64) 75 process_64(fp, use_real_mode, as_text, 76 - show_absolute_syms, show_absolute_relocs); 77 else 78 process_32(fp, use_real_mode, as_text, 79 - show_absolute_syms, show_absolute_relocs); 80 fclose(fp); 81 return 0; 82 }
··· 11 12 static void usage(void) 13 { 14 + die("relocs [--abs-syms|--abs-relocs|--reloc-info|--text|--realmode]" \ 15 + " vmlinux\n"); 16 } 17 18 int main(int argc, char **argv) 19 { 20 + int show_absolute_syms, show_absolute_relocs, show_reloc_info; 21 int as_text, use_real_mode; 22 const char *fname; 23 FILE *fp; ··· 25 26 show_absolute_syms = 0; 27 show_absolute_relocs = 0; 28 + show_reloc_info = 0; 29 as_text = 0; 30 use_real_mode = 0; 31 fname = NULL; ··· 37 } 38 if (strcmp(arg, "--abs-relocs") == 0) { 39 show_absolute_relocs = 1; 40 + continue; 41 + } 42 + if (strcmp(arg, "--reloc-info") == 0) { 43 + show_reloc_info = 1; 44 continue; 45 } 46 if (strcmp(arg, "--text") == 0) { ··· 67 rewind(fp); 68 if (e_ident[EI_CLASS] == ELFCLASS64) 69 process_64(fp, use_real_mode, as_text, 70 + show_absolute_syms, show_absolute_relocs, 71 + show_reloc_info); 72 else 73 process_32(fp, use_real_mode, as_text, 74 + show_absolute_syms, show_absolute_relocs, 75 + show_reloc_info); 76 fclose(fp); 77 return 0; 78 }