aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 21:13:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 21:13:20 -0500
commit10ffe3dbf7f9c63d6fde3d1fe23b8fd2ae4d7bd1 (patch)
tree579d5f88d8cb9eea77925a516fdaede366f05d82 /arch/x86
parentf8a504c404c6c4abbed4ae34fe1027ba3c24d035 (diff)
parentde3accdaec88851874c573031de007283e90b199 (diff)
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
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Makefile22
-rw-r--r--arch/x86/boot/Makefile15
-rw-r--r--arch/x86/boot/cpuflags.c25
-rw-r--r--arch/x86/boot/video.h2
-rw-r--r--arch/x86/realmode/rm/Makefile17
-rw-r--r--arch/x86/tools/relocs.c30
-rw-r--r--arch/x86/tools/relocs.h7
-rw-r--r--arch/x86/tools/relocs_common.c16
8 files changed, 91 insertions, 43 deletions
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 13b22e0f681d..eeda43abed6e 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -11,6 +11,28 @@ else
11 KBUILD_DEFCONFIG := $(ARCH)_defconfig 11 KBUILD_DEFCONFIG := $(ARCH)_defconfig
12endif 12endif
13 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.
21CODE16GCC_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))
24M16_CFLAGS := $(call cc-option, -m16, $(CODE16GCC_CFLAGS))
25
26REALMODE_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)
34export REALMODE_CFLAGS
35
14# BITS is used as extension for files which are available in a 32 bit 36# BITS is used as extension for files which are available in a 32 bit
15# and a 64 bit version to simplify shared Makefiles. 37# and a 64 bit version to simplify shared Makefiles.
16# e.g.: obj-y += foo_$(BITS).o 38# e.g.: obj-y += foo_$(BITS).o
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index de7066918005..878df7e88cd4 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -51,20 +51,7 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
51 51
52# --------------------------------------------------------------------------- 52# ---------------------------------------------------------------------------
53 53
54# How to compile the 16-bit code. Note we always compile for -march=i386, 54KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP
55# that way we can complain to the user if the CPU is insufficient.
56KBUILD_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)
68KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 55KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
69GCOV_PROFILE := n 56GCOV_PROFILE := n
70 57
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
index a9fcb7cfb241..431fa5f84537 100644
--- a/arch/x86/boot/cpuflags.c
+++ b/arch/x86/boot/cpuflags.c
@@ -28,20 +28,35 @@ static int has_fpu(void)
28 return fsw == 0 && (fcw & 0x103f) == 0x003f; 28 return fsw == 0 && (fcw & 0x103f) == 0x003f;
29} 29}
30 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
31int has_eflag(unsigned long mask) 46int has_eflag(unsigned long mask)
32{ 47{
33 unsigned long f0, f1; 48 unsigned long f0, f1;
34 49
35 asm volatile("pushf \n\t" 50 asm volatile(PUSHF " \n\t"
36 "pushf \n\t" 51 PUSHF " \n\t"
37 "pop %0 \n\t" 52 "pop %0 \n\t"
38 "mov %0,%1 \n\t" 53 "mov %0,%1 \n\t"
39 "xor %2,%1 \n\t" 54 "xor %2,%1 \n\t"
40 "push %1 \n\t" 55 "push %1 \n\t"
41 "popf \n\t" 56 POPF " \n\t"
42 "pushf \n\t" 57 PUSHF " \n\t"
43 "pop %1 \n\t" 58 "pop %1 \n\t"
44 "popf" 59 POPF
45 : "=&r" (f0), "=&r" (f1) 60 : "=&r" (f0), "=&r" (f1)
46 : "ri" (mask)); 61 : "ri" (mask));
47 62
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index ff339c5db311..0bb25491262d 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -80,7 +80,7 @@ struct card_info {
80 u16 xmode_n; /* Size of unprobed mode range */ 80 u16 xmode_n; /* Size of unprobed mode range */
81}; 81};
82 82
83#define __videocard struct card_info __attribute__((section(".videocards"))) 83#define __videocard struct card_info __attribute__((used,section(".videocards")))
84extern struct card_info video_cards[], video_cards_end[]; 84extern struct card_info video_cards[], video_cards_end[];
85 85
86int mode_defined(u16 mode); /* video.c */ 86int mode_defined(u16 mode); /* video.c */
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
index 9cac82588cbc..3497f14e4dea 100644
--- a/arch/x86/realmode/rm/Makefile
+++ b/arch/x86/realmode/rm/Makefile
@@ -64,20 +64,7 @@ $(obj)/realmode.relocs: $(obj)/realmode.elf FORCE
64 64
65# --------------------------------------------------------------------------- 65# ---------------------------------------------------------------------------
66 66
67# How to compile the 16-bit code. Note we always compile for -march=i386, 67KBUILD_CFLAGS := $(LINUXINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \
68# that way we can complain to the user if the CPU is insufficient. 68 -I$(srctree)/arch/x86/boot
69KBUILD_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)
82KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 69KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
83GCOV_PROFILE := n 70GCOV_PROFILE := n
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 11f9285a2ff6..cfbdbdb4e173 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -1025,6 +1025,29 @@ static void emit_relocs(int as_text, int use_real_mode)
1025 } 1025 }
1026} 1026}
1027 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 */
1034static 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
1045static void print_reloc_info(void)
1046{
1047 printf("reloc section\treloc type\tsymbol\tsymbol section\n");
1048 walk_relocs(do_reloc_info);
1049}
1050
1028#if ELF_BITS == 64 1051#if ELF_BITS == 64
1029# define process process_64 1052# define process process_64
1030#else 1053#else
@@ -1032,7 +1055,8 @@ static void emit_relocs(int as_text, int use_real_mode)
1032#endif 1055#endif
1033 1056
1034void process(FILE *fp, int use_real_mode, int as_text, 1057void process(FILE *fp, int use_real_mode, int as_text,
1035 int show_absolute_syms, int show_absolute_relocs) 1058 int show_absolute_syms, int show_absolute_relocs,
1059 int show_reloc_info)
1036{ 1060{
1037 regex_init(use_real_mode); 1061 regex_init(use_real_mode);
1038 read_ehdr(fp); 1062 read_ehdr(fp);
@@ -1050,5 +1074,9 @@ void process(FILE *fp, int use_real_mode, int as_text,
1050 print_absolute_relocs(); 1074 print_absolute_relocs();
1051 return; 1075 return;
1052 } 1076 }
1077 if (show_reloc_info) {
1078 print_reloc_info();
1079 return;
1080 }
1053 emit_relocs(as_text, use_real_mode); 1081 emit_relocs(as_text, use_real_mode);
1054} 1082}
diff --git a/arch/x86/tools/relocs.h b/arch/x86/tools/relocs.h
index 07cdb1eca4fa..f59590645b68 100644
--- a/arch/x86/tools/relocs.h
+++ b/arch/x86/tools/relocs.h
@@ -29,8 +29,9 @@ enum symtype {
29}; 29};
30 30
31void process_32(FILE *fp, int use_real_mode, int as_text, 31void process_32(FILE *fp, int use_real_mode, int as_text,
32 int show_absolute_syms, int show_absolute_relocs); 32 int show_absolute_syms, int show_absolute_relocs,
33 int show_reloc_info);
33void process_64(FILE *fp, int use_real_mode, int as_text, 34void process_64(FILE *fp, int use_real_mode, int as_text,
34 int show_absolute_syms, int show_absolute_relocs); 35 int show_absolute_syms, int show_absolute_relocs,
35 36 int show_reloc_info);
36#endif /* RELOCS_H */ 37#endif /* RELOCS_H */
diff --git a/arch/x86/tools/relocs_common.c b/arch/x86/tools/relocs_common.c
index 44d396823a53..acab636bcb34 100644
--- a/arch/x86/tools/relocs_common.c
+++ b/arch/x86/tools/relocs_common.c
@@ -11,12 +11,13 @@ void die(char *fmt, ...)
11 11
12static void usage(void) 12static void usage(void)
13{ 13{
14 die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); 14 die("relocs [--abs-syms|--abs-relocs|--reloc-info|--text|--realmode]" \
15 " vmlinux\n");
15} 16}
16 17
17int main(int argc, char **argv) 18int main(int argc, char **argv)
18{ 19{
19 int show_absolute_syms, show_absolute_relocs; 20 int show_absolute_syms, show_absolute_relocs, show_reloc_info;
20 int as_text, use_real_mode; 21 int as_text, use_real_mode;
21 const char *fname; 22 const char *fname;
22 FILE *fp; 23 FILE *fp;
@@ -25,6 +26,7 @@ int main(int argc, char **argv)
25 26
26 show_absolute_syms = 0; 27 show_absolute_syms = 0;
27 show_absolute_relocs = 0; 28 show_absolute_relocs = 0;
29 show_reloc_info = 0;
28 as_text = 0; 30 as_text = 0;
29 use_real_mode = 0; 31 use_real_mode = 0;
30 fname = NULL; 32 fname = NULL;
@@ -39,6 +41,10 @@ int main(int argc, char **argv)
39 show_absolute_relocs = 1; 41 show_absolute_relocs = 1;
40 continue; 42 continue;
41 } 43 }
44 if (strcmp(arg, "--reloc-info") == 0) {
45 show_reloc_info = 1;
46 continue;
47 }
42 if (strcmp(arg, "--text") == 0) { 48 if (strcmp(arg, "--text") == 0) {
43 as_text = 1; 49 as_text = 1;
44 continue; 50 continue;
@@ -67,10 +73,12 @@ int main(int argc, char **argv)
67 rewind(fp); 73 rewind(fp);
68 if (e_ident[EI_CLASS] == ELFCLASS64) 74 if (e_ident[EI_CLASS] == ELFCLASS64)
69 process_64(fp, use_real_mode, as_text, 75 process_64(fp, use_real_mode, as_text,
70 show_absolute_syms, show_absolute_relocs); 76 show_absolute_syms, show_absolute_relocs,
77 show_reloc_info);
71 else 78 else
72 process_32(fp, use_real_mode, as_text, 79 process_32(fp, use_real_mode, as_text,
73 show_absolute_syms, show_absolute_relocs); 80 show_absolute_syms, show_absolute_relocs,
81 show_reloc_info);
74 fclose(fp); 82 fclose(fp);
75 return 0; 83 return 0;
76} 84}