};
int pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
- void *overlay_start, void *code_start, void *code_end)
+ void *overlay_start, void *code_start, void *code_end,
+ void *rel_start, void *rel_end)
{
Elf32_Rel *rel;
int records;
int i;
struct arm_pie_tail *pie_tail = tail;
int count;
+ void *kern_off;
rel = (Elf32_Rel *) __pie_rel_dyn_start;
- records = (__pie_rel_dyn_end - __pie_rel_dyn_start) /
- sizeof(*rel);
+ 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;
+ break;
/* Adjust offset to match area in kernel */
kern_off = common_start + rel->r_offset;
if (tail)
pie_tail->offset[count] = rel->r_offset;
count++;
- } else if (kern_off >= code_start && kern_off < code_end) {
+ }
+ }
+
+ rel = (Elf32_Rel *) rel_start;
+ records = (rel_end - rel_start) / sizeof(*rel);
+
+ for (i = 0; i < records; i++, rel++) {
+ if (ELF32_R_TYPE(rel->r_info) != R_ARM_RELATIVE)
+ break;
+
+ /* 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 -
- (code_start - overlay_start);
+ pie_tail->offset[count] = rel->r_offset;
count++;
}
}
}
PIE_COMMON_END
- PIE_OVERLAY_START
- OVERLAY : NOCROSSREFS {
- PIE_OVERLAY_SECTION(rockchip)
- }
- PIE_OVERLAY_END
-
__pie_rel_dyn_start : {
VMLINUX_SYMBOL(__pie_rel_dyn_start) = .;
}
.rel.dyn : {
- KEEP(*(.rel*))
+ KEEP(*(.rel.pie.text))
}
__pie_rel_dyn_end : {
VMLINUX_SYMBOL(__pie_rel_dyn_end) = .;
}
+ PIE_OVERLAY_START
+ OVERLAY : NOCROSSREFS {
+ PIE_OVERLAY_SECTION(rk3188)
+ }
+ PIE_OVERLAY_END
+
PIE_DISCARDS
}
VMLINUX_SYMBOL(__pie_##name##_end) = \
LOADADDR(.pie.##name##) + \
SIZEOF(.pie.##name##); \
+ } \
+ .rel.##name { \
+ KEEP(*(.rel.pie.##name##.*)) \
+ VMLINUX_SYMBOL(__pie_rel_##name##_start) = \
+ LOADADDR(.rel.##name##); \
+ VMLINUX_SYMBOL(__pie_rel_##name##_end) = \
+ LOADADDR(.rel.##name##) + \
+ SIZEOF(.rel.##name##); \
}
#define PIE_DISCARDS \
* Returns number of bytes required/used for tail on success, -EERROR otherwise.
*/
extern int pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
- void *overlay_start, void *code_start, void *code_end);
+ void *overlay_start, void *code_start, void *code_end,
+ void *rel_start, void *rel_end);
#ifdef CONFIG_PIE
*
* Returns 0 on success, -EERROR otherwise
*/
-extern struct pie_chunk *__pie_load_data(struct gen_pool *pool,
- void *start, void *end, bool phys);
+extern struct pie_chunk *__pie_load_data(struct gen_pool *pool, bool phys,
+ void *start, void *end,
+ void *rel_start, void *rel_end);
/**
* pie_to_phys - translate a virtual PIE address into a physical one
#define __pie_load_sections(pool, name, phys) ({ \
extern char __pie_##name##_start[]; \
extern char __pie_##name##_end[]; \
+ extern char __pie_rel_##name##_start[]; \
+ extern char __pie_rel_##name##_end[]; \
\
- __pie_load_data(pool, __pie_##name##_start, \
- __pie_##name##_end, phys); \
+ __pie_load_data(pool, phys, \
+ __pie_##name##_start, __pie_##name##_end, \
+ __pie_rel_##name##_start, __pie_rel_##name##_end); \
})
/*
extern char __pie_overlay_start[];
int __weak pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
- void *overlay_start, void *code_start, void *code_end)
+ void *overlay_start, void *code_start, void *code_end,
+ void *rel_start, void *rel_end)
{
return 0;
}
return 0;
}
-struct pie_chunk *__pie_load_data(struct gen_pool *pool, void *code_start,
- void *code_end, bool phys)
+struct pie_chunk *__pie_load_data(struct gen_pool *pool, bool phys,
+ void *code_start, void *code_end,
+ void *rel_start, void *rel_end)
{
struct pie_chunk *chunk;
unsigned long offset;
/* Calculate the tail size */
ret = pie_arch_fill_tail(NULL, __pie_common_start, __pie_common_end,
- __pie_overlay_start, code_start, code_end);
+ __pie_overlay_start, code_start, code_end,
+ rel_start, rel_end);
if (ret < 0)
goto err;
tail_sz = ret;
goto err;
}
- common_sz = __pie_overlay_start - __pie_common_start;
+ common_sz = code_start - (void *)__pie_common_start;
code_sz = code_end - code_start;
chunk->pool = pool;
/* Fill in tail data */
ret = pie_arch_fill_tail(tail, __pie_common_start, __pie_common_end,
- __pie_overlay_start, code_start, code_end);
+ __pie_overlay_start, code_start, code_end,
+ rel_start, rel_end);
if (ret < 0)
goto err_alloc;
# Drop everything but the pie sections
OBJCOPYFLAGS_pie_stage3.o += -j ".pie.*"
OBJCOPYFLAGS_pie_stage3.o += -j ".pie.text"
-OBJCOPYFLAGS_pie_stage3.o += -j ".pie.rockchip.text" -j ".pie.rockchip.data"
+OBJCOPYFLAGS_pie_stage3.o += -j ".pie.rk3188.text" -j ".pie.rk3188.data"
$(obj)/pie_stage3.o: $(obj)/pie_stage2.o
$(call if_changed,objcopy)