CHECKFLAGS += -D__arm__
+OBJCOPY_OUTPUT_FORMAT := elf32-littlearm
+
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o
textofs-y := 0x00008000
libs-y := arch/arm/lib/ $(libs-y)
+PIE_LDS := arch/arm/kernel/pie.lds
+libpie-$(CONFIG_PIE) += arch/arm/libpie/
+
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
KBUILD_IMAGE := xipImage
--- /dev/null
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ * Russ Dill <russ.dill@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pie.h>
+#include <linux/elf.h>
+
+#include <asm/elf.h>
+
+extern char __pie_rel_dyn_start[];
+extern char __pie_rel_dyn_end[];
+extern char __pie_tail_offset[];
+
+struct arm_pie_tail {
+ int count;
+ uintptr_t offset[0];
+};
+
+int pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
+ void *overlay_start, void *code_start, void *code_end)
+{
+ Elf32_Rel *rel;
+ int records;
+ int i;
+ struct arm_pie_tail *pie_tail = tail;
+ int count;
+
+ rel = (Elf32_Rel *) __pie_rel_dyn_start;
+ records = (__pie_rel_dyn_end - __pie_rel_dyn_start) /
+ sizeof(*rel);
+
+ count = 0;
+ for (i = 0; i < records; i++, rel++) {
+ void *kern_off;
+ if (ELF32_R_TYPE(rel->r_info) != R_ARM_RELATIVE)
+ return -ENOEXEC;
+
+ /* Adjust offset to match area in kernel */
+ kern_off = common_start + rel->r_offset;
+
+ if (kern_off >= common_start && kern_off < code_end) {
+ if (tail)
+ pie_tail->offset[count] = rel->r_offset;
+ count++;
+ } else if (kern_off >= code_start && kern_off < code_end) {
+ if (tail)
+ pie_tail->offset[count] = rel->r_offset -
+ (code_start - overlay_start);
+ count++;
+ }
+ }
+
+ if (tail)
+ pie_tail->count = count;
+
+ return count * sizeof(uintptr_t) + sizeof(*pie_tail);
+}
+EXPORT_SYMBOL_GPL(pie_arch_fill_tail);
+
+/*
+ * R_ARM_RELATIVE: B(S) + A
+ * B(S) - Addressing origin of the output segment defining the symbol S.
+ * A - Addend for the relocation.
+ */
+int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail,
+ unsigned long offset)
+{
+ struct arm_pie_tail *pie_tail = tail;
+ int i;
+
+ /* Perform relocation fixups for given offset */
+ for (i = 0; i < pie_tail->count; i++)
+ *((uintptr_t *) (pie_tail->offset[i] + base)) += offset;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pie_arch_fixup);
--- /dev/null
+/*
+ * ld script to make ARM PIEs
+ * taken from the ARM vmlinux.lds.S version by Russ Dill <russ.dill@ti.com.
+ */
+
+#include <asm-generic/pie.lds.h>
+
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+ . = 0x0;
+
+ PIE_COMMON_START
+ .got.plt : {
+ *(.got)
+ *(.got.plt)
+ }
+ .text : {
+ PIE_TEXT_TEXT
+ }
+ PIE_COMMON_END
+
+ PIE_OVERLAY_START
+ OVERLAY : NOCROSSREFS {
+ }
+ PIE_OVERLAY_SEND
+
+ __pie_rel_dyn_start : {
+ VMLINUX_SYMBOL(__pie_rel_dyn_start) = .;
+ }
+ .rel.dyn : {
+ KEEP(*(.rel*))
+ }
+ __pie_rel_dyn_end : {
+ VMLINUX_SYMBOL(__pie_rel_dyn_end) = .;
+ }
+
+ PIE_DISCARDS
+}
--- /dev/null
+#
+# linux/arch/arm/libpie/Makefile
+#
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin
+
+obj-y := empty.o
+obj-y += lib1funcs.o ashldi3.o string.o
+
+# string library code (-Os is enforced to keep it much smaller)
+string = $(obj)/string.o
+CFLAGS_string.o := -Os
+
+$(obj)/string.c: $(srctree)/arch/$(SRCARCH)/boot/compressed/string.c
+ $(call cmd,shipped)
+
+# For __aeabi_uidivmod
+lib1funcs = $(obj)/lib1funcs.o
+
+$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
+ $(call cmd,shipped)
+
+# For __aeabi_llsl
+ashldi3 = $(obj)/ashldi3.o
+
+$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
+ $(call cmd,shipped)
+
+$(obj)/libpie.o: $(string) $(lib1funcs) $(ashldi3) $(addprefix $(obj)/,$(OBJS))
+ $(call if_changed,ld)
+
+# Make sure files are removed during clean
+extra-y += string.c lib1funcs.S ashldi3.S