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
1650f8d3
Commit
1650f8d3
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.14
parent
98606bdd
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1560 additions
and
110 deletions
+1560
-110
Makefile
Makefile
+1
-1
config.in
config.in
+3
-6
drivers/block/mcd.c
drivers/block/mcd.c
+2
-2
drivers/block/sbpcd.c
drivers/block/sbpcd.c
+5
-1
fs/Makefile
fs/Makefile
+0
-7
fs/exec.c
fs/exec.c
+53
-45
fs/proc/net.c
fs/proc/net.c
+2
-0
fs/select.c
fs/select.c
+7
-1
ibcs/binfmt_coff.c
ibcs/binfmt_coff.c
+784
-0
ibcs/binfmt_elf.c
ibcs/binfmt_elf.c
+636
-0
include/linux/binfmts.h
include/linux/binfmts.h
+18
-15
include/linux/personality.h
include/linux/personality.h
+12
-0
include/linux/sched.h
include/linux/sched.h
+4
-2
kernel/exit.c
kernel/exit.c
+3
-1
kernel/ksyms.c
kernel/ksyms.c
+13
-25
kernel/sched.c
kernel/sched.c
+10
-0
kernel/signal.c
kernel/signal.c
+7
-3
net/inet/p8022.c
net/inet/p8022.c
+0
-1
No files found.
Makefile
View file @
1650f8d3
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
1
3
SUBLEVEL
=
1
4
all
:
Version zImage
...
...
config.in
View file @
1650f8d3
...
...
@@ -17,7 +17,9 @@ if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET y
if [ "$CONFIG_INET" "=" "y" ]; then
bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n
comment '(it is safe to leave these untouched)'
bool 'PC/TCP compatibility mode' CONFIG_INET_PCTCP n
bool 'Reverse ARP' CONFIG_INET_RARP n
bool 'Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
...
...
@@ -26,11 +28,6 @@ bool 'The IPX protocol' CONFIG_IPX y
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
fi
comment 'Program binary formats'
bool 'Elf executables' CONFIG_BINFMT_ELF y
bool 'COFF executables' CONFIG_BINFMT_COFF y
comment 'SCSI support'
bool 'SCSI support?' CONFIG_SCSI n
...
...
@@ -78,7 +75,7 @@ if [ "$CONFIG_SLIP" = "y" ]; then
bool ' CSLIP compressed headers' SL_COMPRESSED y
# bool ' SLIP debugging on' SL_DUMP y
fi
#
bool 'PPP (point-to-point) support' CONFIG_PPP n
bool 'PPP (point-to-point) support' CONFIG_PPP n
bool 'Load balancing support (very experimental)' CONFIG_SLAVE_BALANCING n
bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'NE2000/NE1000 support' CONFIG_NE2000 n
...
...
drivers/block/mcd.c
View file @
1650f8d3
...
...
@@ -881,9 +881,9 @@ mcd_init(unsigned long mem_start, unsigned long mem_end)
/* don't get the IRQ until we know for sure the drive is there */
if
(
irqaction
(
MCD_INTR_NR
,
&
mcd_sigaction
))
if
(
irqaction
(
mcd_irq
,
&
mcd_sigaction
))
{
printk
(
"mcd: Unable to get IRQ%d for Mitsumi CD-ROM
\n
"
,
MCD_INTR_NR
);
printk
(
"mcd: Unable to get IRQ%d for Mitsumi CD-ROM
\n
"
,
mcd_irq
);
return
mem_start
;
}
snarf_region
(
mcd_port
,
4
);
...
...
drivers/block/sbpcd.c
View file @
1650f8d3
...
...
@@ -123,7 +123,6 @@
#include <linux/signal.h>
#endif SBPCD_USE_IRQ
#include <linux/ddi.h>
#include <linux/major.h>
#include <asm/system.h>
...
...
@@ -142,6 +141,11 @@
#error "SBPCD: \"make config\" again. File system iso9660 is necessary."
#endif
/*
* This may come back some day..
*/
#define DDIOCSDBG 0x9000
/*
* still testing around...
*/
...
...
fs/Makefile
View file @
1650f8d3
...
...
@@ -40,13 +40,6 @@ ifdef CONFIG_HPFS_FS
FS_SUBDIRS
:=
$(FS_SUBDIRS)
hpfs
endif
ifdef
CONFIG_BINFMT_ELF
BINFMTS
:=
$(BINFMTS)
binfmt_elf.o
endif
ifdef
CONFIG_BINFMT_COFF
BINFMTS
:=
$(BINFMTS)
binfmt_coff.o
endif
.c.s
:
$(CC)
$(CFLAGS)
-S
$<
.c.o
:
...
...
fs/exec.c
View file @
1650f8d3
...
...
@@ -53,6 +53,47 @@ asmlinkage int sys_brk(unsigned long);
extern
void
shm_exit
(
void
);
static
int
load_aout_binary
(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
static
int
load_aout_library
(
int
fd
);
/*
* Here are the actual binaries that will be accepted:
* add more with "register_binfmt()"..
*/
static
struct
linux_binfmt
aout_format
=
{
NULL
,
load_aout_binary
,
load_aout_library
};
static
struct
linux_binfmt
*
formats
=
&
aout_format
;
int
register_binfmt
(
struct
linux_binfmt
*
fmt
)
{
struct
linux_binfmt
**
tmp
=
&
formats
;
if
(
!
fmt
)
return
-
EINVAL
;
if
(
fmt
->
next
)
return
-
EBUSY
;
while
(
*
tmp
)
{
if
(
fmt
==
*
tmp
)
return
-
EBUSY
;
tmp
=
&
(
*
tmp
)
->
next
;
}
*
tmp
=
fmt
;
return
0
;
}
int
unregister_binfmt
(
struct
linux_binfmt
*
fmt
)
{
struct
linux_binfmt
**
tmp
=
&
formats
;
while
(
*
tmp
)
{
if
(
fmt
==
*
tmp
)
{
*
tmp
=
fmt
->
next
;
return
0
;
}
tmp
=
&
(
*
tmp
)
->
next
;
}
return
-
EINVAL
;
}
int
open_inode
(
struct
inode
*
inode
,
int
mode
)
{
int
error
,
fd
;
...
...
@@ -247,14 +288,14 @@ asmlinkage int sys_uselib(const char * library)
file
=
current
->
files
->
fd
[
fd
];
retval
=
-
ENOEXEC
;
if
(
file
&&
file
->
f_inode
&&
file
->
f_op
&&
file
->
f_op
->
read
)
{
fmt
=
formats
;
do
{
for
(
fmt
=
formats
;
fmt
;
fmt
=
fmt
->
next
)
{
int
(
*
fn
)(
int
)
=
fmt
->
load_shlib
;
if
(
!
fn
)
break
;
retval
=
fn
(
fd
);
fmt
++
;
}
while
(
retval
==
-
ENOEXEC
);
if
(
retval
!=
-
ENOEXEC
)
break
;
}
}
sys_close
(
fd
);
return
retval
;
...
...
@@ -530,13 +571,13 @@ void flush_old_exec(struct linux_binprm * bprm)
if
(
last_task_used_math
==
current
)
last_task_used_math
=
NULL
;
current
->
used_math
=
0
;
current
->
elf_executable
=
0
;
current
->
personality
=
0
;
}
/*
* sys_execve() executes a new program.
*/
static
int
do_execve
(
char
*
filename
,
char
**
argv
,
char
**
envp
,
struct
pt_regs
*
regs
)
int
do_execve
(
char
*
filename
,
char
**
argv
,
char
**
envp
,
struct
pt_regs
*
regs
)
{
struct
linux_binprm
bprm
;
struct
linux_binfmt
*
fmt
;
...
...
@@ -684,8 +725,7 @@ static int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs
}
bprm
.
sh_bang
=
sh_bang
;
fmt
=
formats
;
do
{
for
(
fmt
=
formats
;
fmt
;
fmt
=
fmt
->
next
)
{
int
(
*
fn
)(
struct
linux_binprm
*
,
struct
pt_regs
*
)
=
fmt
->
load_binary
;
if
(
!
fn
)
break
;
...
...
@@ -695,8 +735,9 @@ static int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs
current
->
did_exec
=
1
;
return
0
;
}
fmt
++
;
}
while
(
retval
==
-
ENOEXEC
);
if
(
retval
!=
-
ENOEXEC
)
break
;
}
exec_error2:
iput
(
bprm
.
inode
);
exec_error1:
...
...
@@ -721,39 +762,6 @@ asmlinkage int sys_execve(struct pt_regs regs)
return
error
;
}
/*
* These are the prototypes for the functions in the dispatch table, as
* well as the dispatch table itself.
*/
extern
int
load_aout_binary
(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
extern
int
load_aout_library
(
int
fd
);
#ifdef CONFIG_BINFMT_ELF
extern
int
load_elf_binary
(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
extern
int
load_elf_library
(
int
fd
);
#endif
#ifdef CONFIG_BINFMT_COFF
extern
int
load_coff_binary
(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
extern
int
load_coff_library
(
int
fd
);
#endif
/* Here are the actual binaries that will be accepted */
struct
linux_binfmt
formats
[]
=
{
{
load_aout_binary
,
load_aout_library
},
#ifdef CONFIG_BINFMT_ELF
{
load_elf_binary
,
load_elf_library
},
#endif
#ifdef CONFIG_BINFMT_COFF
{
load_coff_binary
,
load_coff_library
},
#endif
{
NULL
,
NULL
}
};
static
void
set_brk
(
unsigned
long
start
,
unsigned
long
end
)
{
start
=
PAGE_ALIGN
(
start
);
...
...
@@ -770,7 +778,7 @@ static void set_brk(unsigned long start, unsigned long end)
* libraries. There is no binary dependent code anywhere else.
*/
int
load_aout_binary
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
)
static
int
load_aout_binary
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
)
{
struct
exec
ex
;
struct
file
*
file
;
...
...
@@ -868,7 +876,7 @@ int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
}
int
load_aout_library
(
int
fd
)
static
int
load_aout_library
(
int
fd
)
{
struct
file
*
file
;
struct
exec
ex
;
...
...
fs/proc/net.c
View file @
1650f8d3
...
...
@@ -280,6 +280,8 @@ static int proc_readnet(struct inode * inode, struct file * file,
* the start pointer and we know the length..
*/
if
(
length
<=
0
)
break
;
/*
* Copy the bytes
*/
...
...
fs/select.c
View file @
1650f8d3
...
...
@@ -3,6 +3,11 @@
*
* Created for Linux based loosely upon Mathius Lattner's minix
* patches by Peter MacDonald. Heavily edited by Linus.
*
* 4 February 1994
* COFF/ELF binary emulation. If the process has the STICKY_TIMEOUTS
* flag set in its personality we do *not* modify the given timeout
* parameter to reflect time remaining.
*/
#include <linux/types.h>
...
...
@@ -14,6 +19,7 @@
#include <linux/stat.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/personality.h>
#include <asm/segment.h>
#include <asm/system.h>
...
...
@@ -235,7 +241,7 @@ asmlinkage int sys_select( unsigned long *buffer )
else
timeout
=
0
;
current
->
timeout
=
0
;
if
(
tvp
)
{
if
(
tvp
&&
!
(
current
->
personality
&
STICKY_TIMEOUTS
)
)
{
put_fs_long
(
timeout
/
HZ
,
(
unsigned
long
*
)
&
tvp
->
tv_sec
);
timeout
%=
HZ
;
timeout
*=
(
1000000
/
HZ
);
...
...
ibcs/binfmt_coff.c
0 → 100644
View file @
1650f8d3
/*
* These are the functions used to load COFF IBSC style executables.
* Information on COFF format may be obtained in either the Intel Binary
* Compatibility Specification 2 or O'Rilley's book on COFF. The shared
* libraries are defined only the in the Intel book.
*
* This file is based upon code written by Eric Youndale for the ELF object
* file format.
*
* Author: Al Longyear (longyear@sii.com)
*
* Latest Revision:
* 3 Feburary 1994
* Al Longyear (longyear@sii.com)
* Cleared first page of bss section using put_fs_byte.
*/
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
#include <asm/segment.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/coff.h>
#include <linux/malloc.h>
asmlinkage
int
sys_exit
(
int
exit_code
);
asmlinkage
int
sys_close
(
unsigned
fd
);
asmlinkage
int
sys_open
(
const
char
*
,
int
,
int
);
asmlinkage
int
sys_uselib
(
const
char
*
library
);
static
int
preload_library
(
struct
linux_binprm
*
exe_bprm
,
COFF_SCNHDR
*
sect
,
struct
file
*
fp
);
static
int
load_object
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
,
int
lib_ok
);
/*
* Small procedure to test for the proper file alignment.
*/
static
inline
int
is_properly_aligned
(
COFF_SCNHDR
*
sect
)
{
long
scnptr
=
COFF_LONG
(
sect
->
s_scnptr
);
long
vaddr
=
COFF_LONG
(
sect
->
s_vaddr
);
/*
* Print the section information if needed
*/
#ifdef COFF_DEBUG
printk
(
"%s, scnptr = %d, vaddr = %d
\n
"
,
sect
->
s_name
,
scnptr
,
vaddr
);
#endif
/*
* Return the error code if the section is not properly aligned.
*/
#ifdef COFF_DEBUG
if
(((
vaddr
-
scnptr
)
&
~
PAGE_MASK
)
!=
0
)
printk
(
"bad alignment in %s
\n
"
,
sect
->
s_name
);
#endif
return
((((
vaddr
-
scnptr
)
&
~
PAGE_MASK
)
!=
0
)
?
-
ENOEXEC
:
0
);
}
/*
* Clear the bytes in the last page of data.
*/
static
int
clear_memory
(
unsigned
long
addr
,
unsigned
long
size
)
{
int
status
;
size
=
(
PAGE_SIZE
-
(
addr
&
~
PAGE_MASK
))
&
~
PAGE_MASK
;
if
(
size
==
0
)
status
=
0
;
else
{
#ifdef COFF_DEBUG
printk
(
"un-initialized storage in last page %d
\n
"
,
size
);
#endif
status
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
addr
,
size
);
#ifdef COFF_DEBUG
printk
(
"result from verify_area = %d
\n
"
,
status
);
#endif
if
(
status
>=
0
)
while
(
size
--
!=
0
)
put_fs_byte
(
0
,
addr
++
);
}
return
status
;
}
/*
* Helper function to process the load operation.
*/
static
int
load_object
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
,
int
lib_ok
)
{
COFF_FILHDR
*
coff_hdr
=
(
COFF_FILHDR
*
)
bprm
->
buf
;
/* COFF Header */
COFF_SCNHDR
*
sect_bufr
;
/* Pointer to section table */
COFF_SCNHDR
*
text_sect
;
/* Pointer to the text section */
COFF_SCNHDR
*
data_sect
;
/* Pointer to the data section */
COFF_SCNHDR
*
bss_sect
;
/* Pointer to the bss section */
int
text_count
;
/* Number of text sections */
int
data_count
;
/* Number of data sections */
int
bss_count
;
/* Number of bss sections */
int
lib_count
;
/* Number of lib sections */
unsigned
int
start_addr
=
0
;
/* Starting location for program */
int
status
=
0
;
/* Result status register */
int
fd
=
-
1
;
/* Open file descriptor */
struct
file
*
fp
=
NULL
;
/* Pointer to the file at "fd" */
short
int
sections
=
0
;
/* Number of sections in the file */
short
int
aout_size
=
0
;
/* Size of the a.out header area */
short
int
flags
;
/* Flag bits from the COFF header */
#ifdef COFF_DEBUG
printk
(
"binfmt_coff entry: %s
\n
"
,
bprm
->
filename
);
#endif
/*
* Validate the magic value for the object file.
*/
do
{
if
(
COFF_I386BADMAG
(
*
coff_hdr
))
{
#ifdef COFF_DEBUG
printk
(
"bad filehdr magic
\n
"
);
#endif
status
=
-
ENOEXEC
;
break
;
}
/*
* The object file should have 32 BIT little endian format. Do not allow
* it to have the 16 bit object file flag set as Linux is not able to run
* on the 80286/80186/8086.
*/
flags
=
COFF_SHORT
(
coff_hdr
->
f_flags
);
if
((
flags
&
(
COFF_F_AR32WR
|
COFF_F_AR16WR
))
!=
COFF_F_AR32WR
)
{
#ifdef COFF_DEBUG
printk
(
"invalid f_flags bits
\n
"
);
#endif
status
=
-
ENOEXEC
;
break
;
}
/*
* Extract the header information which we need.
*/
sections
=
COFF_SHORT
(
coff_hdr
->
f_nscns
);
/* Number of sections */
aout_size
=
COFF_SHORT
(
coff_hdr
->
f_opthdr
);
/* Size of opt. headr */
/*
* If the file is not executable then reject the exectution. This means
* that there must not be external references.
*/
if
((
flags
&
COFF_F_EXEC
)
==
0
)
{
#ifdef COFF_DEBUG
printk
(
"not executable bit
\n
"
);
#endif
status
=
-
ENOEXEC
;
break
;
}
/*
* There must be atleast one section.
*/
if
(
sections
==
0
)
{
#ifdef COFF_DEBUG
printk
(
"no sections
\n
"
);
#endif
status
=
-
ENOEXEC
;
break
;
}
/*
* Do some additional consistency checks.
* The system requires mapping for this loader. If you try
* to use a file system with no mapping, the format is not valid.
*/
if
(
!
bprm
->
inode
->
i_op
||
!
bprm
->
inode
->
i_op
->
default_file_ops
->
mmap
)
{
#ifdef COFF_DEBUG
printk
(
"no mmap in fs
\n
"
);
#endif
status
=
-
ENOEXEC
;
}
}
while
(
0
);
/*
* Allocate a buffer to hold the entire coff section list.
*/
if
(
status
>=
0
)
{
int
nbytes
=
sections
*
COFF_SCNHSZ
;
sect_bufr
=
(
COFF_SCNHDR
*
)
kmalloc
(
nbytes
,
GFP_KERNEL
);
if
(
0
==
sect_bufr
)
{
#ifdef COFF_DEBUG
printk
(
"kmalloc failed
\n
"
);
#endif
status
=
-
ENOEXEC
;
}
/*
* Read the section list from the disk file.
*/
else
{
int
old_fs
=
get_fs
();
set_fs
(
get_ds
());
/* Make it point to the proper location */
status
=
read_exec
(
bprm
->
inode
,
/* INODE for file */
aout_size
+
COFF_FILHSZ
,
/* Offset in the file */
(
char
*
)
sect_bufr
,
/* Buffer for read */
nbytes
);
/* Byte count reqd. */
set_fs
(
old_fs
);
/* Restore the selector */
#ifdef COFF_DEBUG
if
(
status
<
0
)
printk
(
"read aout hdr, status = %d
\n
"
,
status
);
#endif
}
}
else
sect_bufr
=
NULL
;
/* Errors do not have a section buffer */
/*
* Count the number of sections for the required types and store the location
* of the last section for the three primary types.
*/
text_count
=
0
;
data_count
=
0
;
bss_count
=
0
;
lib_count
=
0
;
text_sect
=
NULL
;
data_sect
=
NULL
;
bss_sect
=
NULL
;
/*
* Loop through the sections and find the various types
*/
if
(
status
>=
0
)
{
int
nIndex
;
COFF_SCNHDR
*
sect_ptr
=
sect_bufr
;
for
(
nIndex
=
0
;
nIndex
<
sections
;
++
nIndex
)
{
long
int
sect_flags
=
COFF_LONG
(
sect_ptr
->
s_flags
);
switch
(
sect_flags
)
{
case
COFF_STYP_TEXT
:
text_sect
=
sect_ptr
;
++
text_count
;
status
=
is_properly_aligned
(
sect_ptr
);
break
;
case
COFF_STYP_DATA
:
data_sect
=
sect_ptr
;
++
data_count
;
status
=
is_properly_aligned
(
sect_ptr
);
break
;
case
COFF_STYP_BSS
:
bss_sect
=
sect_ptr
;
++
bss_count
;
break
;
case
COFF_STYP_LIB
:
#ifdef COFF_DEBUG
printk
(
".lib section found
\n
"
);
#endif
++
lib_count
;
break
;
default:
break
;
}
sect_ptr
=
(
COFF_SCNHDR
*
)
&
((
char
*
)
sect_ptr
)[
COFF_SCNHSZ
];
}
/*
* Ensure that there are the required sections. There must be one text
* sections and one each of the data and bss sections for an executable.
* A library may or may not have a data / bss section.
*/
if
(
text_count
!=
1
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"no text sections
\n
"
);
#endif
}
else
{
if
(
lib_ok
)
{
if
(
data_count
!=
1
||
bss_count
!=
1
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"no .data nor .bss sections
\n
"
);
#endif
}
}
}
}
/*
* If there is no additional header then assume the file starts at
* the first byte of the text section. This may not be the proper place,
* so the best solution is to include the optional header. A shared library
* __MUST__ have an optional header to indicate that it is a shared library.
*/
if
(
status
>=
0
)
{
if
(
aout_size
==
0
)
{
if
(
!
lib_ok
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"no header in library
\n
"
);
#endif
}
start_addr
=
COFF_LONG
(
text_sect
->
s_vaddr
);
}
/*
* There is some header. Ensure that it is sufficient.
*/
else
{
if
(
aout_size
<
COFF_AOUTSZ
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"header too small
\n
"
);
#endif
}
else
{
COFF_AOUTHDR
*
aout_hdr
=
/* Pointer to a.out header */
(
COFF_AOUTHDR
*
)
&
((
char
*
)
coff_hdr
)[
COFF_FILHSZ
];
short
int
aout_magic
=
COFF_SHORT
(
aout_hdr
->
magic
);
/* id */
/*
* Validate the magic number in the a.out header. If it is valid then
* update the starting symbol location. Do not accept these file formats
* when loading a shared library.
*/
switch
(
aout_magic
)
{
case
COFF_OMAGIC
:
case
COFF_ZMAGIC
:
case
COFF_STMAGIC
:
if
(
!
lib_ok
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"wrong a.out header magic
\n
"
);
#endif
}
start_addr
=
(
unsigned
int
)
COFF_LONG
(
aout_hdr
->
entry
);
break
;
/*
* Magic value for a shared library. This is valid only when loading a
* shared library. (There is no need for a start_addr. It won't be used.)
*/
case
COFF_SHMAGIC
:
if
(
lib_ok
)
{
#ifdef COFF_DEBUG
printk
(
"wrong a.out header magic
\n
"
);
#endif
status
=
-
ENOEXEC
;
}
break
;
default:
#ifdef COFF_DEBUG
printk
(
"wrong a.out header magic
\n
"
);
#endif
status
=
-
ENOEXEC
;
break
;
}
}
}
}
/*
* Fetch a file pointer to the executable.
*/
if
(
status
>=
0
)
{
fd
=
open_inode
(
bprm
->
inode
,
O_RDONLY
);
if
(
fd
<
0
)
{
#ifdef COFF_DEBUG
printk
(
"can not open inode, result = %d
\n
"
,
fd
);
#endif
status
=
fd
;
}
else
fp
=
current
->
files
->
fd
[
fd
];
}
else
fd
=
-
1
;
/* Invalidate the open file descriptor */
/*
* Generate the proper values for the text fields
*
* THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD
* SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD.
*/
if
(
status
>=
0
)
{
long
text_scnptr
=
COFF_LONG
(
text_sect
->
s_scnptr
);
long
text_size
=
COFF_LONG
(
text_sect
->
s_size
);
long
text_vaddr
=
COFF_LONG
(
text_sect
->
s_vaddr
);
long
data_scnptr
;
long
data_size
;
long
data_vaddr
;
long
bss_size
;
long
bss_vaddr
;
/*
* Generate the proper values for the data fields
*/
if
(
data_sect
!=
NULL
)
{
data_scnptr
=
COFF_LONG
(
data_sect
->
s_scnptr
);
data_size
=
COFF_LONG
(
data_sect
->
s_size
);
data_vaddr
=
COFF_LONG
(
data_sect
->
s_vaddr
);
}
else
{
data_scnptr
=
0
;
data_size
=
0
;
data_vaddr
=
0
;
}
/*
* Generate the proper values for the bss fields
*/
if
(
bss_sect
!=
NULL
)
{
bss_size
=
COFF_LONG
(
bss_sect
->
s_size
);
bss_vaddr
=
COFF_LONG
(
bss_sect
->
s_vaddr
);
}
else
{
bss_size
=
0
;
bss_vaddr
=
0
;
}
/*
* Flush the executable from memory. At this point the executable is
* committed to being defined or a segmentation violation will occur.
*/
if
(
lib_ok
)
{
#ifdef COFF_DEBUG
printk
(
"flushing executable
\n
"
);
#endif
flush_old_exec
(
bprm
);
/*
* Define the initial locations for the various items in the new process
*/
current
->
mm
->
mmap
=
NULL
;
current
->
mm
->
rss
=
0
;
/*
* Construct the parameter and environment string table entries.
*/
bprm
->
p
+=
change_ldt
(
0
,
bprm
->
page
);
bprm
->
p
-=
MAX_ARG_PAGES
*
PAGE_SIZE
;
bprm
->
p
=
(
unsigned
long
)
create_tables
((
char
*
)
bprm
->
p
,
bprm
->
argc
,
bprm
->
envc
,
1
);
/*
* Do the end processing once the stack has been constructed
*/
current
->
mm
->
start_code
=
text_vaddr
&
PAGE_MASK
;
current
->
mm
->
end_code
=
text_vaddr
+
text_size
;
current
->
mm
->
end_data
=
data_vaddr
+
data_size
;
current
->
mm
->
start_brk
=
current
->
mm
->
brk
=
bss_vaddr
+
bss_size
;
current
->
suid
=
current
->
euid
=
bprm
->
e_uid
;
current
->
sgid
=
current
->
egid
=
bprm
->
e_gid
;
current
->
executable
=
bprm
->
inode
;
/* Store inode for file */
++
bprm
->
inode
->
i_count
;
/* Count the open inode */
regs
->
eip
=
start_addr
;
/* Current EIP register */
regs
->
esp
=
current
->
mm
->
start_stack
=
bprm
->
p
;
}
/*
* Map the text pages
*/
#ifdef COFF_DEBUG
printk
(
".text: vaddr = %d, size = %d, scnptr = %d
\n
"
,
text_vaddr
,
text_size
,
text_scnptr
);
#endif
status
=
do_mmap
(
fp
,
text_vaddr
&
PAGE_MASK
,
text_size
+
(
text_vaddr
&
~
PAGE_MASK
),
PROT_READ
|
PROT_EXEC
,
MAP_FIXED
|
MAP_SHARED
,
text_scnptr
&
PAGE_MASK
);
status
=
(
status
==
(
text_vaddr
&
PAGE_MASK
))
?
0
:
-
ENOEXEC
;
/*
* Map the data pages
*/
if
(
status
>=
0
&&
data_size
!=
0
)
{
#ifdef COFF_DEBUG
printk
(
".data: vaddr = %d, size = %d, scnptr = %d
\n
"
,
data_vaddr
,
data_size
,
data_scnptr
);
#endif
status
=
do_mmap
(
fp
,
data_vaddr
&
PAGE_MASK
,
data_size
+
(
data_vaddr
&
~
PAGE_MASK
),
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
data_scnptr
&
PAGE_MASK
);
status
=
(
status
==
(
data_vaddr
&
PAGE_MASK
))
?
0
:
-
ENOEXEC
;
}
/*
* Construct the bss data for the process. The bss ranges from the
* end of the data (which may not be on a page boundry) to the end
* of the bss section. Allocate any necessary pages for the data.
*/
if
(
status
>=
0
&&
bss_size
!=
0
)
{
#ifdef COFF_DEBUG
printk
(
".bss: vaddr = %d, size = %d
\n
"
,
bss_vaddr
,
bss_size
);
#endif
zeromap_page_range
(
PAGE_ALIGN
(
bss_vaddr
),
PAGE_ALIGN
(
bss_size
),
PAGE_COPY
);
status
=
clear_memory
(
bss_vaddr
,
bss_size
);
}
/*
* Load any shared library for the executable.
*/
if
(
status
>=
0
&&
lib_ok
&&
lib_count
!=
0
)
{
int
nIndex
;
COFF_SCNHDR
*
sect_ptr
=
sect_bufr
;
/*
* Find the library sections. (There should be atleast one. It was counted
* earlier.) This will evenutally recurse to our code and load the shared
* library with our own procedures.
*/
for
(
nIndex
=
0
;
nIndex
<
sections
;
++
nIndex
)
{
long
int
sect_flags
=
COFF_LONG
(
sect_ptr
->
s_flags
);
if
(
sect_flags
==
COFF_STYP_LIB
)
{
status
=
preload_library
(
bprm
,
sect_ptr
,
fp
);
if
(
status
!=
0
)
break
;
}
sect_ptr
=
(
COFF_SCNHDR
*
)
&
((
char
*
)
sect_ptr
)
[
COFF_SCNHSZ
];
}
}
/*
* Generate any needed trap for this process. If an error occured then
* generate a segmentation violation. If the process is being debugged
* then generate the load trap. (Note: If this is a library load then
* do not generate the trap here. Pass the error to the caller who
* will do it for the process in the outer lay of this procedure call.)
*/
if
(
lib_ok
)
{
if
(
status
<
0
)
send_sig
(
SIGSEGV
,
current
,
0
);
/* Generate the error trap */
else
{
if
(
current
->
flags
&
PF_PTRACED
)
send_sig
(
SIGTRAP
,
current
,
0
);
}
status
=
0
;
/* We are committed. It can't fail */
}
}
/*
* Do any cleanup processing
*/
if
(
fd
>=
0
)
sys_close
(
fd
);
/* Close unused code file */
if
(
sect_bufr
!=
NULL
)
kfree
(
sect_bufr
);
/* Release section list buffer */
/*
* Return the completion status.
*/
#ifdef COFF_DEBUG
printk
(
"binfmt_coff: result = %d
\n
"
,
status
);
#endif
return
(
status
);
}
/*
* This procedure will load the library listed in the file name given
* as the paramter. The result will be non-zero should something fail
* to load.
*/
static
int
preload_this_library
(
struct
linux_binprm
*
exe_bprm
,
char
*
lib_name
)
{
int
status
;
int
old_fs
=
get_fs
();
/*
* If debugging then print "we have arrived"
*/
#ifdef COFF_DEBUG
printk
(
"%s loading shared library %s
\n
"
,
exe_bprm
->
filename
,
lib_name
);
#endif
/*
* Change the FS register to the proper kernel address space and attempt
* to load the library. The library name is allocated from the kernel
* pool.
*/
set_fs
(
get_ds
());
status
=
sys_uselib
(
lib_name
);
set_fs
(
old_fs
);
/*
* Return the success/failure to the caller.
*/
return
(
status
);
}
/*
* This procedure is called to load a library section. The various
* libraries are loaded from the list given in the section data.
*/
static
int
preload_library
(
struct
linux_binprm
*
exe_bprm
,
COFF_SCNHDR
*
sect
,
struct
file
*
fp
)
{
int
status
=
0
;
/* Completion status */
long
nbytes
;
/* Count of bytes in the header area */
/*
* Fetch the size of the section. There must be enough room for atleast
* one entry.
*/
nbytes
=
COFF_LONG
(
sect
->
s_size
);
if
(
nbytes
<
COFF_SLIBSZ
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"library section too small
\n
"
);
#endif
}
/*
* Allocate a buffer to hold the section data
*/
else
{
COFF_SLIBHD
*
phdr
;
char
*
buffer
=
(
char
*
)
kmalloc
(
nbytes
,
GFP_KERNEL
);
if
(
0
==
buffer
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"kmalloc failed
\n
"
);
#endif
}
else
{
int
old_fs
=
get_fs
();
/*
* Read the section data from the disk file.
*/
set_fs
(
get_ds
());
/* Make it point to the proper location */
status
=
read_exec
(
exe_bprm
->
inode
,
/* INODE for file */
COFF_LONG
(
sect
->
s_scnptr
),
/* Disk location */
buffer
,
/* Buffer for read */
nbytes
);
/* Byte count reqd. */
set_fs
(
old_fs
);
/* Restore the selector */
/*
* Check the result. The value returned is the byte count actaully read.
*/
if
(
status
>=
0
&&
status
!=
nbytes
)
{
#ifdef COFF_DEBUG
printk
(
"read of lib section was short
\n
"
);
#endif
status
=
-
ENOEXEC
;
}
}
/*
* At this point, go through the list of libraries in the data area.
*/
phdr
=
(
COFF_SLIBHD
*
)
buffer
;
while
(
status
>=
0
&&
nbytes
>
COFF_SLIBSZ
)
{
int
entry_size
=
COFF_LONG
(
phdr
->
sl_entsz
)
*
sizeof
(
long
);
int
header_size
=
COFF_LONG
(
phdr
->
sl_pathndx
)
*
sizeof
(
long
);
/*
* Validate the sizes of the various items. I don't trust the linker!!
*/
if
((
unsigned
)
header_size
>=
(
unsigned
)
nbytes
||
entry_size
<=
0
||
(
unsigned
)
entry_size
<=
(
unsigned
)
header_size
)
{
status
=
-
ENOEXEC
;
#ifdef COFF_DEBUG
printk
(
"header count is invalid
\n
"
);
#endif
}
/*
* Load the library. Stop the load process on the first error.
*/
else
{
status
=
preload_this_library
(
exe_bprm
,
&
((
char
*
)
phdr
)[
header_size
]);
#ifdef COFF_DEBUG
printk
(
"preload_this_library result = %d
\n
"
,
status
);
#endif
}
/*
* Point to the next library in the section data.
*/
nbytes
-=
entry_size
;
phdr
=
(
COFF_SLIBHD
*
)
&
((
char
*
)
phdr
)[
entry_size
];
}
/*
* Release the space for the library list.
*/
if
(
buffer
!=
NULL
)
kfree
(
buffer
);
}
/*
* Return the resulting status to the caller.
*/
return
(
status
);
}
/*
* This procedure is called by the main load sequence. It will load
* the executable and prepare it for execution. It provides the additional
* parameters used by the recursive coff loader and tells the loader that
* this is the main executable. How simple it is . . . .
*/
int
load_coff_binary
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
)
{
return
(
load_object
(
bprm
,
regs
,
1
));
}
/*
* Load the image for any shared library.
*
* This is called when we need to load a library based upon a file name.
*/
int
load_coff_library
(
int
fd
)
{
struct
linux_binprm
*
bprm
;
/* Parameters for the load operation */
int
status
;
/* Status of the request */
/*
* Read the first portion of the file.
*/
bprm
=
(
struct
linux_binprm
*
)
kmalloc
(
sizeof
(
struct
linux_binprm
),
GFP_KERNEL
);
if
(
0
==
bprm
)
{
#ifdef COFF_DEBUG
printk
(
"kmalloc failed
\n
"
);
#endif
status
=
-
ENOEXEC
;
}
else
{
struct
file
*
file
;
/* Pointer to the file table */
struct
pt_regs
regs
;
/* Register work area */
int
old_fs
=
get_fs
();
/* Previous FS register value */
memset
(
bprm
,
'\0'
,
sizeof
(
struct
linux_binprm
));
file
=
current
->
files
->
fd
[
fd
];
bprm
->
inode
=
file
->
f_inode
;
/* The only item _really_ needed */
bprm
->
filename
=
""
;
/* Make it a legal string */
/*
* Read the section list from the disk file.
*/
set_fs
(
get_ds
());
/* Make it point to the proper location */
status
=
read_exec
(
bprm
->
inode
,
/* INODE for file */
0L
,
/* Offset in the file */
bprm
->
buf
,
/* Buffer for read */
sizeof
(
bprm
->
buf
));
/* Size of the buffer */
set_fs
(
old_fs
);
/* Restore the selector */
/*
* Try to load the library.
*/
status
=
load_object
(
bprm
,
&
regs
,
0
);
/*
* Release the work buffer and return the result.
*/
kfree
(
bprm
);
/* Release the buffer area */
}
/*
* Return the result of the load operation
*/
return
(
status
);
}
ibcs/binfmt_elf.c
0 → 100644
View file @
1650f8d3
/*
* linux/fs/binfmt_elf.c
*/
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/shm.h>
#include <asm/segment.h>
asmlinkage
int
sys_exit
(
int
exit_code
);
asmlinkage
int
sys_close
(
unsigned
fd
);
asmlinkage
int
sys_open
(
const
char
*
,
int
,
int
);
asmlinkage
int
sys_brk
(
unsigned
long
);
#define DLINFO_ITEMS 8
#include <linux/elf.h>
/* We need to explicitly zero any fractional pages
after the data section (i.e. bss). This would
contain the junk from the file that should not
be in memory */
static
void
padzero
(
int
elf_bss
){
unsigned
int
fpnt
,
nbyte
;
if
(
elf_bss
&
0xfff
)
{
nbyte
=
(
PAGE_SIZE
-
(
elf_bss
&
0xfff
))
&
0xfff
;
if
(
nbyte
){
verify_area
(
VERIFY_WRITE
,
(
void
*
)
elf_bss
,
nbyte
);
fpnt
=
elf_bss
;
while
(
fpnt
&
0xfff
)
put_fs_byte
(
0
,
fpnt
++
);
};
};
}
unsigned
long
*
create_elf_tables
(
char
*
p
,
int
argc
,
int
envc
,
struct
elfhdr
*
exec
,
unsigned
int
load_addr
,
int
ibcs
)
{
unsigned
long
*
argv
,
*
envp
,
*
dlinfo
;
unsigned
long
*
sp
;
struct
vm_area_struct
*
mpnt
;
mpnt
=
(
struct
vm_area_struct
*
)
kmalloc
(
sizeof
(
*
mpnt
),
GFP_KERNEL
);
if
(
mpnt
)
{
mpnt
->
vm_task
=
current
;
mpnt
->
vm_start
=
PAGE_MASK
&
(
unsigned
long
)
p
;
mpnt
->
vm_end
=
TASK_SIZE
;
mpnt
->
vm_page_prot
=
PAGE_PRIVATE
|
PAGE_DIRTY
;
mpnt
->
vm_share
=
NULL
;
mpnt
->
vm_inode
=
NULL
;
mpnt
->
vm_offset
=
0
;
mpnt
->
vm_ops
=
NULL
;
insert_vm_struct
(
current
,
mpnt
);
current
->
mm
->
stk_vma
=
mpnt
;
}
sp
=
(
unsigned
long
*
)
(
0xfffffffc
&
(
unsigned
long
)
p
);
if
(
exec
)
sp
-=
DLINFO_ITEMS
*
2
;
dlinfo
=
sp
;
sp
-=
envc
+
1
;
envp
=
sp
;
sp
-=
argc
+
1
;
argv
=
sp
;
if
(
!
ibcs
)
{
put_fs_long
((
unsigned
long
)
envp
,
--
sp
);
put_fs_long
((
unsigned
long
)
argv
,
--
sp
);
}
/* The constant numbers (0-9) that we are writing here are
described in the header file sys/auxv.h on at least
some versions of SVr4 */
if
(
exec
)
{
/* Put this here for an ELF program interpreter */
struct
elf_phdr
*
eppnt
;
eppnt
=
(
struct
elf_phdr
*
)
exec
->
e_phoff
;
put_fs_long
(
3
,
dlinfo
++
);
put_fs_long
(
load_addr
+
exec
->
e_phoff
,
dlinfo
++
);
put_fs_long
(
4
,
dlinfo
++
);
put_fs_long
(
sizeof
(
struct
elf_phdr
),
dlinfo
++
);
put_fs_long
(
5
,
dlinfo
++
);
put_fs_long
(
exec
->
e_phnum
,
dlinfo
++
);
put_fs_long
(
9
,
dlinfo
++
);
put_fs_long
((
unsigned
long
)
exec
->
e_entry
,
dlinfo
++
);
put_fs_long
(
7
,
dlinfo
++
);
put_fs_long
(
SHM_RANGE_START
,
dlinfo
++
);
put_fs_long
(
8
,
dlinfo
++
);
put_fs_long
(
0
,
dlinfo
++
);
put_fs_long
(
6
,
dlinfo
++
);
put_fs_long
(
PAGE_SIZE
,
dlinfo
++
);
put_fs_long
(
0
,
dlinfo
++
);
put_fs_long
(
0
,
dlinfo
++
);
};
put_fs_long
((
unsigned
long
)
argc
,
--
sp
);
current
->
mm
->
arg_start
=
(
unsigned
long
)
p
;
while
(
argc
-->
0
)
{
put_fs_long
((
unsigned
long
)
p
,
argv
++
);
while
(
get_fs_byte
(
p
++
))
/* nothing */
;
}
put_fs_long
(
0
,
argv
);
current
->
mm
->
arg_end
=
current
->
mm
->
env_start
=
(
unsigned
long
)
p
;
while
(
envc
-->
0
)
{
put_fs_long
((
unsigned
long
)
p
,
envp
++
);
while
(
get_fs_byte
(
p
++
))
/* nothing */
;
}
put_fs_long
(
0
,
envp
);
current
->
mm
->
env_end
=
(
unsigned
long
)
p
;
return
sp
;
}
/* This is much more generalized than the library routine read function,
so we keep this separate. Techincally the library read function
is only provided so that we can read a.out libraries that have
an ELF header */
static
unsigned
int
load_elf_interp
(
struct
elfhdr
*
interp_elf_ex
,
struct
inode
*
interpreter_inode
)
{
struct
file
*
file
;
struct
elf_phdr
*
elf_phdata
=
NULL
;
struct
elf_phdr
*
eppnt
;
unsigned
int
len
;
unsigned
int
load_addr
;
int
elf_exec_fileno
;
int
elf_bss
;
int
old_fs
,
retval
;
unsigned
int
last_bss
;
int
error
;
int
i
,
k
;
elf_bss
=
0
;
last_bss
=
0
;
error
=
load_addr
=
0
;
/* First of all, some simple consistency checks */
if
((
interp_elf_ex
->
e_type
!=
ET_EXEC
&&
interp_elf_ex
->
e_type
!=
ET_DYN
)
||
(
interp_elf_ex
->
e_machine
!=
EM_386
&&
interp_elf_ex
->
e_machine
!=
EM_486
)
||
(
!
interpreter_inode
->
i_op
||
!
interpreter_inode
->
i_op
->
bmap
||
!
interpreter_inode
->
i_op
->
default_file_ops
->
mmap
)){
return
0xffffffff
;
};
/* Now read in all of the header information */
if
(
sizeof
(
struct
elf_phdr
)
*
interp_elf_ex
->
e_phnum
>
PAGE_SIZE
)
return
0xffffffff
;
elf_phdata
=
(
struct
elf_phdr
*
)
kmalloc
(
sizeof
(
struct
elf_phdr
)
*
interp_elf_ex
->
e_phnum
,
GFP_KERNEL
);
if
(
!
elf_phdata
)
return
0xffffffff
;
old_fs
=
get_fs
();
set_fs
(
get_ds
());
retval
=
read_exec
(
interpreter_inode
,
interp_elf_ex
->
e_phoff
,
(
char
*
)
elf_phdata
,
sizeof
(
struct
elf_phdr
)
*
interp_elf_ex
->
e_phnum
);
set_fs
(
old_fs
);
elf_exec_fileno
=
open_inode
(
interpreter_inode
,
O_RDONLY
);
if
(
elf_exec_fileno
<
0
)
return
0xffffffff
;
file
=
current
->
files
->
fd
[
elf_exec_fileno
];
eppnt
=
elf_phdata
;
for
(
i
=
0
;
i
<
interp_elf_ex
->
e_phnum
;
i
++
,
eppnt
++
)
if
(
eppnt
->
p_type
==
PT_LOAD
)
{
error
=
do_mmap
(
file
,
eppnt
->
p_vaddr
&
0xfffff000
,
eppnt
->
p_filesz
+
(
eppnt
->
p_vaddr
&
0xfff
),
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_PRIVATE
|
(
interp_elf_ex
->
e_type
==
ET_EXEC
?
MAP_FIXED
:
0
),
eppnt
->
p_offset
&
0xfffff000
);
if
(
!
load_addr
&&
interp_elf_ex
->
e_type
==
ET_DYN
)
load_addr
=
error
;
k
=
load_addr
+
eppnt
->
p_vaddr
+
eppnt
->
p_filesz
;
if
(
k
>
elf_bss
)
elf_bss
=
k
;
if
(
error
<
0
&&
error
>
-
1024
)
break
;
/* Real error */
k
=
load_addr
+
eppnt
->
p_memsz
+
eppnt
->
p_vaddr
;
if
(
k
>
last_bss
)
last_bss
=
k
;
}
/* Now use mmap to map the library into memory. */
sys_close
(
elf_exec_fileno
);
if
(
error
<
0
&&
error
>
-
1024
)
{
kfree
(
elf_phdata
);
return
0xffffffff
;
}
padzero
(
elf_bss
);
len
=
(
elf_bss
+
0xfff
)
&
0xfffff000
;
/* What we have mapped so far */
/* Map the last of the bss segment */
if
(
last_bss
>
len
)
do_mmap
(
NULL
,
len
,
last_bss
-
len
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
kfree
(
elf_phdata
);
return
((
unsigned
int
)
interp_elf_ex
->
e_entry
)
+
load_addr
;
}
static
unsigned
int
load_aout_interp
(
struct
exec
*
interp_ex
,
struct
inode
*
interpreter_inode
)
{
int
retval
;
unsigned
int
elf_entry
;
current
->
mm
->
brk
=
interp_ex
->
a_bss
+
(
current
->
mm
->
end_data
=
interp_ex
->
a_data
+
(
current
->
mm
->
end_code
=
interp_ex
->
a_text
));
elf_entry
=
interp_ex
->
a_entry
;
if
(
N_MAGIC
(
*
interp_ex
)
==
OMAGIC
)
{
do_mmap
(
NULL
,
0
,
interp_ex
->
a_text
+
interp_ex
->
a_data
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
retval
=
read_exec
(
interpreter_inode
,
32
,
(
char
*
)
0
,
interp_ex
->
a_text
+
interp_ex
->
a_data
);
}
else
if
(
N_MAGIC
(
*
interp_ex
)
==
ZMAGIC
||
N_MAGIC
(
*
interp_ex
)
==
QMAGIC
)
{
do_mmap
(
NULL
,
0
,
interp_ex
->
a_text
+
interp_ex
->
a_data
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
retval
=
read_exec
(
interpreter_inode
,
N_TXTOFF
(
*
interp_ex
)
,
(
char
*
)
N_TXTADDR
(
*
interp_ex
),
interp_ex
->
a_text
+
interp_ex
->
a_data
);
}
else
retval
=
-
1
;
if
(
retval
>=
0
)
do_mmap
(
NULL
,
(
interp_ex
->
a_text
+
interp_ex
->
a_data
+
0xfff
)
&
0xfffff000
,
interp_ex
->
a_bss
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
if
(
retval
<
0
)
return
0xffffffff
;
return
elf_entry
;
}
/*
* These are the functions used to load ELF style executables and shared
* libraries. There is no binary dependent code anywhere else.
*/
#define INTERPRETER_NONE 0
#define INTERPRETER_AOUT 1
#define INTERPRETER_ELF 2
int
load_elf_binary
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
)
{
struct
elfhdr
elf_ex
;
struct
elfhdr
interp_elf_ex
;
struct
file
*
file
;
struct
exec
interp_ex
;
struct
inode
*
interpreter_inode
;
unsigned
int
load_addr
;
unsigned
int
interpreter_type
=
INTERPRETER_NONE
;
int
i
;
int
old_fs
;
int
error
;
struct
elf_phdr
*
elf_ppnt
,
*
elf_phdata
;
int
elf_exec_fileno
;
unsigned
int
elf_bss
,
k
,
elf_brk
;
int
retval
;
char
*
elf_interpreter
;
unsigned
int
elf_entry
;
int
status
;
unsigned
int
start_code
,
end_code
,
end_data
;
unsigned
int
elf_stack
;
char
passed_fileno
[
6
];
status
=
0
;
load_addr
=
0
;
elf_ex
=
*
((
struct
elfhdr
*
)
bprm
->
buf
);
/* exec-header */
if
(
elf_ex
.
e_ident
[
0
]
!=
0x7f
||
strncmp
(
&
elf_ex
.
e_ident
[
1
],
"ELF"
,
3
)
!=
0
)
return
-
ENOEXEC
;
/* First of all, some simple consistency checks */
if
(
elf_ex
.
e_type
!=
ET_EXEC
||
(
elf_ex
.
e_machine
!=
EM_386
&&
elf_ex
.
e_machine
!=
EM_486
)
||
(
!
bprm
->
inode
->
i_op
||
!
bprm
->
inode
->
i_op
->
default_file_ops
||
!
bprm
->
inode
->
i_op
->
default_file_ops
->
mmap
)){
return
-
ENOEXEC
;
};
/* Now read in all of the header information */
elf_phdata
=
(
struct
elf_phdr
*
)
kmalloc
(
elf_ex
.
e_phentsize
*
elf_ex
.
e_phnum
,
GFP_KERNEL
);
old_fs
=
get_fs
();
set_fs
(
get_ds
());
retval
=
read_exec
(
bprm
->
inode
,
elf_ex
.
e_phoff
,
(
char
*
)
elf_phdata
,
elf_ex
.
e_phentsize
*
elf_ex
.
e_phnum
);
set_fs
(
old_fs
);
if
(
retval
<
0
)
{
kfree
(
elf_phdata
);
return
retval
;
}
elf_ppnt
=
elf_phdata
;
elf_bss
=
0
;
elf_brk
=
0
;
elf_exec_fileno
=
open_inode
(
bprm
->
inode
,
O_RDONLY
);
if
(
elf_exec_fileno
<
0
)
{
kfree
(
elf_phdata
);
return
elf_exec_fileno
;
}
file
=
current
->
files
->
fd
[
elf_exec_fileno
];
elf_stack
=
0xffffffff
;
elf_interpreter
=
NULL
;
start_code
=
0
;
end_code
=
0
;
end_data
=
0
;
old_fs
=
get_fs
();
set_fs
(
get_ds
());
for
(
i
=
0
;
i
<
elf_ex
.
e_phnum
;
i
++
){
if
(
elf_ppnt
->
p_type
==
PT_INTERP
)
{
/* This is the program interpreter used for shared libraries -
for now assume that this is an a.out format binary */
elf_interpreter
=
(
char
*
)
kmalloc
(
elf_ppnt
->
p_filesz
,
GFP_KERNEL
);
retval
=
read_exec
(
bprm
->
inode
,
elf_ppnt
->
p_offset
,
elf_interpreter
,
elf_ppnt
->
p_filesz
);
#if 0
printk("Using ELF interpreter %s\n", elf_interpreter);
#endif
if
(
retval
>=
0
)
retval
=
namei
(
elf_interpreter
,
&
interpreter_inode
);
if
(
retval
>=
0
)
retval
=
read_exec
(
interpreter_inode
,
0
,
bprm
->
buf
,
128
);
if
(
retval
>=
0
){
interp_ex
=
*
((
struct
exec
*
)
bprm
->
buf
);
/* exec-header */
interp_elf_ex
=
*
((
struct
elfhdr
*
)
bprm
->
buf
);
/* exec-header */
};
if
(
retval
<
0
)
{
kfree
(
elf_phdata
);
kfree
(
elf_interpreter
);
return
retval
;
};
};
elf_ppnt
++
;
};
set_fs
(
old_fs
);
/* Some simple consistency checks for the interpreter */
if
(
elf_interpreter
){
interpreter_type
=
INTERPRETER_ELF
|
INTERPRETER_AOUT
;
if
(
retval
<
0
)
{
kfree
(
elf_interpreter
);
kfree
(
elf_phdata
);
return
-
ELIBACC
;
};
/* Now figure out which format our binary is */
if
((
N_MAGIC
(
interp_ex
)
!=
OMAGIC
)
&&
(
N_MAGIC
(
interp_ex
)
!=
ZMAGIC
)
&&
(
N_MAGIC
(
interp_ex
)
!=
QMAGIC
))
interpreter_type
=
INTERPRETER_ELF
;
if
(
interp_elf_ex
.
e_ident
[
0
]
!=
0x7f
||
strncmp
(
&
interp_elf_ex
.
e_ident
[
1
],
"ELF"
,
3
)
!=
0
)
interpreter_type
&=
~
INTERPRETER_ELF
;
if
(
!
interpreter_type
)
{
kfree
(
elf_interpreter
);
kfree
(
elf_phdata
);
return
-
ELIBBAD
;
};
}
/* OK, we are done with that, now set up the arg stuff,
and then start this sucker up */
if
(
!
bprm
->
sh_bang
)
{
char
*
passed_p
;
if
(
interpreter_type
==
INTERPRETER_AOUT
)
{
sprintf
(
passed_fileno
,
"%d"
,
elf_exec_fileno
);
passed_p
=
passed_fileno
;
if
(
elf_interpreter
)
{
bprm
->
p
=
copy_strings
(
1
,
&
passed_p
,
bprm
->
page
,
bprm
->
p
,
2
);
bprm
->
argc
++
;
};
};
if
(
!
bprm
->
p
)
{
if
(
elf_interpreter
)
{
kfree
(
elf_interpreter
);
}
kfree
(
elf_phdata
);
return
-
E2BIG
;
}
}
/* OK, This is the point of no return */
flush_old_exec
(
bprm
);
current
->
mm
->
end_data
=
0
;
current
->
mm
->
end_code
=
0
;
current
->
mm
->
start_mmap
=
ELF_START_MMAP
;
current
->
mm
->
mmap
=
NULL
;
elf_entry
=
(
unsigned
int
)
elf_ex
.
e_entry
;
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
current
->
mm
->
rss
=
0
;
bprm
->
p
+=
change_ldt
(
0
,
bprm
->
page
);
current
->
mm
->
start_stack
=
bprm
->
p
;
/* Now we do a little grungy work by mmaping the ELF image into
the correct location in memory. At this point, we assume that
the image should be loaded at fixed address, not at a variable
address. */
old_fs
=
get_fs
();
set_fs
(
get_ds
());
elf_ppnt
=
elf_phdata
;
for
(
i
=
0
;
i
<
elf_ex
.
e_phnum
;
i
++
){
if
(
elf_ppnt
->
p_type
==
PT_INTERP
)
{
/* Set these up so that we are able to load the interpreter */
/* Now load the interpreter into user address space */
set_fs
(
old_fs
);
if
(
interpreter_type
&
1
)
elf_entry
=
load_aout_interp
(
&
interp_ex
,
interpreter_inode
);
if
(
interpreter_type
&
2
)
elf_entry
=
load_elf_interp
(
&
interp_elf_ex
,
interpreter_inode
);
old_fs
=
get_fs
();
set_fs
(
get_ds
());
iput
(
interpreter_inode
);
kfree
(
elf_interpreter
);
if
(
elf_entry
==
0xffffffff
)
{
printk
(
"Unable to load interpreter
\n
"
);
kfree
(
elf_phdata
);
send_sig
(
SIGSEGV
,
current
,
0
);
return
0
;
};
};
if
(
elf_ppnt
->
p_type
==
PT_LOAD
)
{
error
=
do_mmap
(
file
,
elf_ppnt
->
p_vaddr
&
0xfffff000
,
elf_ppnt
->
p_filesz
+
(
elf_ppnt
->
p_vaddr
&
0xfff
),
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
elf_ppnt
->
p_offset
&
0xfffff000
);
#ifdef LOW_ELF_STACK
if
(
elf_ppnt
->
p_vaddr
&
0xfffff000
<
elf_stack
)
elf_stack
=
elf_ppnt
->
p_vaddr
&
0xfffff000
;
#endif
if
(
!
load_addr
)
load_addr
=
elf_ppnt
->
p_vaddr
-
elf_ppnt
->
p_offset
;
k
=
elf_ppnt
->
p_vaddr
;
if
(
k
>
start_code
)
start_code
=
k
;
k
=
elf_ppnt
->
p_vaddr
+
elf_ppnt
->
p_filesz
;
if
(
k
>
elf_bss
)
elf_bss
=
k
;
if
((
elf_ppnt
->
p_flags
|
PROT_WRITE
)
&&
end_code
<
k
)
end_code
=
k
;
if
(
end_data
<
k
)
end_data
=
k
;
k
=
elf_ppnt
->
p_vaddr
+
elf_ppnt
->
p_memsz
;
if
(
k
>
elf_brk
)
elf_brk
=
k
;
};
elf_ppnt
++
;
};
set_fs
(
old_fs
);
kfree
(
elf_phdata
);
if
(
!
elf_interpreter
)
sys_close
(
elf_exec_fileno
);
current
->
elf_executable
=
1
;
current
->
executable
=
bprm
->
inode
;
bprm
->
inode
->
i_count
++
;
#ifdef LOW_ELF_STACK
current
->
start_stack
=
p
=
elf_stack
-
4
;
#endif
bprm
->
p
-=
MAX_ARG_PAGES
*
PAGE_SIZE
;
bprm
->
p
=
(
unsigned
long
)
create_elf_tables
((
char
*
)
bprm
->
p
,
bprm
->
argc
,
bprm
->
envc
,
(
interpreter_type
==
INTERPRETER_ELF
?
&
elf_ex
:
NULL
),
load_addr
,
(
interpreter_type
==
INTERPRETER_AOUT
?
0
:
1
));
if
(
interpreter_type
==
INTERPRETER_AOUT
)
current
->
mm
->
arg_start
+=
strlen
(
passed_fileno
)
+
1
;
current
->
mm
->
start_brk
=
current
->
mm
->
brk
=
elf_brk
;
current
->
mm
->
end_code
=
end_code
;
current
->
mm
->
start_code
=
start_code
;
current
->
mm
->
end_data
=
end_data
;
current
->
mm
->
start_stack
=
bprm
->
p
;
current
->
suid
=
current
->
euid
=
bprm
->
e_uid
;
current
->
sgid
=
current
->
egid
=
bprm
->
e_gid
;
/* Calling sys_brk effectively mmaps the pages that we need for the bss and break
sections */
current
->
mm
->
brk
=
(
elf_bss
+
0xfff
)
&
0xfffff000
;
sys_brk
((
elf_brk
+
0xfff
)
&
0xfffff000
);
padzero
(
elf_bss
);
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */
error
=
do_mmap
(
NULL
,
0
,
4096
,
PROT_READ
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
regs
->
eip
=
elf_entry
;
/* eip, magic happens :-) */
regs
->
esp
=
bprm
->
p
;
/* stack pointer */
if
(
current
->
flags
&
PF_PTRACED
)
send_sig
(
SIGTRAP
,
current
,
0
);
return
0
;
}
/* This is really simpleminded and specialized - we are loading an
a.out library that is given an ELF header. */
int
load_elf_library
(
int
fd
){
struct
file
*
file
;
struct
elfhdr
elf_ex
;
struct
elf_phdr
*
elf_phdata
=
NULL
;
struct
inode
*
inode
;
unsigned
int
len
;
int
elf_bss
;
int
old_fs
,
retval
;
unsigned
int
bss
;
int
error
;
int
i
,
j
,
k
;
len
=
0
;
file
=
current
->
files
->
fd
[
fd
];
inode
=
file
->
f_inode
;
elf_bss
=
0
;
set_fs
(
KERNEL_DS
);
if
(
file
->
f_op
->
read
(
inode
,
file
,
(
char
*
)
&
elf_ex
,
sizeof
(
elf_ex
))
!=
sizeof
(
elf_ex
))
{
sys_close
(
fd
);
return
-
EACCES
;
}
set_fs
(
USER_DS
);
if
(
elf_ex
.
e_ident
[
0
]
!=
0x7f
||
strncmp
(
&
elf_ex
.
e_ident
[
1
],
"ELF"
,
3
)
!=
0
)
return
-
ENOEXEC
;
/* First of all, some simple consistency checks */
if
(
elf_ex
.
e_type
!=
ET_EXEC
||
elf_ex
.
e_phnum
>
2
||
(
elf_ex
.
e_machine
!=
EM_386
&&
elf_ex
.
e_machine
!=
EM_486
)
||
(
!
inode
->
i_op
||
!
inode
->
i_op
->
bmap
||
!
inode
->
i_op
->
default_file_ops
->
mmap
)){
return
-
ENOEXEC
;
};
/* Now read in all of the header information */
if
(
sizeof
(
struct
elf_phdr
)
*
elf_ex
.
e_phnum
>
PAGE_SIZE
)
return
-
ENOEXEC
;
elf_phdata
=
(
struct
elf_phdr
*
)
kmalloc
(
sizeof
(
struct
elf_phdr
)
*
elf_ex
.
e_phnum
,
GFP_KERNEL
);
old_fs
=
get_fs
();
set_fs
(
get_ds
());
retval
=
read_exec
(
inode
,
elf_ex
.
e_phoff
,
(
char
*
)
elf_phdata
,
sizeof
(
struct
elf_phdr
)
*
elf_ex
.
e_phnum
);
set_fs
(
old_fs
);
j
=
0
;
for
(
i
=
0
;
i
<
elf_ex
.
e_phnum
;
i
++
)
if
((
elf_phdata
+
i
)
->
p_type
==
PT_LOAD
)
j
++
;
if
(
j
!=
1
)
{
kfree
(
elf_phdata
);
return
-
ENOEXEC
;
};
while
(
elf_phdata
->
p_type
!=
PT_LOAD
)
elf_phdata
++
;
/* Now use mmap to map the library into memory. */
error
=
do_mmap
(
file
,
elf_phdata
->
p_vaddr
&
0xfffff000
,
elf_phdata
->
p_filesz
+
(
elf_phdata
->
p_vaddr
&
0xfff
),
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
elf_phdata
->
p_offset
&
0xfffff000
);
k
=
elf_phdata
->
p_vaddr
+
elf_phdata
->
p_filesz
;
if
(
k
>
elf_bss
)
elf_bss
=
k
;
sys_close
(
fd
);
if
(
error
!=
elf_phdata
->
p_vaddr
&
0xfffff000
)
{
kfree
(
elf_phdata
);
return
error
;
}
padzero
(
elf_bss
);
len
=
(
elf_phdata
->
p_filesz
+
elf_phdata
->
p_vaddr
+
0xfff
)
&
0xfffff000
;
bss
=
elf_phdata
->
p_memsz
+
elf_phdata
->
p_vaddr
;
if
(
bss
>
len
)
do_mmap
(
NULL
,
len
,
bss
-
len
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
,
MAP_FIXED
|
MAP_PRIVATE
,
0
);
kfree
(
elf_phdata
);
return
0
;
}
include/linux/binfmts.h
View file @
1650f8d3
...
...
@@ -24,15 +24,18 @@ struct linux_binprm{
char
*
filename
;
/* Name of binary */
};
/* This structure defines the functions that are used to load the binary formats that
* linux accepts. */
struct
linux_binfmt
{
/*
* This structure defines the functions that are used to load the binary formats that
* linux accepts.
*/
struct
linux_binfmt
{
struct
linux_binfmt
*
next
;
int
(
*
load_binary
)(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
int
(
*
load_shlib
)(
int
fd
);
};
extern
struct
linux_binfmt
formats
[];
extern
int
register_binfmt
(
struct
linux_binfmt
*
);
extern
int
unregister_binfmt
(
struct
linux_binfmt
*
);
extern
int
read_exec
(
struct
inode
*
inode
,
unsigned
long
offset
,
char
*
addr
,
unsigned
long
count
);
...
...
include/linux/personality.h
0 → 100644
View file @
1650f8d3
/* Flags for bug emulation. These occupy the top three bytes. */
#define STICKY_TIMEOUTS 0x8000000
#define WHOLE_SECONDS 0x4000000
/* Personality types. These go in the low byte. */
#define PER_MASK (0x00ff)
#define PER_LINUX (0x0000)
#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
include/linux/sched.h
View file @
1650f8d3
...
...
@@ -254,10 +254,12 @@ struct task_struct {
/* various fields */
struct
task_struct
*
next_task
,
*
prev_task
;
struct
sigaction
sigaction
[
32
];
unsigned
long
*
signal_map
;
unsigned
long
*
signal_invmap
;
unsigned
long
saved_kernel_stack
;
unsigned
long
kernel_stack_page
;
int
exit_code
,
exit_signal
;
int
elf_executable
:
1
;
unsigned
long
personality
;
int
dumpable
:
1
;
int
did_exec
:
1
;
int
pid
,
pgrp
,
session
,
leader
;
...
...
@@ -323,7 +325,7 @@ struct task_struct {
/* state etc */
{ 0,15,15,0,0,0,0, \
/* debugregs */
{ 0, }, \
/* schedlink */
&init_task,&init_task, \
/* signals */
{{ 0, },}, \
/* signals */
{{ 0, },},
ident_map, ident_map,
\
/* stack */
0,(unsigned long) &init_kernel_stack, \
/* ec,brk... */
0,0,0,0,0, \
/* pid etc.. */
0,0,0,0, \
...
...
kernel/exit.c
View file @
1650f8d3
...
...
@@ -282,10 +282,12 @@ int kill_proc(int pid, int sig, int priv)
* POSIX specifies that kill(-1,sig) is unspecified, but what we have
* is probably wrong. Should make it like BSD or SYSV.
*/
asmlinkage
int
sys_kill
(
int
pid
,
int
sig
)
asmlinkage
int
sys_kill
(
int
pid
,
unsigned
int
sig
)
{
int
err
,
retval
=
0
,
count
=
0
;
if
(
sig
>
32
)
return
-
EINVAL
;
if
(
!
pid
)
return
(
kill_pg
(
current
->
pgrp
,
sig
,
0
));
if
(
pid
==
-
1
)
{
...
...
kernel/ksyms.c
View file @
1650f8d3
...
...
@@ -15,6 +15,7 @@
#include <linux/sys.h>
#include <linux/utsname.h>
#include <linux/interrupt.h>
#include <linux/binfmts.h>
#ifdef CONFIG_INET
#include <linux/netdevice.h>
#endif
...
...
@@ -28,20 +29,16 @@ extern char * ftape_big_buffer;
extern
void
(
*
do_floppy
)(
void
);
#endif
#ifdef CONFIG_BINFMT_IBCS
extern
int
do_execve
(
char
*
filename
,
char
**
argv
,
char
**
envp
,
struct
pt_regs
*
regs
);
extern
void
flush_old_exec
(
struct
linux_binprm
*
bprm
);
extern
int
open_inode
(
struct
inode
*
inode
,
int
mode
);
extern
int
read_exec
(
struct
inode
*
inode
,
unsigned
long
offset
,
char
*
addr
,
unsigned
long
count
);
extern
void
check_pending
(
int
signum
);
extern
int
do_signal
(
unsigned
long
oldmask
,
struct
pt_regs
*
regs
);
extern
int
(
*
ibcs_invmapsig
)(
int
);
extern
void
(
*
iABI_hook
)(
struct
pt_regs
*
regs
);
#endif
#ifdef CONFIG_INET
extern
int
register_netdev
(
struct
device
*
);
extern
void
unregister_netdev
(
struct
device
*
);
...
...
@@ -67,6 +64,8 @@ struct {
X
(
__verify_write
),
X
(
do_mmap
),
X
(
do_munmap
),
X
(
insert_vm_struct
),
X
(
zeromap_page_range
),
/* internal kernel memory management */
X
(
__get_free_pages
),
...
...
@@ -94,6 +93,10 @@ struct {
X
(
register_filesystem
),
X
(
unregister_filesystem
),
/* executable format registration */
X
(
register_binfmt
),
X
(
unregister_binfmt
),
/* interrupt handling */
X
(
request_irq
),
X
(
free_irq
),
...
...
@@ -115,24 +118,8 @@ struct {
X
(
system_utsname
),
X
(
sys_call_table
),
#ifdef CONFIG_FTAPE
/* The next labels are needed for ftape driver. */
X
(
ftape_big_buffer
),
X
(
do_floppy
),
#endif
#ifdef CONFIG_BINFMT_IBCS
/*
* The following are needed if iBCS support is modular rather than
* compiled in.
*/
/* Emulator hooks. */
X
(
iABI_hook
),
X
(
ibcs_invmapsig
),
/* Signal interfaces */
X
(
do_signal
),
X
(
check_pending
),
X
(
send_sig
),
/* Program loader interfaces */
...
...
@@ -141,16 +128,17 @@ struct {
X
(
create_tables
),
X
(
do_execve
),
X
(
flush_old_exec
),
X
(
formats
),
X
(
insert_vm_struct
),
X
(
open_inode
),
X
(
read_exec
),
X
(
zeromap_page_range
),
/* Miscellaneous access points */
X
(
si_meminfo
),
#endif
#ifdef CONFIG_FTAPE
/* The next labels are needed for ftape driver. */
X
(
ftape_big_buffer
),
X
(
do_floppy
),
#endif
#ifdef CONFIG_INET
/* support for loadable net drivers */
X
(
register_netdev
),
...
...
kernel/sched.c
View file @
1650f8d3
...
...
@@ -87,6 +87,16 @@ extern void mem_use(void);
extern
int
timer_interrupt
(
void
);
asmlinkage
int
system_call
(
void
);
/*
* signal mapping: this is the default identity mapping used for normal
* linux binaries (it's both the reverse and the normal map, of course)
*/
static
unsigned
long
ident_map
[
33
]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
};
static
unsigned
long
init_kernel_stack
[
1024
]
=
{
STACK_MAGIC
,
};
struct
task_struct
init_task
=
INIT_TASK
;
...
...
kernel/signal.c
View file @
1650f8d3
...
...
@@ -135,7 +135,9 @@ asmlinkage int sys_signal(int signum, unsigned long handler)
{
struct
sigaction
tmp
;
if
(
signum
<
1
||
signum
>
32
||
signum
==
SIGKILL
||
signum
==
SIGSTOP
)
if
(
signum
<
1
||
signum
>
32
)
return
-
EINVAL
;
if
(
signum
==
SIGKILL
||
signum
==
SIGSTOP
)
return
-
EINVAL
;
if
(
handler
>=
TASK_SIZE
)
return
-
EFAULT
;
...
...
@@ -154,7 +156,9 @@ asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
{
struct
sigaction
new_sa
,
*
p
;
if
(
signum
<
1
||
signum
>
32
||
signum
==
SIGKILL
||
signum
==
SIGSTOP
)
if
(
signum
<
1
||
signum
>
32
)
return
-
EINVAL
;
if
(
signum
==
SIGKILL
||
signum
==
SIGSTOP
)
return
-
EINVAL
;
p
=
signum
-
1
+
current
->
sigaction
;
if
(
action
)
{
...
...
@@ -242,7 +246,7 @@ static void setup_frame(struct sigaction * sa, unsigned long ** fp, unsigned lon
do_exit
(
SIGSEGV
);
/* set up the "normal" stack seen by the signal handler (iBCS2) */
put_fs_long
(
__CODE
,
frame
);
put_fs_long
(
signr
,
frame
+
1
);
put_fs_long
(
current
->
signal_invmap
[
signr
]
,
frame
+
1
);
put_fs_long
(
regs
->
gs
,
frame
+
2
);
put_fs_long
(
regs
->
fs
,
frame
+
3
);
put_fs_long
(
regs
->
es
,
frame
+
4
);
...
...
net/inet/p8022.c
View file @
1650f8d3
...
...
@@ -3,7 +3,6 @@
#include "datalink.h"
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/ddi.h>
static
struct
datalink_proto
*
p8022_list
=
NULL
;
...
...
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