mips:compel: Enable mips in compel/

Signed-off-by: Guoyun Sun <sunguoyun@loongson.cn>
This commit is contained in:
Guoyun Sun 2020-04-08 10:21:11 +08:00 committed by Andrei Vagin
parent ba0d6dbac1
commit e7d13b368d
6 changed files with 93 additions and 4 deletions

View file

@ -4,7 +4,14 @@
#define COMPEL_TYPE_INT (1u << 0)
#define COMPEL_TYPE_LONG (1u << 1)
#define COMPEL_TYPE_GOTPCREL (1u << 2)
#ifdef CONFIG_MIPS
#define COMPEL_TYPE_MIPS_26 (1u << 3)
#define COMPEL_TYPE_MIPS_HI16 (1u << 4)
#define COMPEL_TYPE_MIPS_LO16 (1u << 5)
#define COMPEL_TYPE_MIPS_HIGHER (1u << 6)
#define COMPEL_TYPE_MIPS_HIGHEST (1u << 7)
#define COMPEL_TYPE_MIPS_64 (1u << 8)
#endif
typedef struct {
unsigned int offset;
unsigned int type;

View file

@ -165,6 +165,7 @@ extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl
extern int __must_check compel_get_thread_regs(struct parasite_thread_ctl *, save_regs_t, void *);
extern void compel_relocs_apply(void *mem, void *vbase, size_t size, compel_reloc_t *elf_relocs, size_t nr_relocs);
extern void compel_relocs_apply_mips(void *mem, void *vbase, compel_reloc_t *elf_relocs, size_t nr_relocs);
extern unsigned long compel_task_size(void);

View file

@ -16,7 +16,12 @@ asflags-y += -I compel/include/uapi
# General compel includes
ccflags-y += -iquote compel/include
ifeq ($(ARCH),mips)
ccflags-y += -mno-abicalls -fno-pic -fno-stack-protector
else
ccflags-y += -fpie -fno-stack-protector
endif
# General compel/plugins includes
ccflags-y += -iquote $(obj)/include
@ -28,7 +33,12 @@ asflags-y += -iquote $(PLUGIN_ARCH_DIR)/include
asflags-y += -iquote $(PLUGIN_ARCH_DIR)
# General flags for assembly
ifeq ($(ARCH),mips)
asflags-y += -mno-abicalls -fno-pic -Wstrict-prototypes
else
asflags-y += -fpie -Wstrict-prototypes
endif
asflags-y += -nostdlib -fomit-frame-pointer
asflags-y += -fno-stack-protector
ldflags-y += -z noexecstack
@ -57,6 +67,10 @@ ifeq ($(ARCH),x86)
std-lib-y += ./$(PLUGIN_ARCH_DIR)/std/memcpy.o
endif
ifeq ($(ARCH),mips)
std-lib-y += ./$(PLUGIN_ARCH_DIR)/std/memcpy.o
endif
ifeq ($(ARCH),ppc64)
std-lib-y += ./$(PLUGIN_ARCH_DIR)/std/memcpy.o
std-lib-y += ./$(PLUGIN_ARCH_DIR)/std/memcmp.o

View file

@ -16,8 +16,9 @@
#include "piegen.h"
#include "log.h"
piegen_opt_t opts = {};
#ifdef CONFIG_MIPS
#include "ldsodefs.h"
#endif
/* Check if pointer is out-of-bound */
static bool __ptr_oob(const uintptr_t ptr, const uintptr_t start, const size_t size)
{
@ -403,6 +404,66 @@ int __handle_elf(void *mem, size_t size)
#endif
switch (ELF_R_TYPE(r->rel.r_info)) {
#ifdef CONFIG_MIPS
case R_MIPS_PC16:
/* s+a-p relative */
*((int32_t *)where) = *((int32_t *)where) | ((value32 + addend32 - place)>>2);
break;
case R_MIPS_26:
/* local : (((A << 2) | (P & 0xf0000000) + S) >> 2
* external : (signextend(A < 2) + S) >> 2
*/
if (((unsigned)ELF_ST_BIND(sym->st_info) == 0x1)
|| ((unsigned)ELF_ST_BIND(sym->st_info) == 0x2)){
/* bind type local is 0x0 ,global is 0x1,WEAK is 0x2 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_26, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_26 */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_32:
/* S+A */
break;
case R_MIPS_64:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_64, "
".addend = %-8ld, .value = 0x%-16lx, }, /* R_MIPS_64 */\n",
(unsigned int)place, (long)addend64, (long)value64);
break;
case R_MIPS_HIGHEST:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHEST, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHEST */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_HIGHER:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HIGHER, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HIGHER */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_HI16:
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_HI16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_HI16 */\n",
(unsigned int)place, addend32, value32);
break;
case R_MIPS_LO16:
if((unsigned)ELF_ST_BIND(sym->st_info) == 0x1){
/* bind type local is 0x0 ,global is 0x1 */
addend32 = value32;
}
pr_out(" { .offset = 0x%-8x, .type = COMPEL_TYPE_MIPS_LO16, "
".addend = %-8d, .value = 0x%-16x, }, /* R_MIPS_LO16 */\n",
(unsigned int)place, addend32, value32);
break;
#endif
#ifdef ELF_PPC64
case R_PPC64_REL24:
/* Update PC relative offset, linker has not done this yet */

View file

@ -817,7 +817,9 @@ err_cure:
void compel_relocs_apply(void *mem, void *vbase, size_t size, compel_reloc_t *elf_relocs, size_t nr_relocs)
{
size_t i, j;
#ifdef CONFIG_MIPS
compel_relocs_apply_mips(mem, vbase, elf_relocs, nr_relocs);
#else
for (i = 0, j = 0; i < nr_relocs; i++) {
if (elf_relocs[i].type & COMPEL_TYPE_LONG) {
long *where = mem + elf_relocs[i].offset;
@ -840,6 +842,7 @@ void compel_relocs_apply(void *mem, void *vbase, size_t size, compel_reloc_t *el
} else
BUG();
}
#endif
}
static int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)

View file

@ -53,11 +53,14 @@ static const flags_t flags = {
#elif defined CONFIG_S390
.arch = "s390",
.cflags = COMPEL_CFLAGS_PIE,
#elif defined CONFIG_MIPS
.arch = "mips",
#else
#error "CONFIG_<ARCH> not defined, or unsupported ARCH"
#endif
};
piegen_opt_t opts = {};
const char *uninst_root;
static int piegen(void)