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
60b75a3c
Commit
60b75a3c
authored
Oct 24, 2003
by
David Mosberger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ia64: Fix/finish kernel module table support so it actually works.
parent
7502ff99
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
15 deletions
+84
-15
arch/ia64/kernel/module.c
arch/ia64/kernel/module.c
+75
-7
arch/ia64/kernel/unwind_i.h
arch/ia64/kernel/unwind_i.h
+1
-7
include/asm-ia64/module.h
include/asm-ia64/module.h
+2
-1
include/asm-ia64/unwind.h
include/asm-ia64/unwind.h
+6
-0
No files found.
arch/ia64/kernel/module.c
View file @
60b75a3c
...
@@ -322,6 +322,10 @@ module_alloc (unsigned long size)
...
@@ -322,6 +322,10 @@ module_alloc (unsigned long size)
void
void
module_free
(
struct
module
*
mod
,
void
*
module_region
)
module_free
(
struct
module
*
mod
,
void
*
module_region
)
{
{
if
(
mod
->
arch
.
init_unw_table
&&
module_region
==
mod
->
module_init
)
{
unw_remove_unwind_table
(
mod
->
arch
.
init_unw_table
);
mod
->
arch
.
init_unw_table
=
NULL
;
}
vfree
(
module_region
);
vfree
(
module_region
);
}
}
...
@@ -843,23 +847,87 @@ apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
...
@@ -843,23 +847,87 @@ apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
return
-
ENOEXEC
;
return
-
ENOEXEC
;
}
}
/*
* Modules contain a single unwind table which covers both the core and the init text
* sections but since the two are not contiguous, we need to split this table up such that
* we can register (and unregister) each "segment" seperately. Fortunately, this sounds
* more complicated than it really is.
*/
static
void
register_unwind_table
(
struct
module
*
mod
)
{
struct
unw_table_entry
*
start
=
(
void
*
)
mod
->
arch
.
unwind
->
sh_addr
;
struct
unw_table_entry
*
end
=
start
+
mod
->
arch
.
unwind
->
sh_size
/
sizeof
(
*
start
);
struct
unw_table_entry
tmp
,
*
e1
,
*
e2
,
*
core
,
*
init
;
unsigned
long
num_init
=
0
,
num_core
=
0
;
/* First, count how many init and core unwind-table entries there are. */
for
(
e1
=
start
;
e1
<
end
;
++
e1
)
if
(
in_init
(
mod
,
e1
->
start_offset
))
++
num_init
;
else
++
num_core
;
/*
* Second, sort the table such that all unwind-table entries for the init and core
* text sections are nicely separated. We do this with a stupid bubble sort
* (unwind tables don't get ridiculously huge).
*/
for
(
e1
=
start
;
e1
<
end
;
++
e1
)
{
for
(
e2
=
e1
+
1
;
e2
<
end
;
++
e2
)
{
if
(
e2
->
start_offset
<
e1
->
start_offset
)
{
tmp
=
*
e1
;
*
e1
=
*
e2
;
*
e2
=
tmp
;
}
}
}
/*
* Third, locate the init and core segments in the unwind table:
*/
if
(
in_init
(
mod
,
start
->
start_offset
))
{
init
=
start
;
core
=
start
+
num_init
;
}
else
{
core
=
start
;
init
=
start
+
num_core
;
}
DEBUGP
(
"%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu
\n
"
,
__FUNCTION__
,
mod
->
name
,
mod
->
arch
.
gp
,
num_init
,
num_core
);
/*
* Fourth, register both tables (if not empty).
*/
if
(
num_core
>
0
)
{
mod
->
arch
.
core_unw_table
=
unw_add_unwind_table
(
mod
->
name
,
0
,
mod
->
arch
.
gp
,
core
,
core
+
num_core
);
DEBUGP
(
"%s: core: handle=%p [%p-%p)
\n
"
,
__FUNCTION__
,
mod
->
arch
.
core_unw_table
,
core
,
core
+
num_core
);
}
if
(
num_init
>
0
)
{
mod
->
arch
.
init_unw_table
=
unw_add_unwind_table
(
mod
->
name
,
0
,
mod
->
arch
.
gp
,
init
,
init
+
num_init
);
DEBUGP
(
"%s: init: handle=%p [%p-%p)
\n
"
,
__FUNCTION__
,
mod
->
arch
.
init_unw_table
,
init
,
init
+
num_init
);
}
}
int
int
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
mod
)
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
mod
)
{
{
DEBUGP
(
"%s: init: entry=%p
\n
"
,
__FUNCTION__
,
mod
->
init
);
DEBUGP
(
"%s: init: entry=%p
\n
"
,
__FUNCTION__
,
mod
->
init
);
if
(
mod
->
arch
.
unwind
)
if
(
mod
->
arch
.
unwind
)
mod
->
arch
.
unw_table
=
unw_add_unwind_table
(
mod
->
name
,
0
,
mod
->
arch
.
gp
,
register_unwind_table
(
mod
);
(
void
*
)
mod
->
arch
.
unwind
->
sh_addr
,
((
void
*
)
mod
->
arch
.
unwind
->
sh_addr
+
mod
->
arch
.
unwind
->
sh_size
));
return
0
;
return
0
;
}
}
void
void
module_arch_cleanup
(
struct
module
*
mod
)
module_arch_cleanup
(
struct
module
*
mod
)
{
{
if
(
mod
->
arch
.
unwind
)
if
(
mod
->
arch
.
init_unw_table
)
unw_remove_unwind_table
(
mod
->
arch
.
unw_table
);
unw_remove_unwind_table
(
mod
->
arch
.
init_unw_table
);
if
(
mod
->
arch
.
core_unw_table
)
unw_remove_unwind_table
(
mod
->
arch
.
core_unw_table
);
}
}
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
...
...
arch/ia64/kernel/unwind_i.h
View file @
60b75a3c
/*
/*
* Copyright (C) 2000, 2002 Hewlett-Packard Co
* Copyright (C) 2000, 2002
-2003
Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* David Mosberger-Tang <davidm@hpl.hp.com>
*
*
* Kernel unwind support.
* Kernel unwind support.
...
@@ -45,12 +45,6 @@ struct unw_info_block {
...
@@ -45,12 +45,6 @@ struct unw_info_block {
/* personality routine and language-specific data follow behind descriptors */
/* personality routine and language-specific data follow behind descriptors */
};
};
struct
unw_table_entry
{
u64
start_offset
;
u64
end_offset
;
u64
info_offset
;
};
struct
unw_table
{
struct
unw_table
{
struct
unw_table
*
next
;
/* must be first member! */
struct
unw_table
*
next
;
/* must be first member! */
const
char
*
name
;
const
char
*
name
;
...
...
include/asm-ia64/module.h
View file @
60b75a3c
...
@@ -18,7 +18,8 @@ struct mod_arch_specific {
...
@@ -18,7 +18,8 @@ struct mod_arch_specific {
struct
elf64_shdr
*
unwind
;
/* unwind-table section */
struct
elf64_shdr
*
unwind
;
/* unwind-table section */
unsigned
long
gp
;
/* global-pointer for module */
unsigned
long
gp
;
/* global-pointer for module */
void
*
unw_table
;
/* unwind-table cookie returned by unwinder */
void
*
core_unw_table
;
/* core unwind-table cookie returned by unwinder */
void
*
init_unw_table
;
/* init unwind-table cookie returned by unwinder */
unsigned
int
next_got_entry
;
/* index of next available got entry */
unsigned
int
next_got_entry
;
/* index of next available got entry */
};
};
...
...
include/asm-ia64/unwind.h
View file @
60b75a3c
...
@@ -93,6 +93,12 @@ struct unw_frame_info {
...
@@ -93,6 +93,12 @@ struct unw_frame_info {
* The official API follows below:
* The official API follows below:
*/
*/
struct
unw_table_entry
{
u64
start_offset
;
u64
end_offset
;
u64
info_offset
;
};
/*
/*
* Initialize unwind support.
* Initialize unwind support.
*/
*/
...
...
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