Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
bca2be21
Commit
bca2be21
authored
Dec 25, 2002
by
Richard Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ALPHA] ET_REL modules support.
parent
56eb992e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
361 additions
and
29 deletions
+361
-29
arch/alpha/kernel/Makefile
arch/alpha/kernel/Makefile
+4
-6
arch/alpha/kernel/module.c
arch/alpha/kernel/module.c
+306
-0
arch/alpha/mm/extable.c
arch/alpha/mm/extable.c
+7
-7
include/asm-alpha/module.h
include/asm-alpha/module.h
+21
-4
include/linux/elf.h
include/linux/elf.h
+23
-12
No files found.
arch/alpha/kernel/Makefile
View file @
bca2be21
...
@@ -19,13 +19,11 @@ obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
...
@@ -19,13 +19,11 @@ obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
obj-y
+=
irq_i8259.o irq_srm.o
\
obj-y
+=
irq_i8259.o irq_srm.o
\
es1888.o smc37c669.o smc37c93x.o ns87312.o
es1888.o smc37c669.o smc37c93x.o ns87312.o
ifdef
CONFIG_VGA_HOSE
obj-$(CONFIG_VGA_HOSE)
+=
console.o
obj-y
+=
console.o
obj-$(CONFIG_SMP)
+=
smp.o
endif
obj-$(CONFIG_PCI)
+=
pci.o pci_iommu.o
obj-$(CONFIG_SMP)
+=
smp.o
obj-$(CONFIG_PCI)
+=
pci.o pci_iommu.o
obj-$(CONFIG_SRM_ENV)
+=
srm_env.o
obj-$(CONFIG_SRM_ENV)
+=
srm_env.o
obj-$(CONFIG_MODULES)
+=
module.o
ifdef
CONFIG_ALPHA_GENERIC
ifdef
CONFIG_ALPHA_GENERIC
...
...
arch/alpha/kernel/module.c
0 → 100644
View file @
bca2be21
/* Kernel module help for Alpha.
Copyright (C) 2002 Richard Henderson.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt...)
#endif
void
*
module_alloc
(
unsigned
long
size
)
{
if
(
size
==
0
)
return
NULL
;
return
vmalloc
(
size
);
}
void
module_free
(
struct
module
*
mod
,
void
*
module_region
)
{
vfree
(
module_region
);
}
/* Allocate the GOT at the end of the core sections. */
struct
got_entry
{
struct
got_entry
*
next
;
Elf64_Addr
r_offset
;
int
got_offset
;
};
static
inline
void
process_reloc_for_got
(
Elf64_Rela
*
rela
,
struct
got_entry
*
chains
,
Elf64_Xword
*
poffset
)
{
unsigned
long
r_sym
=
ELF64_R_SYM
(
rela
->
r_info
);
unsigned
long
r_type
=
ELF64_R_TYPE
(
rela
->
r_info
);
Elf64_Addr
r_offset
=
rela
->
r_offset
;
struct
got_entry
*
g
;
if
(
r_type
!=
R_ALPHA_LITERAL
)
return
;
for
(
g
=
chains
+
r_sym
;
g
;
g
=
g
->
next
)
if
(
g
->
r_offset
==
r_offset
)
{
if
(
g
->
got_offset
==
0
)
{
g
->
got_offset
=
*
poffset
;
*
poffset
+=
8
;
}
goto
found_entry
;
}
g
=
kmalloc
(
sizeof
(
*
g
),
GFP_KERNEL
);
g
->
next
=
chains
[
r_sym
].
next
;
g
->
r_offset
=
r_offset
;
g
->
got_offset
=
*
poffset
;
*
poffset
+=
8
;
chains
[
r_sym
].
next
=
g
;
found_entry:
/* Trick: most of the ELF64_R_TYPE field is unused. There are
42 valid relocation types, and a 32-bit field. Co-opt the
bits above 256 to store the got offset for this reloc. */
rela
->
r_info
|=
g
->
got_offset
<<
8
;
}
int
module_frob_arch_sections
(
const
Elf64_Ehdr
*
hdr
,
const
Elf64_Shdr
*
sechdrs
,
const
char
*
secstrings
,
struct
module
*
me
)
{
struct
got_entry
*
chains
;
Elf64_Rela
*
rela
;
const
Elf64_Shdr
*
esechdrs
,
*
symtab
,
*
s
;
Elf64_Shdr
*
got
;
unsigned
long
nsyms
,
nrela
,
i
;
esechdrs
=
sechdrs
+
hdr
->
e_shnum
;
symtab
=
got
=
NULL
;
/* Find out how large the symbol table is. Allocate one got_entry
head per symbol. Normally this will be enough, but not always.
We'll chain different offsets for the symbol down each head. */
for
(
s
=
sechdrs
;
s
<
esechdrs
;
++
s
)
if
(
s
->
sh_type
==
SHT_SYMTAB
)
symtab
=
s
;
else
if
(
!
strcmp
(
".got"
,
secstrings
+
s
->
sh_name
))
{
got
=
(
Elf64_Shdr
*
)
s
;
me
->
arch
.
gotsecindex
=
s
-
sechdrs
;
}
if
(
!
symtab
)
{
printk
(
KERN_ERR
"module %s: no symbol table
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
if
(
!
got
)
{
printk
(
KERN_ERR
"module %s: no got section
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
nsyms
=
symtab
->
sh_size
/
sizeof
(
Elf64_Sym
);
chains
=
kmalloc
(
nsyms
*
sizeof
(
struct
got_entry
),
GFP_KERNEL
);
memset
(
chains
,
0
,
nsyms
*
sizeof
(
struct
got_entry
));
got
->
sh_size
=
0
;
got
->
sh_addralign
=
8
;
got
->
sh_type
=
SHT_NOBITS
;
/* Examine all LITERAL relocations to find out what GOT entries
are required. This sizes the GOT section as well. */
for
(
s
=
sechdrs
;
s
<
esechdrs
;
++
s
)
if
(
s
->
sh_type
==
SHT_RELA
)
{
nrela
=
s
->
sh_size
/
sizeof
(
Elf64_Rela
);
rela
=
(
void
*
)
hdr
+
s
->
sh_offset
;
for
(
i
=
0
;
i
<
nrela
;
++
i
)
process_reloc_for_got
(
rela
+
i
,
chains
,
&
got
->
sh_size
);
}
/* Free the memory we allocated. */
for
(
i
=
0
;
i
<
nsyms
;
++
i
)
{
struct
got_entry
*
g
,
*
n
;
for
(
g
=
chains
[
i
].
next
;
g
;
g
=
n
)
{
n
=
g
->
next
;
kfree
(
g
);
}
}
kfree
(
chains
);
return
0
;
}
int
apply_relocate
(
Elf64_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
printk
(
KERN_ERR
"module %s: REL relocation unsupported
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
int
apply_relocate_add
(
Elf64_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
Elf64_Rela
*
rela
=
(
void
*
)
sechdrs
[
relsec
].
sh_addr
;
unsigned
long
i
,
n
=
sechdrs
[
relsec
].
sh_size
/
sizeof
(
*
rela
);
Elf64_Sym
*
symtab
,
*
sym
;
void
*
base
,
*
location
;
unsigned
long
got
,
gp
;
DEBUGP
(
"Applying relocate section %u to %u
\n
"
,
relsec
,
sechdrs
[
relsec
].
sh_info
);
base
=
(
void
*
)
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_addr
;
symtab
=
(
Elf64_Sym
*
)
sechdrs
[
symindex
].
sh_addr
;
/* The small sections were sorted to the end of the segment.
The following should definitely cover them. */
gp
=
(
u64
)
me
->
module_core
+
me
->
core_size
-
0x8000
;
got
=
sechdrs
[
me
->
arch
.
gotsecindex
].
sh_addr
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
unsigned
long
r_sym
=
ELF64_R_SYM
(
rela
[
i
].
r_info
);
unsigned
long
r_type
=
ELF64_R_TYPE
(
rela
[
i
].
r_info
);
unsigned
long
r_got_offset
=
r_type
>>
8
;
unsigned
long
value
,
hi
,
lo
;
r_type
&=
0xff
;
/* This is where to make the change. */
location
=
base
+
rela
[
i
].
r_offset
;
/* This is the symbol it is referring to. */
sym
=
symtab
+
r_sym
;
value
=
sym
->
st_value
;
if
(
!
value
)
{
printk
(
KERN_ERR
"module %s: Unknown symbol %s
\n
"
,
me
->
name
,
strtab
+
sym
->
st_name
);
return
-
ENOENT
;
}
value
+=
rela
[
i
].
r_addend
;
switch
(
r_type
)
{
case
R_ALPHA_NONE
:
break
;
case
R_ALPHA_REFQUAD
:
*
(
u64
*
)
location
=
value
;
break
;
case
R_ALPHA_GPREL32
:
value
-=
gp
;
if
((
int
)
value
!=
value
)
goto
reloc_overflow
;
*
(
u32
*
)
location
=
value
;
break
;
case
R_ALPHA_LITERAL
:
hi
=
got
+
r_got_offset
;
lo
=
hi
-
gp
;
if
((
short
)
lo
!=
lo
)
goto
reloc_overflow
;
*
(
u16
*
)
location
=
lo
;
*
(
u64
*
)
hi
=
value
;
break
;
case
R_ALPHA_LITUSE
:
break
;
case
R_ALPHA_GPDISP
:
value
=
gp
-
(
u64
)
location
;
lo
=
(
short
)
value
;
hi
=
(
int
)(
value
-
lo
);
if
(
hi
+
lo
!=
value
)
goto
reloc_overflow
;
*
(
u16
*
)
location
=
hi
>>
16
;
*
(
u16
*
)(
location
+
rela
[
i
].
r_addend
)
=
lo
;
break
;
case
R_ALPHA_BRSGP
:
/* BRSGP is only allowed to bind to local symbols.
If the section is undef, this means that the
value was resolved from somewhere else. */
if
(
sym
->
st_shndx
==
SHN_UNDEF
)
goto
reloc_overflow
;
/* FALLTHRU */
case
R_ALPHA_BRADDR
:
value
-=
(
u64
)
location
+
4
;
if
(
value
&
3
)
goto
reloc_overflow
;
value
=
(
long
)
value
>>
2
;
if
(
value
+
(
1
<<
21
)
>=
1
<<
22
)
goto
reloc_overflow
;
value
&=
0x1fffff
;
value
|=
*
(
u32
*
)
location
&
~
0x1fffff
;
*
(
u32
*
)
location
=
value
;
break
;
case
R_ALPHA_HINT
:
break
;
case
R_ALPHA_SREL32
:
value
-=
(
u64
)
location
;
if
((
int
)
value
!=
value
)
goto
reloc_overflow
;
*
(
u32
*
)
location
=
value
;
break
;
case
R_ALPHA_SREL64
:
value
-=
(
u64
)
location
;
*
(
u64
*
)
location
=
value
;
break
;
case
R_ALPHA_GPRELHIGH
:
value
=
(
value
-
gp
+
0x8000
)
>>
16
;
if
((
short
)
value
!=
value
)
goto
reloc_overflow
;
*
(
u16
*
)
location
=
value
;
break
;
case
R_ALPHA_GPRELLOW
:
value
-=
gp
;
*
(
u16
*
)
location
=
value
;
break
;
case
R_ALPHA_GPREL16
:
value
-=
gp
;
if
((
short
)
value
!=
value
)
goto
reloc_overflow
;
*
(
u16
*
)
location
=
value
;
break
;
default:
printk
(
KERN_ERR
"module %s: Unknown relocation: %lu
\n
"
,
me
->
name
,
r_type
);
return
-
ENOEXEC
;
reloc_overflow:
if
(
ELF64_ST_TYPE
(
sym
->
st_info
)
==
STT_SECTION
)
printk
(
KERN_ERR
"module %s: Relocation overflow vs section %d
\n
"
,
me
->
name
,
sym
->
st_shndx
);
else
printk
(
KERN_ERR
"module %s: Relocation overflow vs %s
\n
"
,
me
->
name
,
strtab
+
sym
->
st_name
);
return
-
ENOEXEC
;
}
}
return
0
;
}
int
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
me
)
{
return
0
;
}
arch/alpha/mm/extable.c
View file @
bca2be21
...
@@ -38,18 +38,18 @@ search_exception_table(unsigned long addr)
...
@@ -38,18 +38,18 @@ search_exception_table(unsigned long addr)
#ifndef CONFIG_MODULES
#ifndef CONFIG_MODULES
ret
=
search_one_table
(
__start___ex_table
,
__stop___ex_table
-
1
,
addr
);
ret
=
search_one_table
(
__start___ex_table
,
__stop___ex_table
-
1
,
addr
);
#else
#else
extern
spinlock_t
modlist_lock
;
unsigned
long
flags
;
unsigned
long
flags
;
/* The kernel is the last "module" -- no need to treat it special. */
struct
list_head
*
i
;
struct
module
*
mp
;
ret
=
0
;
ret
=
0
;
spin_lock_irqsave
(
&
modlist_lock
,
flags
);
spin_lock_irqsave
(
&
modlist_lock
,
flags
);
for
(
mp
=
module_list
;
mp
;
mp
=
mp
->
next
)
{
list_for_each
(
i
,
&
extables
)
{
if
(
!
mp
->
ex_table_start
||
!
(
mp
->
flags
&
(
MOD_RUNNING
|
MOD_INITIALIZING
)))
struct
exception_table
*
ex
=
list_entry
(
i
,
struct
exception_table
,
list
);
if
(
ex
->
num_entries
==
0
)
continue
;
continue
;
ret
=
search_one_table
(
mp
->
ex_table_start
,
ret
=
search_one_table
(
ex
->
entry
,
mp
->
ex_table_end
-
1
,
addr
);
ex
->
entry
+
ex
->
num_entries
-
1
,
addr
);
if
(
ret
)
if
(
ret
)
break
;
break
;
}
}
...
...
include/asm-alpha/module.h
View file @
bca2be21
#ifndef _A
SM_A
LPHA_MODULE_H
#ifndef _ALPHA_MODULE_H
#define _A
SM_A
LPHA_MODULE_H
#define _ALPHA_MODULE_H
/* Module rewrite still in progress. */
struct
mod_arch_specific
{
unsigned
int
gotsecindex
;
};
#endif
/* _ASM_ALPHA_MODULE_H */
#define Elf_Sym Elf64_Sym
#define Elf_Shdr Elf64_Shdr
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Phdr Elf64_Phdr
#define Elf_Dyn Elf64_Dyn
#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
#define ARCH_SHF_SMALL SHF_ALPHA_GPREL
#ifdef MODULE
asm
(
".section .got,
\"
aws
\"
,@nobits; .align 3; .previous"
);
#endif
#endif
/*_ALPHA_MODULE_H*/
include/linux/elf.h
View file @
bca2be21
...
@@ -159,6 +159,9 @@ typedef __s64 Elf64_Sxword;
...
@@ -159,6 +159,9 @@ typedef __s64 Elf64_Sxword;
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF64_ST_BIND(x) ((x) >> 4)
#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
/* Symbolic values for the entries in the auxiliary table
/* Symbolic values for the entries in the auxiliary table
put on the initial stack */
put on the initial stack */
#define AT_NULL 0
/* end of vector */
#define AT_NULL 0
/* end of vector */
...
@@ -362,22 +365,30 @@ typedef struct {
...
@@ -362,22 +365,30 @@ typedef struct {
#define R_ALPHA_SREL16 9
/* PC relative 16 bit */
#define R_ALPHA_SREL16 9
/* PC relative 16 bit */
#define R_ALPHA_SREL32 10
/* PC relative 32 bit */
#define R_ALPHA_SREL32 10
/* PC relative 32 bit */
#define R_ALPHA_SREL64 11
/* PC relative 64 bit */
#define R_ALPHA_SREL64 11
/* PC relative 64 bit */
#define R_ALPHA_OP_PUSH 12
/* OP stack push */
#define R_ALPHA_GPRELHIGH 17
/* GP relative 32 bit, high 16 bits */
#define R_ALPHA_OP_STORE 13
/* OP stack pop and store */
#define R_ALPHA_GPRELLOW 18
/* GP relative 32 bit, low 16 bits */
#define R_ALPHA_OP_PSUB 14
/* OP stack subtract */
#define R_ALPHA_GPREL16 19
/* GP relative 16 bit */
#define R_ALPHA_OP_PRSHIFT 15
/* OP stack right shift */
#define R_ALPHA_GPVALUE 16
#define R_ALPHA_GPRELHIGH 17
#define R_ALPHA_GPRELLOW 18
#define R_ALPHA_IMMED_GP_16 19
#define R_ALPHA_IMMED_GP_HI32 20
#define R_ALPHA_IMMED_SCN_HI32 21
#define R_ALPHA_IMMED_BR_HI32 22
#define R_ALPHA_IMMED_LO32 23
#define R_ALPHA_COPY 24
/* Copy symbol at runtime */
#define R_ALPHA_COPY 24
/* Copy symbol at runtime */
#define R_ALPHA_GLOB_DAT 25
/* Create GOT entry */
#define R_ALPHA_GLOB_DAT 25
/* Create GOT entry */
#define R_ALPHA_JMP_SLOT 26
/* Create PLT entry */
#define R_ALPHA_JMP_SLOT 26
/* Create PLT entry */
#define R_ALPHA_RELATIVE 27
/* Adjust by program base */
#define R_ALPHA_RELATIVE 27
/* Adjust by program base */
#define R_ALPHA_BRSGP 28
#define R_ALPHA_TLSGD 29
#define R_ALPHA_TLS_LDM 30
#define R_ALPHA_DTPMOD64 31
#define R_ALPHA_GOTDTPREL 32
#define R_ALPHA_DTPREL64 33
#define R_ALPHA_DTPRELHI 34
#define R_ALPHA_DTPRELLO 35
#define R_ALPHA_DTPREL16 36
#define R_ALPHA_GOTTPREL 37
#define R_ALPHA_TPREL64 38
#define R_ALPHA_TPRELHI 39
#define R_ALPHA_TPRELLO 40
#define R_ALPHA_TPREL16 41
#define SHF_ALPHA_GPREL 0x10000000
/* PowerPC relocations defined by the ABIs */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_NONE 0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment