diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 21:13:20 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 21:13:20 -0500 |
| commit | 10ffe3dbf7f9c63d6fde3d1fe23b8fd2ae4d7bd1 (patch) | |
| tree | 579d5f88d8cb9eea77925a516fdaede366f05d82 | |
| parent | f8a504c404c6c4abbed4ae34fe1027ba3c24d035 (diff) | |
| parent | de3accdaec88851874c573031de007283e90b199 (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
| -rw-r--r-- | arch/x86/Makefile | 22 | ||||
| -rw-r--r-- | arch/x86/boot/Makefile | 15 | ||||
| -rw-r--r-- | arch/x86/boot/cpuflags.c | 25 | ||||
| -rw-r--r-- | arch/x86/boot/video.h | 2 | ||||
| -rw-r--r-- | arch/x86/realmode/rm/Makefile | 17 | ||||
| -rw-r--r-- | arch/x86/tools/relocs.c | 30 | ||||
| -rw-r--r-- | arch/x86/tools/relocs.h | 7 | ||||
| -rw-r--r-- | arch/x86/tools/relocs_common.c | 16 |
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 |
| 12 | endif | 12 | endif |
| 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. | ||
| 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 | |||
| 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, | 54 | KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP |
| 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__ | 55 | KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
| 69 | GCOV_PROFILE := n | 56 | GCOV_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 | |||
| 31 | int has_eflag(unsigned long mask) | 46 | int 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"))) |
| 84 | extern struct card_info video_cards[], video_cards_end[]; | 84 | extern struct card_info video_cards[], video_cards_end[]; |
| 85 | 85 | ||
| 86 | int mode_defined(u16 mode); /* video.c */ | 86 | int 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, | 67 | KBUILD_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 |
| 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__ | 69 | KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
| 83 | GCOV_PROFILE := n | 70 | GCOV_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 | */ | ||
| 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 | |||
| 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 | ||
| 1034 | void process(FILE *fp, int use_real_mode, int as_text, | 1057 | void 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 | ||
| 31 | void process_32(FILE *fp, int use_real_mode, int as_text, | 31 | void 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); | ||
| 33 | void process_64(FILE *fp, int use_real_mode, int as_text, | 34 | void 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 | ||
| 12 | static void usage(void) | 12 | static 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 | ||
| 17 | int main(int argc, char **argv) | 18 | int 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 | } |
