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
Kirill Smelkov
linux
Commits
9a180727
Commit
9a180727
authored
Feb 23, 2003
by
Martin Schwidefsky
Committed by
Linus Torvalds
Feb 23, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] s390: kernel module loader.
Add missing/fix existing s390 relocations in the kernel module loader.
parent
eebba6ad
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
693 additions
and
250 deletions
+693
-250
arch/s390/kernel/module.c
arch/s390/kernel/module.c
+276
-85
arch/s390x/kernel/module.c
arch/s390x/kernel/module.c
+302
-102
include/asm-s390/module.h
include/asm-s390/module.h
+20
-2
include/asm-s390x/module.h
include/asm-s390x/module.h
+20
-2
include/linux/elf.h
include/linux/elf.h
+75
-59
No files found.
arch/s390/kernel/module.c
View file @
9a180727
...
...
@@ -2,7 +2,8 @@
* arch/s390/kernel/module.c - Kernel module help for s390.
*
* S390 version
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
...
...
@@ -36,6 +37,9 @@
#define DEBUGP(fmt , ...)
#endif
#define GOT_ENTRY_SIZE 4
#define PLT_ENTRY_SIZE 12
void
*
module_alloc
(
unsigned
long
size
)
{
if
(
size
==
0
)
...
...
@@ -51,109 +55,296 @@ void module_free(struct module *mod, void *module_region)
table entries. */
}
int
module_frob_arch_sections
(
Elf_Ehdr
*
hdr
,
Elf_Shdr
*
sechdrs
,
char
*
secstrings
,
struct
module
*
mod
)
static
inline
void
check_rela
(
Elf32_Rela
*
rela
,
struct
module
*
me
)
{
// FIXME: add space needed for GOT/PLT
struct
mod_arch_syminfo
*
info
;
info
=
me
->
arch
.
syminfo
+
ELF32_R_SYM
(
rela
->
r_info
);
switch
(
ELF32_R_TYPE
(
rela
->
r_info
))
{
case
R_390_GOT12
:
/* 12 bit GOT offset. */
case
R_390_GOT16
:
/* 16 bit GOT offset. */
case
R_390_GOT32
:
/* 32 bit GOT offset. */
case
R_390_GOTENT
:
/* 32 bit PC rel. to GOT entry shifted by 1. */
case
R_390_GOTPLT12
:
/* 12 bit offset to jump slot. */
case
R_390_GOTPLT16
:
/* 16 bit offset to jump slot. */
case
R_390_GOTPLT32
:
/* 32 bit offset to jump slot. */
case
R_390_GOTPLTENT
:
/* 32 bit rel. offset to jump slot >> 1. */
if
(
info
->
got_offset
==
-
1UL
)
{
info
->
got_offset
=
me
->
arch
.
got_size
;
me
->
arch
.
got_size
+=
GOT_ENTRY_SIZE
;
}
break
;
case
R_390_PLT16DBL
:
/* 16 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32DBL
:
/* 32 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32
:
/* 32 bit PC relative PLT address. */
case
R_390_PLTOFF16
:
/* 16 bit offset from GOT to PLT. */
case
R_390_PLTOFF32
:
/* 32 bit offset from GOT to PLT. */
if
(
info
->
plt_offset
==
-
1UL
)
{
info
->
plt_offset
=
me
->
arch
.
plt_size
;
me
->
arch
.
plt_size
+=
PLT_ENTRY_SIZE
;
}
break
;
case
R_390_COPY
:
case
R_390_GLOB_DAT
:
case
R_390_JMP_SLOT
:
case
R_390_RELATIVE
:
/* Only needed if we want to support loading of
modules linked with -shared. */
break
;
}
}
/*
* Account for GOT and PLT relocations. We can't add sections for
* got and plt but we can increase the core module size.
*/
int
module_frob_arch_sections
(
Elf32_Ehdr
*
hdr
,
Elf32_Shdr
*
sechdrs
,
char
*
secstrings
,
struct
module
*
me
)
{
Elf32_Shdr
*
symtab
;
Elf32_Sym
*
symbols
;
Elf32_Rela
*
rela
;
char
*
strings
;
int
nrela
,
i
,
j
;
/* Find symbol table and string table. */
symtab
=
0
;
for
(
i
=
0
;
i
<
hdr
->
e_shnum
;
i
++
)
switch
(
sechdrs
[
i
].
sh_type
)
{
case
SHT_SYMTAB
:
symtab
=
sechdrs
+
i
;
break
;
}
if
(
!
symtab
)
{
printk
(
KERN_ERR
"module %s: no symbol table
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
/* Allocate one syminfo structure per symbol. */
me
->
arch
.
nsyms
=
symtab
->
sh_size
/
sizeof
(
Elf32_Sym
);
me
->
arch
.
syminfo
=
kmalloc
(
me
->
arch
.
nsyms
*
sizeof
(
struct
mod_arch_syminfo
),
GFP_KERNEL
);
if
(
!
me
->
arch
.
syminfo
)
return
-
ENOMEM
;
symbols
=
(
void
*
)
hdr
+
symtab
->
sh_offset
;
strings
=
(
void
*
)
hdr
+
sechdrs
[
symtab
->
sh_link
].
sh_offset
;
for
(
i
=
0
;
i
<
me
->
arch
.
nsyms
;
i
++
)
{
if
(
symbols
[
i
].
st_shndx
==
SHN_UNDEF
&&
strcmp
(
strings
+
symbols
[
i
].
st_name
,
"_GLOBAL_OFFSET_TABLE_"
)
==
0
)
/* "Define" it as absolute. */
symbols
[
i
].
st_shndx
=
SHN_ABS
;
me
->
arch
.
syminfo
[
i
].
got_offset
=
-
1UL
;
me
->
arch
.
syminfo
[
i
].
plt_offset
=
-
1UL
;
me
->
arch
.
syminfo
[
i
].
got_initialized
=
0
;
me
->
arch
.
syminfo
[
i
].
plt_initialized
=
0
;
}
/* Search for got/plt relocations. */
me
->
arch
.
got_size
=
me
->
arch
.
plt_size
=
0
;
for
(
i
=
0
;
i
<
hdr
->
e_shnum
;
i
++
)
{
if
(
sechdrs
[
i
].
sh_type
!=
SHT_RELA
)
continue
;
nrela
=
sechdrs
[
i
].
sh_size
/
sizeof
(
Elf32_Rela
);
rela
=
(
void
*
)
hdr
+
sechdrs
[
i
].
sh_offset
;
for
(
j
=
0
;
j
<
nrela
;
j
++
)
check_rela
(
rela
+
j
,
me
);
}
/* Increase core size by size of got & plt and set start
offsets for got and plt. */
me
->
core_size
=
ALIGN
(
me
->
core_size
,
4
);
me
->
arch
.
got_offset
=
me
->
core_size
;
me
->
core_size
+=
me
->
arch
.
got_size
;
me
->
arch
.
plt_offset
=
me
->
core_size
;
me
->
core_size
+=
me
->
arch
.
plt_size
;
return
0
;
}
int
apply_relocate
(
Elf_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
int
apply_relocate
(
Elf_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
printk
(
KERN_ERR
"module %s: RELOCATION unsupported
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
static
inline
int
apply_rela
(
Elf32_Rela
*
rela
,
Elf32_Addr
base
,
Elf32_Sym
*
symtab
,
struct
module
*
me
)
{
unsigned
int
i
;
ElfW
(
Rel
)
*
rel
=
(
void
*
)
sechdrs
[
relsec
].
sh_addr
;
ElfW
(
Sym
)
*
sym
;
ElfW
(
Addr
)
*
location
;
DEBUGP
(
"Applying relocate section %u to %u
\n
"
,
relsec
,
sechdrs
[
relsec
].
sh_info
);
for
(
i
=
0
;
i
<
sechdrs
[
relsec
].
sh_size
/
sizeof
(
*
rel
);
i
++
)
{
struct
mod_arch_syminfo
*
info
;
Elf32_Addr
loc
,
val
;
int
r_type
,
r_sym
;
/* This is where to make the change */
location
=
(
void
*
)
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_addr
+
rel
[
i
].
r_offset
;
loc
=
base
+
rela
->
r_offset
;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym
=
(
ElfW
(
Sym
)
*
)
sechdrs
[
symindex
].
sh_addr
+
ELFW
(
R_SYM
)(
rel
[
i
].
r_info
);
r_sym
=
ELF32_R_SYM
(
rela
->
r_info
);
r_type
=
ELF32_R_TYPE
(
rela
->
r_info
);
info
=
me
->
arch
.
syminfo
+
r_sym
;
val
=
symtab
[
r_sym
].
st_value
;
switch
(
ELF_R_TYPE
(
rel
[
i
].
r_info
)
)
{
switch
(
r_type
)
{
case
R_390_8
:
/* Direct 8 bit. */
*
(
u8
*
)
location
+=
sym
->
st_value
;
break
;
case
R_390_12
:
/* Direct 12 bit. */
*
(
u16
*
)
location
=
(
*
(
u16
*
)
location
&
0xf000
)
|
(
sym
->
st_value
&
0xfff
);
break
;
case
R_390_16
:
/* Direct 16 bit. */
*
(
u16
*
)
location
+=
sym
->
st_value
;
break
;
case
R_390_32
:
/* Direct 32 bit. */
*
(
u32
*
)
location
+=
sym
->
st_value
;
val
+=
rela
->
r_addend
;
if
(
r_type
==
R_390_8
)
*
(
unsigned
char
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_12
)
*
(
unsigned
short
*
)
loc
=
(
val
&
0xfff
)
|
(
*
(
unsigned
short
*
)
loc
&
0xf000
);
else
if
(
r_type
==
R_390_16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_32
)
*
(
unsigned
int
*
)
loc
=
val
;
break
;
case
R_390_PC16
:
/* PC relative 16 bit. */
*
(
u16
*
)
location
+=
sym
->
st_value
-
(
unsigned
long
)
location
;
case
R_390_PC16DBL
:
/* PC relative 16 bit shifted by 1. */
*
(
u16
*
)
location
+=
(
sym
->
st_value
-
(
unsigned
long
)
location
)
>>
1
;
case
R_390_PC32DBL
:
/* PC relative 32 bit shifted by 1. */
case
R_390_PC32
:
/* PC relative 32 bit. */
*
(
u32
*
)
location
+=
sym
->
st_value
-
(
unsigned
long
)
location
;
val
+=
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_PC16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PC16DBL
)
*
(
unsigned
short
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PC32DBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PC32
)
*
(
unsigned
int
*
)
loc
=
val
;
break
;
case
R_390_GOT12
:
/* 12 bit GOT offset. */
case
R_390_GOT16
:
/* 16 bit GOT offset. */
case
R_390_GOT32
:
/* 32 bit GOT offset. */
// FIXME: TODO
case
R_390_GOTENT
:
/* 32 bit PC rel. to GOT entry shifted by 1. */
case
R_390_GOTPLT12
:
/* 12 bit offset to jump slot. */
case
R_390_GOTPLT16
:
/* 16 bit offset to jump slot. */
case
R_390_GOTPLT32
:
/* 32 bit offset to jump slot. */
case
R_390_GOTPLTENT
:
/* 32 bit rel. offset to jump slot >> 1. */
if
(
info
->
got_initialized
==
0
)
{
Elf32_Addr
*
gotent
;
gotent
=
me
->
module_core
+
me
->
arch
.
got_offset
+
info
->
got_offset
;
*
gotent
=
val
;
info
->
got_initialized
=
1
;
}
val
=
info
->
got_offset
+
rela
->
r_addend
;
if
(
r_type
==
R_390_GOT12
||
r_type
==
R_390_GOTPLT12
)
*
(
unsigned
short
*
)
loc
=
(
val
&
0xfff
)
|
(
*
(
unsigned
short
*
)
loc
&
0xf000
);
else
if
(
r_type
==
R_390_GOT16
||
r_type
==
R_390_GOTPLT16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOT32
||
r_type
==
R_390_GOTPLT32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTENT
||
r_type
==
R_390_GOTPLTENT
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
break
;
case
R_390_PLT16DBL
:
/* 16 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32DBL
:
/* 32 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32
:
/* 32 bit PC relative PLT address. */
// FIXME: TODO
case
R_390_PLTOFF16
:
/* 16 bit offset from GOT to PLT. */
case
R_390_PLTOFF32
:
/* 32 bit offset from GOT to PLT. */
if
(
info
->
plt_initialized
==
0
)
{
unsigned
int
*
ip
;
ip
=
me
->
module_core
+
me
->
arch
.
plt_offset
+
info
->
plt_offset
;
ip
[
0
]
=
0x0d105810
;
/* basr 1,0; l 1,6(1); br 1 */
ip
[
1
]
=
0x100607f1
;
ip
[
2
]
=
val
;
info
->
plt_initialized
=
1
;
}
if
(
r_type
==
R_390_PLTOFF16
||
r_type
==
R_390_PLTOFF32
)
val
=
me
->
arch
.
plt_offset
-
me
->
arch
.
got_offset
+
info
->
plt_offset
+
rela
->
r_addend
;
else
val
=
(
Elf32_Addr
)
me
->
module_core
+
me
->
arch
.
plt_offset
+
info
->
plt_offset
+
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_PLT16DBL
)
*
(
unsigned
short
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PLTOFF16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PLT32DBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PLT32
||
r_type
==
R_390_PLTOFF32
)
*
(
unsigned
int
*
)
loc
=
val
;
break
;
case
R_390_GOTOFF16
:
/* 16 bit offset to GOT. */
case
R_390_GOTOFF32
:
/* 32 bit offset to GOT. */
val
=
val
+
rela
->
r_addend
-
((
Elf32_Addr
)
me
->
module_core
+
me
->
arch
.
got_offset
);
if
(
r_type
==
R_390_GOTOFF16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTOFF32
)
*
(
unsigned
int
*
)
loc
=
val
;
break
;
case
R_390_GOTPC
:
/* 32 bit PC relative offset to GOT. */
case
R_390_GOTPCDBL
:
/* 32 bit PC rel. off. to GOT shifted by 1. */
val
=
(
Elf32_Addr
)
me
->
module_core
+
me
->
arch
.
got_offset
+
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_GOTPC
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTPCDBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
break
;
case
R_390_COPY
:
case
R_390_GLOB_DAT
:
/* Create GOT entry. */
case
R_390_JMP_SLOT
:
/* Create PLT entry. */
*
location
=
sym
->
st_value
;
break
;
case
R_390_RELATIVE
:
/* Adjust by program base. */
// FIXME: TODO
break
;
case
R_390_GOTOFF
:
/* 32 bit offset to GOT. */
// FIXME: TODO
break
;
case
R_390_GOTPC
:
/* 32 bit PC relative offset to GOT. */
// FIXME: TODO
/* Only needed if we want to support loading of
modules linked with -shared. */
break
;
default:
printk
(
KERN_ERR
"module %s: Unknown relocation: %lu
\n
"
,
me
->
name
,
(
unsigned
long
)
ELF_R_TYPE
(
rel
[
i
].
r_info
));
printk
(
KERN_ERR
"module %s: Unknown relocation: %u
\n
"
,
me
->
name
,
r_type
);
return
-
ENOEXEC
;
}
}
return
0
;
}
int
apply_relocate_add
(
Elf32_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
int
apply_relocate_add
(
Elf32_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
printk
(
KERN_ERR
"module %s: ADD RELOCATION unsupported
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
Elf32_Addr
base
;
Elf32_Sym
*
symtab
;
Elf32_Rela
*
rela
;
unsigned
long
i
,
n
;
int
rc
;
DEBUGP
(
"Applying relocate section %u to %u
\n
"
,
relsec
,
sechdrs
[
relsec
].
sh_info
);
base
=
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_addr
;
symtab
=
(
Elf32_Sym
*
)
sechdrs
[
symindex
].
sh_addr
;
rela
=
(
Elf32_Rela
*
)
sechdrs
[
relsec
].
sh_addr
;
n
=
sechdrs
[
relsec
].
sh_size
/
sizeof
(
Elf32_Rela
);
for
(
i
=
0
;
i
<
n
;
i
++
,
rela
++
)
{
rc
=
apply_rela
(
rela
,
base
,
symtab
,
me
);
if
(
rc
)
return
rc
;
}
return
0
;
}
int
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
me
)
{
if
(
me
->
arch
.
syminfo
)
kfree
(
me
->
arch
.
syminfo
);
return
0
;
}
arch/s390x/kernel/module.c
View file @
9a180727
...
...
@@ -2,7 +2,8 @@
* arch/s390x/kernel/module.c - Kernel module help for s390x.
*
* S390 version
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
...
...
@@ -36,6 +37,9 @@
#define DEBUGP(fmt , ...)
#endif
#define GOT_ENTRY_SIZE 8
#define PLT_ENTRY_SIZE 20
void
*
module_alloc
(
unsigned
long
size
)
{
if
(
size
==
0
)
...
...
@@ -51,126 +55,322 @@ void module_free(struct module *mod, void *module_region)
table entries. */
}
/* s390/s390x needs additional memory for GOT/PLT sections. */
int
module_frob_arch_sections
(
Elf_Ehdr
*
hdr
,
Elf_Shdr
*
sechdrs
,
char
*
secstrings
,
struct
module
*
mod
)
static
inline
void
check_rela
(
Elf64_Rela
*
rela
,
struct
module
*
me
)
{
struct
mod_arch_syminfo
*
info
;
info
=
me
->
arch
.
syminfo
+
ELF64_R_SYM
(
rela
->
r_info
);
switch
(
ELF64_R_TYPE
(
rela
->
r_info
))
{
case
R_390_GOT12
:
/* 12 bit GOT offset. */
case
R_390_GOT16
:
/* 16 bit GOT offset. */
case
R_390_GOT32
:
/* 32 bit GOT offset. */
case
R_390_GOT64
:
/* 64 bit GOT offset. */
case
R_390_GOTENT
:
/* 32 bit PC rel. to GOT entry shifted by 1. */
case
R_390_GOTPLT12
:
/* 12 bit offset to jump slot. */
case
R_390_GOTPLT16
:
/* 16 bit offset to jump slot. */
case
R_390_GOTPLT32
:
/* 32 bit offset to jump slot. */
case
R_390_GOTPLT64
:
/* 64 bit offset to jump slot. */
case
R_390_GOTPLTENT
:
/* 32 bit rel. offset to jump slot >> 1. */
if
(
info
->
got_offset
==
-
1UL
)
{
info
->
got_offset
=
me
->
arch
.
got_size
;
me
->
arch
.
got_size
+=
GOT_ENTRY_SIZE
;
}
break
;
case
R_390_PLT16DBL
:
/* 16 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32DBL
:
/* 32 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32
:
/* 32 bit PC relative PLT address. */
case
R_390_PLT64
:
/* 64 bit PC relative PLT address. */
case
R_390_PLTOFF16
:
/* 16 bit offset from GOT to PLT. */
case
R_390_PLTOFF32
:
/* 32 bit offset from GOT to PLT. */
case
R_390_PLTOFF64
:
/* 16 bit offset from GOT to PLT. */
if
(
info
->
plt_offset
==
-
1UL
)
{
info
->
plt_offset
=
me
->
arch
.
plt_size
;
me
->
arch
.
plt_size
+=
PLT_ENTRY_SIZE
;
}
break
;
case
R_390_COPY
:
case
R_390_GLOB_DAT
:
case
R_390_JMP_SLOT
:
case
R_390_RELATIVE
:
/* Only needed if we want to support loading of
modules linked with -shared. */
break
;
}
}
/*
* Account for GOT and PLT relocations. We can't add sections for
* got and plt but we can increase the core module size.
*/
int
module_frob_arch_sections
(
Elf64_Ehdr
*
hdr
,
Elf64_Shdr
*
sechdrs
,
char
*
secstrings
,
struct
module
*
me
)
{
// FIXME: add space needed for GOT/PLT
Elf64_Shdr
*
symtab
;
Elf64_Sym
*
symbols
;
Elf64_Rela
*
rela
;
char
*
strings
;
int
nrela
,
i
,
j
;
/* Find symbol table and string table. */
symtab
=
0
;
for
(
i
=
0
;
i
<
hdr
->
e_shnum
;
i
++
)
switch
(
sechdrs
[
i
].
sh_type
)
{
case
SHT_SYMTAB
:
symtab
=
sechdrs
+
i
;
break
;
}
if
(
!
symtab
)
{
printk
(
KERN_ERR
"module %s: no symbol table
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
/* Allocate one syminfo structure per symbol. */
me
->
arch
.
nsyms
=
symtab
->
sh_size
/
sizeof
(
Elf64_Sym
);
me
->
arch
.
syminfo
=
kmalloc
(
me
->
arch
.
nsyms
*
sizeof
(
struct
mod_arch_syminfo
),
GFP_KERNEL
);
if
(
!
me
->
arch
.
syminfo
)
return
-
ENOMEM
;
symbols
=
(
void
*
)
hdr
+
symtab
->
sh_offset
;
strings
=
(
void
*
)
hdr
+
sechdrs
[
symtab
->
sh_link
].
sh_offset
;
for
(
i
=
0
;
i
<
me
->
arch
.
nsyms
;
i
++
)
{
if
(
symbols
[
i
].
st_shndx
==
SHN_UNDEF
&&
strcmp
(
strings
+
symbols
[
i
].
st_name
,
"_GLOBAL_OFFSET_TABLE_"
)
==
0
)
/* "Define" it as absolute. */
symbols
[
i
].
st_shndx
=
SHN_ABS
;
me
->
arch
.
syminfo
[
i
].
got_offset
=
-
1UL
;
me
->
arch
.
syminfo
[
i
].
plt_offset
=
-
1UL
;
me
->
arch
.
syminfo
[
i
].
got_initialized
=
0
;
me
->
arch
.
syminfo
[
i
].
plt_initialized
=
0
;
}
/* Search for got/plt relocations. */
me
->
arch
.
got_size
=
me
->
arch
.
plt_size
=
0
;
for
(
i
=
0
;
i
<
hdr
->
e_shnum
;
i
++
)
{
if
(
sechdrs
[
i
].
sh_type
!=
SHT_RELA
)
continue
;
nrela
=
sechdrs
[
i
].
sh_size
/
sizeof
(
Elf64_Rela
);
rela
=
(
void
*
)
hdr
+
sechdrs
[
i
].
sh_offset
;
for
(
j
=
0
;
j
<
nrela
;
j
++
)
check_rela
(
rela
+
j
,
me
);
}
/* Increase core size by size of got & plt and set start
offsets for got and plt. */
me
->
core_size
=
ALIGN
(
me
->
core_size
,
4
);
me
->
arch
.
got_offset
=
me
->
core_size
;
me
->
core_size
+=
me
->
arch
.
got_size
;
me
->
arch
.
plt_offset
=
me
->
core_size
;
me
->
core_size
+=
me
->
arch
.
plt_size
;
return
0
;
}
int
apply_relocate
(
Elf_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
int
apply_relocate
(
Elf_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
printk
(
KERN_ERR
"module %s: RELOCATION unsupported
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
}
static
inline
int
apply_rela
(
Elf64_Rela
*
rela
,
Elf64_Addr
base
,
Elf64_Sym
*
symtab
,
struct
module
*
me
)
{
unsigned
int
i
;
ElfW
(
Rel
)
*
rel
=
(
void
*
)
sechdrs
[
relsec
].
sh_addr
;
ElfW
(
Sym
)
*
sym
;
ElfW
(
Addr
)
*
location
;
DEBUGP
(
"Applying relocate section %u to %u
\n
"
,
relsec
,
sechdrs
[
relsec
].
sh_info
);
for
(
i
=
0
;
i
<
sechdrs
[
relsec
].
sh_size
/
sizeof
(
*
rel
);
i
++
)
{
struct
mod_arch_syminfo
*
info
;
Elf64_Addr
loc
,
val
;
int
r_type
,
r_sym
;
/* This is where to make the change */
location
=
(
void
*
)
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_addr
+
rel
[
i
].
r_offset
;
loc
=
base
+
rela
->
r_offset
;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym
=
(
ElfW
(
Sym
)
*
)
sechdrs
[
symindex
].
sh_addr
+
ELFW
(
R_SYM
)(
rel
[
i
].
r_info
);
r_sym
=
ELF64_R_SYM
(
rela
->
r_info
);
r_type
=
ELF64_R_TYPE
(
rela
->
r_info
);
info
=
me
->
arch
.
syminfo
+
r_sym
;
val
=
symtab
[
r_sym
].
st_value
;
switch
(
ELF_R_TYPE
(
rel
[
i
].
r_info
)
)
{
switch
(
r_type
)
{
case
R_390_8
:
/* Direct 8 bit. */
*
(
u8
*
)
location
+=
sym
->
st_value
;
break
;
case
R_390_12
:
/* Direct 12 bit. */
*
(
u16
*
)
location
=
(
*
(
u16
*
)
location
&
0xf000
)
|
(
sym
->
st_value
&
0xfff
);
break
;
case
R_390_16
:
/* Direct 16 bit. */
*
(
u16
*
)
location
+=
sym
->
st_value
;
break
;
case
R_390_32
:
/* Direct 32 bit. */
*
(
u32
*
)
location
+=
sym
->
st_value
;
break
;
case
R_390_64
:
/* Direct 64 bit. */
*
(
u64
*
)
location
+=
sym
->
st_value
;
val
+=
rela
->
r_addend
;
if
(
r_type
==
R_390_8
)
*
(
unsigned
char
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_12
)
*
(
unsigned
short
*
)
loc
=
(
val
&
0xfff
)
|
(
*
(
unsigned
short
*
)
loc
&
0xf000
);
else
if
(
r_type
==
R_390_16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_64
)
*
(
unsigned
long
*
)
loc
=
val
;
break
;
case
R_390_PC16
:
/* PC relative 16 bit. */
*
(
u16
*
)
location
+=
sym
->
st_value
-
(
unsigned
long
)
location
;
case
R_390_PC16DBL
:
/* PC relative 16 bit shifted by 1. */
*
(
u16
*
)
location
+=
(
sym
->
st_value
-
(
unsigned
long
)
location
)
>>
1
;
case
R_390_PC32
:
/* PC relative 32 bit. */
*
(
u32
*
)
location
+=
sym
->
st_value
-
(
unsigned
long
)
location
;
break
;
case
R_390_PC32DBL
:
/* PC relative 32 bit shifted by 1. */
*
(
u32
*
)
location
+=
(
sym
->
st_value
-
(
unsigned
long
)
location
)
>>
1
;
break
;
case
R_390_PC32
:
/* PC relative 32 bit. */
case
R_390_PC64
:
/* PC relative 64 bit. */
*
(
u64
*
)
location
+=
sym
->
st_value
-
(
unsigned
long
)
location
;
val
+=
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_PC16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PC16DBL
)
*
(
unsigned
short
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PC32DBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PC32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PC64
)
*
(
unsigned
long
*
)
loc
=
val
;
break
;
case
R_390_GOT12
:
/* 12 bit GOT offset. */
case
R_390_GOT16
:
/* 16 bit GOT offset. */
case
R_390_GOT32
:
/* 32 bit GOT offset. */
case
R_390_GOT64
:
/* 64 bit GOT offset. */
case
R_390_GOTENT
:
/* 32 bit PC rel. to GOT entry >> 1. */
// FIXME: TODO
case
R_390_GOTENT
:
/* 32 bit PC rel. to GOT entry shifted by 1. */
case
R_390_GOTPLT12
:
/* 12 bit offset to jump slot. */
case
R_390_GOTPLT16
:
/* 16 bit offset to jump slot. */
case
R_390_GOTPLT32
:
/* 32 bit offset to jump slot. */
case
R_390_GOTPLT64
:
/* 64 bit offset to jump slot. */
case
R_390_GOTPLTENT
:
/* 32 bit rel. offset to jump slot >> 1. */
if
(
info
->
got_initialized
==
0
)
{
Elf64_Addr
*
gotent
;
gotent
=
me
->
module_core
+
me
->
arch
.
got_offset
+
info
->
got_offset
;
*
gotent
=
val
;
info
->
got_initialized
=
1
;
}
val
=
info
->
got_offset
+
rela
->
r_addend
;
if
(
r_type
==
R_390_GOT12
||
r_type
==
R_390_GOTPLT12
)
*
(
unsigned
short
*
)
loc
=
(
val
&
0xfff
)
|
(
*
(
unsigned
short
*
)
loc
&
0xf000
);
else
if
(
r_type
==
R_390_GOT16
||
r_type
==
R_390_GOTPLT16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOT32
||
r_type
==
R_390_GOTPLT32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTENT
||
r_type
==
R_390_GOTPLTENT
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_GOT64
||
r_type
==
R_390_GOTPLT64
)
*
(
unsigned
long
*
)
loc
=
val
;
break
;
case
R_390_PLT16DBL
:
/* 16 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32
:
/* 32 bit PC relative PLT address. */
case
R_390_PLT32DBL
:
/* 32 bit PC rel. PLT shifted by 1. */
case
R_390_PLT32
:
/* 32 bit PC relative PLT address. */
case
R_390_PLT64
:
/* 64 bit PC relative PLT address. */
// FIXME: TODO
case
R_390_PLTOFF16
:
/* 16 bit offset from GOT to PLT. */
case
R_390_PLTOFF32
:
/* 32 bit offset from GOT to PLT. */
case
R_390_PLTOFF64
:
/* 16 bit offset from GOT to PLT. */
if
(
info
->
plt_initialized
==
0
)
{
unsigned
int
*
ip
;
ip
=
me
->
module_core
+
me
->
arch
.
plt_offset
+
info
->
plt_offset
;
ip
[
0
]
=
0x0d10e310
;
/* basr 1,0; lg 1,10(1); br 1 */
ip
[
1
]
=
0x100a0004
;
ip
[
2
]
=
0x07f10000
;
ip
[
3
]
=
(
unsigned
int
)
(
val
>>
32
);
ip
[
4
]
=
(
unsigned
int
)
val
;
info
->
plt_initialized
=
1
;
}
if
(
r_type
==
R_390_PLTOFF16
||
r_type
==
R_390_PLTOFF32
||
r_type
==
R_390_PLTOFF64
)
val
=
me
->
arch
.
plt_offset
-
me
->
arch
.
got_offset
+
info
->
plt_offset
+
rela
->
r_addend
;
else
val
=
(
Elf64_Addr
)
me
->
module_core
+
me
->
arch
.
plt_offset
+
info
->
plt_offset
+
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_PLT16DBL
)
*
(
unsigned
short
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PLTOFF16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PLT32DBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
else
if
(
r_type
==
R_390_PLT32
||
r_type
==
R_390_PLTOFF32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_PLT64
||
r_type
==
R_390_PLTOFF64
)
*
(
unsigned
long
*
)
loc
=
val
;
break
;
case
R_390_GOTOFF16
:
/* 16 bit offset to GOT. */
case
R_390_GOTOFF32
:
/* 32 bit offset to GOT. */
case
R_390_GOTOFF64
:
/* 64 bit offset to GOT. */
val
=
val
+
rela
->
r_addend
-
((
Elf64_Addr
)
me
->
module_core
+
me
->
arch
.
got_offset
);
if
(
r_type
==
R_390_GOTOFF16
)
*
(
unsigned
short
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTOFF32
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTOFF64
)
*
(
unsigned
long
*
)
loc
=
val
;
break
;
case
R_390_GOTPC
:
/* 32 bit PC relative offset to GOT. */
case
R_390_GOTPCDBL
:
/* 32 bit PC rel. off. to GOT shifted by 1. */
val
=
(
Elf64_Addr
)
me
->
module_core
+
me
->
arch
.
got_offset
+
rela
->
r_addend
-
loc
;
if
(
r_type
==
R_390_GOTPC
)
*
(
unsigned
int
*
)
loc
=
val
;
else
if
(
r_type
==
R_390_GOTPCDBL
)
*
(
unsigned
int
*
)
loc
=
val
>>
1
;
break
;
case
R_390_COPY
:
case
R_390_GLOB_DAT
:
/* Create GOT entry. */
case
R_390_JMP_SLOT
:
/* Create PLT entry. */
*
location
=
sym
->
st_value
;
break
;
case
R_390_RELATIVE
:
/* Adjust by program base. */
// FIXME: TODO
break
;
case
R_390_GOTOFF
:
/* 32 bit offset to GOT. */
// FIXME: TODO
break
;
case
R_390_GOTPC
:
/* 32 bit PC relative offset to GOT. */
case
R_390_GOTPCDBL
:
/* 32 bit PC rel. GOT shifted by 1. */
// FIXME: TODO
/* Only needed if we want to support loading of
modules linked with -shared. */
break
;
default:
printk
(
KERN_ERR
"module %s: Unknown relocation: %lu
\n
"
,
me
->
name
,
(
unsigned
long
)
ELF_R_TYPE
(
rel
[
i
].
r_info
));
printk
(
KERN_ERR
"module %s: Unknown relocation: %u
\n
"
,
me
->
name
,
r_type
);
return
-
ENOEXEC
;
}
}
return
0
;
}
int
apply_relocate_add
(
Elf32_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
int
apply_relocate_add
(
Elf64_Shdr
*
sechdrs
,
const
char
*
strtab
,
unsigned
int
symindex
,
unsigned
int
relsec
,
struct
module
*
me
)
{
printk
(
KERN_ERR
"module %s: ADD RELOCATION unsupported
\n
"
,
me
->
name
);
return
-
ENOEXEC
;
Elf64_Addr
base
;
Elf64_Sym
*
symtab
;
Elf64_Rela
*
rela
;
unsigned
long
i
,
n
;
int
rc
;
DEBUGP
(
"Applying relocate section %u to %u
\n
"
,
relsec
,
sechdrs
[
relsec
].
sh_info
);
base
=
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_addr
;
symtab
=
(
Elf64_Sym
*
)
sechdrs
[
symindex
].
sh_addr
;
rela
=
(
Elf64_Rela
*
)
sechdrs
[
relsec
].
sh_addr
;
n
=
sechdrs
[
relsec
].
sh_size
/
sizeof
(
Elf64_Rela
);
for
(
i
=
0
;
i
<
n
;
i
++
,
rela
++
)
{
rc
=
apply_rela
(
rela
,
base
,
symtab
,
me
);
if
(
rc
)
return
rc
;
}
return
0
;
}
int
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
me
)
{
if
(
me
->
arch
.
syminfo
)
kfree
(
me
->
arch
.
syminfo
);
return
0
;
}
include/asm-s390/module.h
View file @
9a180727
...
...
@@ -4,10 +4,28 @@
* This file contains the s390 architecture specific module code.
*/
struct
mod_arch_syminfo
{
unsigned
long
got_offset
;
unsigned
long
plt_offset
;
int
got_initialized
;
int
plt_initialized
;
};
struct
mod_arch_specific
{
void
*
module_got
,
*
module_plt
;
unsigned
long
got_size
,
plt_size
;
/* Starting offset of got in the module core memory. */
unsigned
long
got_offset
;
/* Starting offset of plt in the module core memory. */
unsigned
long
plt_offset
;
/* Size of the got. */
unsigned
long
got_size
;
/* Size of the plt. */
unsigned
long
plt_size
;
/* Number of symbols in syminfo. */
int
nsyms
;
/* Additional symbol information (got and plt offsets). */
struct
mod_arch_syminfo
*
syminfo
;
};
#ifdef CONFIG_ARCH_S390X
...
...
include/asm-s390x/module.h
View file @
9a180727
...
...
@@ -4,10 +4,28 @@
* This file contains the s390 architecture specific module code.
*/
struct
mod_arch_syminfo
{
unsigned
long
got_offset
;
unsigned
long
plt_offset
;
int
got_initialized
;
int
plt_initialized
;
};
struct
mod_arch_specific
{
void
*
module_got
,
*
module_plt
;
unsigned
long
got_size
,
plt_size
;
/* Starting offset of got in the module core memory. */
unsigned
long
got_offset
;
/* Starting offset of plt in the module core memory. */
unsigned
long
plt_offset
;
/* Size of the got. */
unsigned
long
got_size
;
/* Size of the plt. */
unsigned
long
plt_size
;
/* Number of symbols in syminfo. */
int
nsyms
;
/* Additional symbol information (got and plt offsets). */
struct
mod_arch_syminfo
*
syminfo
;
};
#ifdef CONFIG_ARCH_S390X
...
...
include/linux/elf.h
View file @
9a180727
...
...
@@ -446,8 +446,8 @@ typedef struct {
#define R_390_GLOB_DAT 10
/* Create GOT entry. */
#define R_390_JMP_SLOT 11
/* Create PLT entry. */
#define R_390_RELATIVE 12
/* Adjust by program base. */
#define R_390_GOTOFF
13
/* 32 bit offset to GOT. */
#define R_390_GOTPC
14
/* 32 bit PC relative
offset to GOT. */
#define R_390_GOTOFF
32 13
/* 32 bit offset to GOT. */
#define R_390_GOTPC
14
/* 32 bit PC rel.
offset to GOT. */
#define R_390_GOT16 15
/* 16 bit GOT offset. */
#define R_390_PC16 16
/* PC relative 16 bit. */
#define R_390_PC16DBL 17
/* PC relative 16 bit shifted by 1. */
...
...
@@ -460,8 +460,55 @@ typedef struct {
#define R_390_GOT64 24
/* 64 bit GOT offset. */
#define R_390_PLT64 25
/* 64 bit PC relative PLT address. */
#define R_390_GOTENT 26
/* 32 bit PC rel. to GOT entry >> 1. */
#define R_390_GOTOFF16 27
/* 16 bit offset to GOT. */
#define R_390_GOTOFF64 28
/* 64 bit offset to GOT. */
#define R_390_GOTPLT12 29
/* 12 bit offset to jump slot. */
#define R_390_GOTPLT16 30
/* 16 bit offset to jump slot. */
#define R_390_GOTPLT32 31
/* 32 bit offset to jump slot. */
#define R_390_GOTPLT64 32
/* 64 bit offset to jump slot. */
#define R_390_GOTPLTENT 33
/* 32 bit rel. offset to jump slot. */
#define R_390_PLTOFF16 34
/* 16 bit offset from GOT to PLT. */
#define R_390_PLTOFF32 35
/* 32 bit offset from GOT to PLT. */
#define R_390_PLTOFF64 36
/* 16 bit offset from GOT to PLT. */
#define R_390_TLS_LOAD 37
/* Tag for load insn in TLS code. */
#define R_390_TLS_GDCALL 38
/* Tag for function call in general
dynamic TLS code. */
#define R_390_TLS_LDCALL 39
/* Tag for function call in local
dynamic TLS code. */
#define R_390_TLS_GD32 40
/* Direct 32 bit for general dynamic
thread local data. */
#define R_390_TLS_GD64 41
/* Direct 64 bit for general dynamic
thread local data. */
#define R_390_TLS_GOTIE12 42
/* 12 bit GOT offset for static TLS
block offset. */
#define R_390_TLS_GOTIE32 43
/* 32 bit GOT offset for static TLS
block offset. */
#define R_390_TLS_GOTIE64 44
/* 64 bit GOT offset for static TLS
block offset. */
#define R_390_TLS_LDM32 45
/* Direct 32 bit for local dynamic
thread local data in LD code. */
#define R_390_TLS_LDM64 46
/* Direct 64 bit for local dynamic
thread local data in LD code. */
#define R_390_TLS_IE32 47
/* 32 bit address of GOT entry for
negated static TLS block offset. */
#define R_390_TLS_IE64 48
/* 64 bit address of GOT entry for
negated static TLS block offset. */
#define R_390_TLS_IEENT 49
/* 32 bit rel. offset to GOT entry for
negated static TLS block offset. */
#define R_390_TLS_LE32 50
/* 32 bit negated offset relative to
static TLS block. */
#define R_390_TLS_LE64 51
/* 64 bit negated offset relative to
static TLS block. */
#define R_390_TLS_LDO32 52
/* 32 bit offset relative to TLS
block. */
#define R_390_TLS_LDO64 53
/* 64 bit offset relative to TLS
block. */
#define R_390_TLS_DTPMOD 54
/* ID of module containing symbol. */
#define R_390_TLS_DTPOFF 55
/* Offset in TLS block. */
#define R_390_TLS_TPOFF 56
/* Negate offset in static TLS
block. */
/* Keep this the last entry. */
#define R_390_NUM
2
7
#define R_390_NUM
5
7
/* x86-64 relocation types */
#define R_X86_64_NONE 0
/* No reloc */
...
...
@@ -484,37 +531,6 @@ typedef struct {
#define R_X86_64_NUM 16
/* s390 relocations defined by the ABIs */
#define R_390_NONE 0
/* No reloc. */
#define R_390_8 1
/* Direct 8 bit. */
#define R_390_12 2
/* Direct 12 bit. */
#define R_390_16 3
/* Direct 16 bit. */
#define R_390_32 4
/* Direct 32 bit. */
#define R_390_PC32 5
/* PC relative 32 bit. */
#define R_390_GOT12 6
/* 12 bit GOT offset. */
#define R_390_GOT32 7
/* 32 bit GOT offset. */
#define R_390_PLT32 8
/* 32 bit PC relative PLT address. */
#define R_390_COPY 9
/* Copy symbol at runtime. */
#define R_390_GLOB_DAT 10
/* Create GOT entry. */
#define R_390_JMP_SLOT 11
/* Create PLT entry. */
#define R_390_RELATIVE 12
/* Adjust by program base. */
#define R_390_GOTOFF 13
/* 32 bit offset to GOT. */
#define R_390_GOTPC 14
/* 32 bit PC relative offset to GOT. */
#define R_390_GOT16 15
/* 16 bit GOT offset. */
#define R_390_PC16 16
/* PC relative 16 bit. */
#define R_390_PC16DBL 17
/* PC relative 16 bit shifted by 1. */
#define R_390_PLT16DBL 18
/* 16 bit PC rel. PLT shifted by 1. */
#define R_390_PC32DBL 19
/* PC relative 32 bit shifted by 1. */
#define R_390_PLT32DBL 20
/* 32 bit PC rel. PLT shifted by 1. */
#define R_390_GOTPCDBL 21
/* 32 bit PC rel. GOT shifted by 1. */
#define R_390_64 22
/* Direct 64 bit. */
#define R_390_PC64 23
/* PC relative 64 bit. */
#define R_390_GOT64 24
/* 64 bit GOT offset. */
#define R_390_PLT64 25
/* 64 bit PC relative PLT address. */
#define R_390_GOTENT 26
/* 32 bit PC rel. to GOT entry >> 1. */
/* Keep this the last entry. */
#define R_390_NUM 27
/* Legal values for e_flags field of Elf64_Ehdr. */
#define EF_ALPHA_32BIT 1
/* All addresses are below 2GB */
...
...
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