Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
30a3866b
Commit
30a3866b
authored
Jul 31, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
preloader: Added support for the new style DT_GNU_HASH symbol table.
parent
51d84822
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
13 deletions
+46
-13
preloader.c
loader/preloader.c
+46
-13
No files found.
loader/preloader.c
View file @
30a3866b
...
...
@@ -131,6 +131,10 @@ static struct wine_preload_info preload_info[] =
#define AT_SYSINFO_EHDR 33
#endif
#ifndef DT_GNU_HASH
#define DT_GNU_HASH 0x6ffffef5
#endif
static
unsigned
int
page_size
,
page_mask
;
static
char
*
preloader_start
,
*
preloader_end
;
...
...
@@ -758,6 +762,13 @@ static unsigned int elf_hash( const char *name )
return
hash
;
}
static
unsigned
int
gnu_hash
(
const
char
*
name
)
{
unsigned
int
h
=
5381
;
while
(
*
name
)
h
=
h
*
33
+
(
unsigned
char
)
*
name
++
;
return
h
;
}
/*
* Find a symbol in the symbol table of the executable loaded
*/
...
...
@@ -767,7 +778,9 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int
const
ElfW
(
Phdr
)
*
ph
;
const
ElfW
(
Sym
)
*
symtab
=
NULL
;
const
Elf_Symndx
*
hashtab
=
NULL
;
const
Elf32_Word
*
gnu_hashtab
=
NULL
;
const
char
*
strings
=
NULL
;
Elf_Symndx
idx
;
/* check the values */
#ifdef DUMP_SYMS
...
...
@@ -799,6 +812,8 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int
symtab
=
(
const
ElfW
(
Sym
)
*
)
dyn
->
d_un
.
d_ptr
;
if
(
dyn
->
d_tag
==
DT_HASH
)
hashtab
=
(
const
Elf_Symndx
*
)
dyn
->
d_un
.
d_ptr
;
if
(
dyn
->
d_tag
==
DT_GNU_HASH
)
gnu_hashtab
=
(
const
Elf32_Word
*
)
dyn
->
d_un
.
d_ptr
;
#ifdef DUMP_SYMS
wld_printf
(
"%x %x
\n
"
,
dyn
->
d_tag
,
dyn
->
d_un
.
d_ptr
);
#endif
...
...
@@ -807,28 +822,46 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int
if
(
(
!
symtab
)
||
(
!
strings
)
)
return
NULL
;
if
(
hashtab
)
if
(
gnu_hashtab
)
/* new style hash table */
{
const
unsigned
int
hash
=
gnu_hash
(
var
);
const
Elf32_Word
nbuckets
=
gnu_hashtab
[
0
];
const
Elf32_Word
symbias
=
gnu_hashtab
[
1
];
const
Elf32_Word
nwords
=
gnu_hashtab
[
2
];
const
ElfW
(
Addr
)
*
bitmask
=
(
const
ElfW
(
Addr
)
*
)(
gnu_hashtab
+
4
);
const
Elf32_Word
*
buckets
=
(
const
Elf32_Word
*
)(
bitmask
+
nwords
);
const
Elf32_Word
*
chains
=
buckets
+
nbuckets
-
symbias
;
if
(
!
(
idx
=
buckets
[
hash
%
nbuckets
]))
return
NULL
;
do
{
if
((
chains
[
idx
]
&
~
1u
)
==
(
hash
&
~
1u
)
&&
symtab
[
idx
].
st_info
==
ELF32_ST_INFO
(
STB_GLOBAL
,
type
)
&&
!
wld_strcmp
(
strings
+
symtab
[
idx
].
st_name
,
var
))
goto
found
;
}
while
(
!
(
chains
[
idx
++
]
&
1u
));
}
else
if
(
hashtab
)
/* old style hash table */
{
Elf_Symndx
nbuckets
=
hashtab
[
0
]
;
unsigned
int
hash
=
elf_hash
(
var
)
%
nbuckets
;
const
unsigned
int
hash
=
elf_hash
(
var
)
;
const
Elf_Symndx
nbuckets
=
hashtab
[
0
]
;
const
Elf_Symndx
*
buckets
=
hashtab
+
2
;
const
Elf_Symndx
*
chains
=
buckets
+
nbuckets
;
Elf_Symndx
idx
=
buckets
[
hash
];
const
Elf_Symndx
*
chains
=
buckets
+
nbuckets
;
while
(
idx
!=
STN_UNDEF
)
for
(
idx
=
buckets
[
hash
%
nbuckets
];
idx
!=
STN_UNDEF
;
idx
=
chains
[
idx
]
)
{
if
(
symtab
[
idx
].
st_info
==
ELF32_ST_INFO
(
STB_GLOBAL
,
type
)
&&
!
wld_strcmp
(
strings
+
symtab
[
idx
].
st_name
,
var
))
{
#ifdef DUMP_SYMS
wld_printf
(
"Found %s -> %x
\n
"
,
strings
+
symtab
[
idx
].
st_name
,
symtab
[
idx
].
st_value
);
#endif
return
(
void
*
)
symtab
[
idx
].
st_value
;
}
idx
=
chains
[
idx
];
goto
found
;
}
}
return
NULL
;
found
:
#ifdef DUMP_SYMS
wld_printf
(
"Found %s -> %x
\n
"
,
strings
+
symtab
[
idx
].
st_name
,
symtab
[
idx
].
st_value
);
#endif
return
(
void
*
)
symtab
[
idx
].
st_value
;
}
/*
...
...
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