mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
unicore32 core architecture: generic elf and ksyms stuff
This patch includes some generic stuff including elf and ksyms. Because all one-line asm-generic headers are auto-generated by ASM_GENERIC_HEADERS in arch/unicore32/Makefile, so the rest seems very little. ELF handling functions and module handling functions are also here. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
790edb61c0
commit
87c1a3fb7c
94
arch/unicore32/include/asm/elf.h
Normal file
94
arch/unicore32/include/asm/elf.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* linux/arch/unicore32/include/asm/elf.h
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __UNICORE_ELF_H__
|
||||
#define __UNICORE_ELF_H__
|
||||
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
typedef unsigned long elf_freg_t[3];
|
||||
|
||||
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct fp_state elf_fpregset_t;
|
||||
|
||||
#define EM_UNICORE 110
|
||||
|
||||
#define R_UNICORE_NONE 0
|
||||
#define R_UNICORE_PC24 1
|
||||
#define R_UNICORE_ABS32 2
|
||||
#define R_UNICORE_CALL 28
|
||||
#define R_UNICORE_JUMP24 29
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_UNICORE
|
||||
|
||||
/*
|
||||
* This yields a string that ld.so will use to load implementation
|
||||
* specific libraries for optimization. This is more specific in
|
||||
* intent than poking at uname or /proc/cpuinfo.
|
||||
*
|
||||
*/
|
||||
#define ELF_PLATFORM_SIZE 8
|
||||
#define ELF_PLATFORM (elf_platform)
|
||||
|
||||
extern char elf_platform[];
|
||||
|
||||
struct elf32_hdr;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
extern int elf_check_arch(const struct elf32_hdr *);
|
||||
#define elf_check_arch elf_check_arch
|
||||
|
||||
struct task_struct;
|
||||
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
|
||||
#define ELF_CORE_COPY_TASK_REGS dump_task_regs
|
||||
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
|
||||
use of this is to invoke "./ld.so someprog" to test out a new version of
|
||||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
|
||||
|
||||
/* When the program starts, a1 contains a pointer to a function to be
|
||||
registered with atexit, as per the SVR4 ABI. A value of 0 means we
|
||||
have no such handler. */
|
||||
#define ELF_PLAT_INIT(_r, load_addr) {(_r)->UCreg_00 = 0; }
|
||||
|
||||
extern void elf_set_personality(const struct elf32_hdr *);
|
||||
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
|
||||
|
||||
struct mm_struct;
|
||||
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define arch_randomize_brk arch_randomize_brk
|
||||
|
||||
extern int vectors_user_mapping(void);
|
||||
#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
|
||||
#endif
|
38
arch/unicore32/include/asm/string.h
Normal file
38
arch/unicore32/include/asm/string.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* linux/arch/unicore32/include/asm/string.h
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __UNICORE_STRING_H__
|
||||
#define __UNICORE_STRING_H__
|
||||
|
||||
/*
|
||||
* We don't do inline string functions, since the
|
||||
* optimised inline asm versions are not small.
|
||||
*/
|
||||
|
||||
#define __HAVE_ARCH_STRRCHR
|
||||
extern char *strrchr(const char *s, int c);
|
||||
|
||||
#define __HAVE_ARCH_STRCHR
|
||||
extern char *strchr(const char *s, int c);
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
extern void *memcpy(void *, const void *, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *, const void *, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMCHR
|
||||
extern void *memchr(const void *, int, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *, int, __kernel_size_t);
|
||||
|
||||
#endif
|
112
arch/unicore32/kernel/asm-offsets.c
Normal file
112
arch/unicore32/kernel/asm-offsets.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* linux/arch/unicore32/kernel/asm-offsets.c
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* Generate definitions needed by assembly language modules.
|
||||
* This code generates raw asm output which is post-processed to extract
|
||||
* and format the required data.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
/*
|
||||
* GCC 3.0, 3.1: general bad code generation.
|
||||
* GCC 3.2.0: incorrect function argument offset calculation.
|
||||
* GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
|
||||
* (http://gcc.gnu.org/PR8896) and incorrect structure
|
||||
* initialisation in fs/jffs2/erase.c
|
||||
*/
|
||||
#if (__GNUC__ < 4)
|
||||
#error Your compiler should upgrade to uc4
|
||||
#error Known good compilers: 4.2.2
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
|
||||
BLANK();
|
||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
|
||||
DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
|
||||
DEFINE(TI_TASK, offsetof(struct thread_info, task));
|
||||
DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
|
||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
||||
DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
|
||||
DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
|
||||
#ifdef CONFIG_UNICORE_FPU_F64
|
||||
DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
|
||||
#endif
|
||||
BLANK();
|
||||
DEFINE(S_R0, offsetof(struct pt_regs, UCreg_00));
|
||||
DEFINE(S_R1, offsetof(struct pt_regs, UCreg_01));
|
||||
DEFINE(S_R2, offsetof(struct pt_regs, UCreg_02));
|
||||
DEFINE(S_R3, offsetof(struct pt_regs, UCreg_03));
|
||||
DEFINE(S_R4, offsetof(struct pt_regs, UCreg_04));
|
||||
DEFINE(S_R5, offsetof(struct pt_regs, UCreg_05));
|
||||
DEFINE(S_R6, offsetof(struct pt_regs, UCreg_06));
|
||||
DEFINE(S_R7, offsetof(struct pt_regs, UCreg_07));
|
||||
DEFINE(S_R8, offsetof(struct pt_regs, UCreg_08));
|
||||
DEFINE(S_R9, offsetof(struct pt_regs, UCreg_09));
|
||||
DEFINE(S_R10, offsetof(struct pt_regs, UCreg_10));
|
||||
DEFINE(S_R11, offsetof(struct pt_regs, UCreg_11));
|
||||
DEFINE(S_R12, offsetof(struct pt_regs, UCreg_12));
|
||||
DEFINE(S_R13, offsetof(struct pt_regs, UCreg_13));
|
||||
DEFINE(S_R14, offsetof(struct pt_regs, UCreg_14));
|
||||
DEFINE(S_R15, offsetof(struct pt_regs, UCreg_15));
|
||||
DEFINE(S_R16, offsetof(struct pt_regs, UCreg_16));
|
||||
DEFINE(S_R17, offsetof(struct pt_regs, UCreg_17));
|
||||
DEFINE(S_R18, offsetof(struct pt_regs, UCreg_18));
|
||||
DEFINE(S_R19, offsetof(struct pt_regs, UCreg_19));
|
||||
DEFINE(S_R20, offsetof(struct pt_regs, UCreg_20));
|
||||
DEFINE(S_R21, offsetof(struct pt_regs, UCreg_21));
|
||||
DEFINE(S_R22, offsetof(struct pt_regs, UCreg_22));
|
||||
DEFINE(S_R23, offsetof(struct pt_regs, UCreg_23));
|
||||
DEFINE(S_R24, offsetof(struct pt_regs, UCreg_24));
|
||||
DEFINE(S_R25, offsetof(struct pt_regs, UCreg_25));
|
||||
DEFINE(S_R26, offsetof(struct pt_regs, UCreg_26));
|
||||
DEFINE(S_FP, offsetof(struct pt_regs, UCreg_fp));
|
||||
DEFINE(S_IP, offsetof(struct pt_regs, UCreg_ip));
|
||||
DEFINE(S_SP, offsetof(struct pt_regs, UCreg_sp));
|
||||
DEFINE(S_LR, offsetof(struct pt_regs, UCreg_lr));
|
||||
DEFINE(S_PC, offsetof(struct pt_regs, UCreg_pc));
|
||||
DEFINE(S_PSR, offsetof(struct pt_regs, UCreg_asr));
|
||||
DEFINE(S_OLD_R0, offsetof(struct pt_regs, UCreg_ORIG_00));
|
||||
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
|
||||
BLANK();
|
||||
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
|
||||
DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
|
||||
BLANK();
|
||||
DEFINE(VM_EXEC, VM_EXEC);
|
||||
BLANK();
|
||||
DEFINE(PAGE_SZ, PAGE_SIZE);
|
||||
BLANK();
|
||||
DEFINE(SYS_ERROR0, 0x9f0000);
|
||||
BLANK();
|
||||
DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
|
||||
DEFINE(PBE_ORIN_ADDRESS, offsetof(struct pbe, orig_address));
|
||||
DEFINE(PBE_NEXT, offsetof(struct pbe, next));
|
||||
DEFINE(SWSUSP_CPU, offsetof(struct swsusp_arch_regs, \
|
||||
cpu_context));
|
||||
#ifdef CONFIG_UNICORE_FPU_F64
|
||||
DEFINE(SWSUSP_FPSTATE, offsetof(struct swsusp_arch_regs, \
|
||||
fpstate));
|
||||
#endif
|
||||
BLANK();
|
||||
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
|
||||
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
|
||||
DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
|
||||
return 0;
|
||||
}
|
38
arch/unicore32/kernel/elf.c
Normal file
38
arch/unicore32/kernel/elf.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* linux/arch/unicore32/kernel/elf.c
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/elf.h>
|
||||
|
||||
int elf_check_arch(const struct elf32_hdr *x)
|
||||
{
|
||||
/* Make sure it's an UniCore executable */
|
||||
if (x->e_machine != EM_UNICORE)
|
||||
return 0;
|
||||
|
||||
/* Make sure the entry address is reasonable */
|
||||
if (x->e_entry & 3)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(elf_check_arch);
|
||||
|
||||
void elf_set_personality(const struct elf32_hdr *x)
|
||||
{
|
||||
unsigned int personality = PER_LINUX;
|
||||
|
||||
set_personality(personality);
|
||||
}
|
||||
EXPORT_SYMBOL(elf_set_personality);
|
99
arch/unicore32/kernel/ksyms.c
Normal file
99
arch/unicore32/kernel/ksyms.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* linux/arch/unicore32/kernel/ksyms.c
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include "ksyms.h"
|
||||
|
||||
EXPORT_SYMBOL(__uc32_find_next_zero_bit);
|
||||
EXPORT_SYMBOL(__uc32_find_next_bit);
|
||||
|
||||
EXPORT_SYMBOL(__backtrace);
|
||||
|
||||
/* platform dependent support */
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
EXPORT_SYMBOL(__const_udelay);
|
||||
|
||||
/* networking */
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
||||
EXPORT_SYMBOL(__csum_ipv6_magic);
|
||||
|
||||
/* io */
|
||||
#ifndef __raw_readsb
|
||||
EXPORT_SYMBOL(__raw_readsb);
|
||||
#endif
|
||||
#ifndef __raw_readsw
|
||||
EXPORT_SYMBOL(__raw_readsw);
|
||||
#endif
|
||||
#ifndef __raw_readsl
|
||||
EXPORT_SYMBOL(__raw_readsl);
|
||||
#endif
|
||||
#ifndef __raw_writesb
|
||||
EXPORT_SYMBOL(__raw_writesb);
|
||||
#endif
|
||||
#ifndef __raw_writesw
|
||||
EXPORT_SYMBOL(__raw_writesw);
|
||||
#endif
|
||||
#ifndef __raw_writesl
|
||||
EXPORT_SYMBOL(__raw_writesl);
|
||||
#endif
|
||||
|
||||
/* string / mem functions */
|
||||
EXPORT_SYMBOL(strchr);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(memchr);
|
||||
|
||||
/* user mem (segment) */
|
||||
EXPORT_SYMBOL(__strnlen_user);
|
||||
EXPORT_SYMBOL(__strncpy_from_user);
|
||||
|
||||
EXPORT_SYMBOL(copy_page);
|
||||
|
||||
EXPORT_SYMBOL(__copy_from_user);
|
||||
EXPORT_SYMBOL(__copy_to_user);
|
||||
EXPORT_SYMBOL(__clear_user);
|
||||
|
||||
EXPORT_SYMBOL(__get_user_1);
|
||||
EXPORT_SYMBOL(__get_user_2);
|
||||
EXPORT_SYMBOL(__get_user_4);
|
||||
|
||||
EXPORT_SYMBOL(__put_user_1);
|
||||
EXPORT_SYMBOL(__put_user_2);
|
||||
EXPORT_SYMBOL(__put_user_4);
|
||||
EXPORT_SYMBOL(__put_user_8);
|
||||
|
||||
EXPORT_SYMBOL(__ashldi3);
|
||||
EXPORT_SYMBOL(__ashrdi3);
|
||||
EXPORT_SYMBOL(__divsi3);
|
||||
EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(__modsi3);
|
||||
EXPORT_SYMBOL(__muldi3);
|
||||
EXPORT_SYMBOL(__ucmpdi2);
|
||||
EXPORT_SYMBOL(__udivsi3);
|
||||
EXPORT_SYMBOL(__umodsi3);
|
||||
EXPORT_SYMBOL(__bswapsi2);
|
||||
|
15
arch/unicore32/kernel/ksyms.h
Normal file
15
arch/unicore32/kernel/ksyms.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* libgcc functions - functions that are used internally by the
|
||||
* compiler... (prototypes are not correct though, but that
|
||||
* doesn't really matter since they're not versioned).
|
||||
*/
|
||||
extern void __ashldi3(void);
|
||||
extern void __ashrdi3(void);
|
||||
extern void __divsi3(void);
|
||||
extern void __lshrdi3(void);
|
||||
extern void __modsi3(void);
|
||||
extern void __muldi3(void);
|
||||
extern void __ucmpdi2(void);
|
||||
extern void __udivsi3(void);
|
||||
extern void __umodsi3(void);
|
||||
extern void __bswapsi2(void);
|
152
arch/unicore32/kernel/module.c
Normal file
152
arch/unicore32/kernel/module.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* linux/arch/unicore32/kernel/module.c
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
|
||||
if (!area)
|
||||
return NULL;
|
||||
|
||||
return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
|
||||
}
|
||||
|
||||
void module_free(struct module *module, void *region)
|
||||
{
|
||||
vfree(region);
|
||||
}
|
||||
|
||||
int module_frob_arch_sections(Elf_Ehdr *hdr,
|
||||
Elf_Shdr *sechdrs,
|
||||
char *secstrings,
|
||||
struct module *mod)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
|
||||
unsigned int relindex, struct module *module)
|
||||
{
|
||||
Elf32_Shdr *symsec = sechdrs + symindex;
|
||||
Elf32_Shdr *relsec = sechdrs + relindex;
|
||||
Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
|
||||
Elf32_Rel *rel = (void *)relsec->sh_addr;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
|
||||
unsigned long loc;
|
||||
Elf32_Sym *sym;
|
||||
s32 offset;
|
||||
|
||||
offset = ELF32_R_SYM(rel->r_info);
|
||||
if (offset < 0 || offset >
|
||||
(symsec->sh_size / sizeof(Elf32_Sym))) {
|
||||
printk(KERN_ERR "%s: bad relocation, "
|
||||
"section %d reloc %d\n",
|
||||
module->name, relindex, i);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
|
||||
|
||||
if (rel->r_offset < 0 || rel->r_offset >
|
||||
dstsec->sh_size - sizeof(u32)) {
|
||||
printk(KERN_ERR "%s: out of bounds relocation, "
|
||||
"section %d reloc %d offset %d size %d\n",
|
||||
module->name, relindex, i, rel->r_offset,
|
||||
dstsec->sh_size);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
loc = dstsec->sh_addr + rel->r_offset;
|
||||
|
||||
switch (ELF32_R_TYPE(rel->r_info)) {
|
||||
case R_UNICORE_NONE:
|
||||
/* ignore */
|
||||
break;
|
||||
|
||||
case R_UNICORE_ABS32:
|
||||
*(u32 *)loc += sym->st_value;
|
||||
break;
|
||||
|
||||
case R_UNICORE_PC24:
|
||||
case R_UNICORE_CALL:
|
||||
case R_UNICORE_JUMP24:
|
||||
offset = (*(u32 *)loc & 0x00ffffff) << 2;
|
||||
if (offset & 0x02000000)
|
||||
offset -= 0x04000000;
|
||||
|
||||
offset += sym->st_value - loc;
|
||||
if (offset & 3 ||
|
||||
offset <= (s32)0xfe000000 ||
|
||||
offset >= (s32)0x02000000) {
|
||||
printk(KERN_ERR
|
||||
"%s: relocation out of range, section "
|
||||
"%d reloc %d sym '%s'\n", module->name,
|
||||
relindex, i, strtab + sym->st_name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
offset >>= 2;
|
||||
|
||||
*(u32 *)loc &= 0xff000000;
|
||||
*(u32 *)loc |= offset & 0x00ffffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s: unknown relocation: %u\n",
|
||||
module->name, ELF32_R_TYPE(rel->r_info));
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
|
||||
unsigned int symindex, unsigned int relsec,
|
||||
struct module *module)
|
||||
{
|
||||
printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
|
||||
module->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
int
|
||||
module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
|
||||
struct module *module)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
}
|
23
arch/unicore32/mm/proc-syms.c
Normal file
23
arch/unicore32/mm/proc-syms.c
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* linux/arch/unicore32/mm/proc-syms.c
|
||||
*
|
||||
* Code specific to PKUnity SoC and UniCore ISA
|
||||
*
|
||||
* Copyright (C) 2001-2010 GUAN Xue-tao
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
EXPORT_SYMBOL(cpu_dcache_clean_area);
|
||||
EXPORT_SYMBOL(cpu_set_pte);
|
||||
|
||||
EXPORT_SYMBOL(__cpuc_dma_flush_range);
|
||||
EXPORT_SYMBOL(__cpuc_dma_clean_range);
|
Loading…
Reference in New Issue
Block a user