Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
jberryman
GHC
Commits
41fb6366
Commit
41fb6366
authored
Dec 29, 2012
by
aljee@hyper.cx
Committed by
Austin Seipp
Oct 25, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ghci: add support for ELF weak symbols
Signed-off-by:
Austin Seipp
<
austin@well-typed.com
>
parent
736ed655
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
77 additions
and
23 deletions
+77
-23
rts/Linker.c
rts/Linker.c
+77
-23
No files found.
rts/Linker.c
View file @
41fb6366
...
...
@@ -137,7 +137,13 @@
#include <sys/tls.h>
#endif
/* Hash table mapping symbol names to Symbol */
typedef
struct
_RtsSymbolInfo
{
void
*
value
;
const
ObjectCode
*
owner
;
HsBool
weak
;
}
RtsSymbolInfo
;
/* Hash table mapping symbol names to RtsSymbolInfo */
static
/*Str*/
HashTable
*
symhash
;
/* List of currently loaded objects */
...
...
@@ -1464,15 +1470,31 @@ static RtsSymbolVal rtsSyms[] = {
* Insert symbols into hash tables, checking for duplicates.
*/
static
void
ghciInsertStrHashTable
(
pathchar
*
obj_name
,
HashTable
*
table
,
char
*
key
,
void
*
data
)
static
void
ghciInsertSymbolTable
(
pathchar
*
obj_name
,
HashTable
*
table
,
char
*
key
,
void
*
data
,
HsBool
weak
,
ObjectCode
*
owner
)
{
if
(
lookupHashTable
(
table
,
(
StgWord
)
key
)
==
NULL
)
RtsSymbolInfo
*
pinfo
=
lookupStrHashTable
(
table
,
key
);
if
(
!
pinfo
)
/* new entry */
{
pinfo
=
stgMallocBytes
(
sizeof
(
*
pinfo
),
"ghciInsertToSymbolTable"
);
pinfo
->
value
=
data
;
pinfo
->
owner
=
owner
;
pinfo
->
weak
=
weak
;
insertStrHashTable
(
table
,
key
,
pinfo
);
return
;
}
else
if
((
!
pinfo
->
weak
||
pinfo
->
value
)
&&
weak
)
{
return
;
/* duplicate weak symbol, throw it away */
}
else
if
(
pinfo
->
weak
)
/* weak symbol is in the table */
{
insertStrHashTable
(
table
,
(
StgWord
)
key
,
data
);
/* override the weak definition with the non-weak one */
pinfo
->
value
=
data
;
pinfo
->
owner
=
owner
;
pinfo
->
weak
=
HS_BOOL_FALSE
;
return
;
}
debugBelch
(
...
...
@@ -1493,6 +1515,32 @@ static void ghciInsertStrHashTable ( pathchar* obj_name,
);
stg_exit
(
1
);
}
static
HsBool
ghciLookupSymbolTable
(
HashTable
*
table
,
const
char
*
key
,
void
**
result
)
{
RtsSymbolInfo
*
pinfo
=
lookupStrHashTable
(
table
,
key
);
if
(
!
pinfo
)
{
*
result
=
NULL
;
return
HS_BOOL_FALSE
;
}
if
(
pinfo
->
weak
)
IF_DEBUG
(
linker
,
debugBelch
(
"lookup: promoting %s
\n
"
,
key
));
/* Once it's looked up, it can no longer be overridden */
pinfo
->
weak
=
HS_BOOL_FALSE
;
*
result
=
pinfo
->
value
;
return
HS_BOOL_TRUE
;
}
static
void
ghciRemoveSymbolTable
(
HashTable
*
table
,
const
char
*
key
,
ObjectCode
*
owner
)
{
RtsSymbolInfo
*
pinfo
=
lookupStrHashTable
(
table
,
key
);
if
(
!
pinfo
||
owner
!=
pinfo
->
owner
)
return
;
removeStrHashTable
(
table
,
key
,
NULL
);
stgFree
(
pinfo
);
}
/* -----------------------------------------------------------------------------
* initialize the object linker
*/
...
...
@@ -1539,8 +1587,8 @@ initLinker( void )
/* populate the symbol table with stuff from the RTS */
for
(
sym
=
rtsSyms
;
sym
->
lbl
!=
NULL
;
sym
++
)
{
ghciInsertS
trHash
Table
(
WSTR
(
"(GHCi built-in symbols)"
),
symhash
,
sym
->
lbl
,
sym
->
addr
);
ghciInsertS
ymbol
Table
(
WSTR
(
"(GHCi built-in symbols)"
),
symhash
,
sym
->
lbl
,
sym
->
addr
,
HS_BOOL_FALSE
,
NULL
);
IF_DEBUG
(
linker
,
debugBelch
(
"initLinker: inserting rts symbol %s, %p
\n
"
,
sym
->
lbl
,
sym
->
addr
));
}
# if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
...
...
@@ -1868,7 +1916,7 @@ error:
void
insertSymbol
(
pathchar
*
obj_name
,
char
*
key
,
void
*
data
)
{
ghciInsertS
trHashTable
(
obj_name
,
symhash
,
key
,
data
);
ghciInsertS
ymbolTable
(
obj_name
,
symhash
,
key
,
data
,
HS_BOOL_FALSE
,
NULL
);
}
/* -----------------------------------------------------------------------------
...
...
@@ -1881,9 +1929,8 @@ lookupSymbol( char *lbl )
IF_DEBUG
(
linker
,
debugBelch
(
"lookupSymbol: looking up %s
\n
"
,
lbl
));
initLinker
()
;
ASSERT
(
symhash
!=
NULL
);
val
=
lookupStrHashTable
(
symhash
,
lbl
);
if
(
val
==
NULL
)
{
if
(
!
ghciLookupSymbolTable
(
symhash
,
lbl
,
&
val
)
)
{
IF_DEBUG
(
linker
,
debugBelch
(
"lookupSymbol: symbol not found
\n
"
));
# if defined(OBJFORMAT_ELF)
return
internal_dlsym
(
dl_prog_handle
,
lbl
);
...
...
@@ -1986,7 +2033,7 @@ void ghci_enquire ( char* addr )
if
(
sym
==
NULL
)
continue
;
a
=
NULL
;
if
(
a
==
NULL
)
{
a
=
lookupStrHashTable
(
symhash
,
sym
);
ghciLookupSymbolTable
(
symhash
,
sym
,
(
void
**
)
&
a
);
}
if
(
a
==
NULL
)
{
// debugBelch("ghci_enquire: can't find %s\n", sym);
...
...
@@ -2854,7 +2901,7 @@ unloadObj( pathchar *path )
int
i
;
for
(
i
=
0
;
i
<
oc
->
n_symbols
;
i
++
)
{
if
(
oc
->
symbols
[
i
]
!=
NULL
)
{
removeStrHashTable
(
symhash
,
oc
->
symbols
[
i
],
NULL
);
ghciRemoveSymbolTable
(
symhash
,
oc
->
symbols
[
i
],
oc
);
}
}
}
...
...
@@ -3978,7 +4025,8 @@ ocGetNames_PEi386 ( ObjectCode* oc )
ASSERT
(
i
>=
0
&&
i
<
oc
->
n_symbols
);
/* cstring_from_COFF_symbol_name always succeeds. */
oc
->
symbols
[
i
]
=
(
char
*
)
sname
;
ghciInsertStrHashTable
(
oc
->
fileName
,
symhash
,
(
char
*
)
sname
,
addr
);
ghciInsertSymbolTable
(
oc
->
fileName
,
symhash
,
(
char
*
)
sname
,
addr
,
HS_BOOL_FALSE
,
oc
);
}
else
{
# if 0
debugBelch
(
...
...
@@ -4820,6 +4868,7 @@ ocGetNames_ELF ( ObjectCode* oc )
for
(
j
=
0
;
j
<
nent
;
j
++
)
{
char
isLocal
=
FALSE
;
/* avoids uninit-var warning */
HsBool
isWeak
=
HS_BOOL_FALSE
;
char
*
ad
=
NULL
;
char
*
nm
=
strtab
+
stab
[
j
].
st_name
;
int
secno
=
stab
[
j
].
st_shndx
;
...
...
@@ -4840,6 +4889,7 @@ ocGetNames_ELF ( ObjectCode* oc )
else
if
(
(
ELF_ST_BIND
(
stab
[
j
].
st_info
)
==
STB_GLOBAL
||
ELF_ST_BIND
(
stab
[
j
].
st_info
)
==
STB_LOCAL
||
ELF_ST_BIND
(
stab
[
j
].
st_info
)
==
STB_WEAK
)
/* and not an undefined symbol */
&&
stab
[
j
].
st_shndx
!=
SHN_UNDEF
...
...
@@ -4863,7 +4913,8 @@ ocGetNames_ELF ( ObjectCode* oc )
ad
=
ehdrC
+
shdr
[
secno
].
sh_offset
+
stab
[
j
].
st_value
;
if
(
ELF_ST_BIND
(
stab
[
j
].
st_info
)
==
STB_LOCAL
)
{
isLocal
=
TRUE
;
}
else
{
isWeak
=
FALSE
;
}
else
{
/* STB_GLOBAL or STB_WEAK */
#ifdef ELF_FUNCTION_DESC
/* dlsym() and the initialisation table both give us function
* descriptors, so to be consistent we store function descriptors
...
...
@@ -4874,6 +4925,7 @@ ocGetNames_ELF ( ObjectCode* oc )
IF_DEBUG
(
linker
,
debugBelch
(
"addOTabName(GLOB): %10p %s %s
\n
"
,
ad
,
oc
->
fileName
,
nm
));
isLocal
=
FALSE
;
isWeak
=
(
ELF_ST_BIND
(
stab
[
j
].
st_info
)
==
STB_WEAK
);
}
}
...
...
@@ -4886,7 +4938,7 @@ ocGetNames_ELF ( ObjectCode* oc )
if
(
isLocal
)
{
/* Ignore entirely. */
}
else
{
ghciInsertS
trHashTable
(
oc
->
fileName
,
symhash
,
nm
,
ad
);
ghciInsertS
ymbolTable
(
oc
->
fileName
,
symhash
,
nm
,
ad
,
isWeak
,
oc
);
}
}
else
{
/* Skip. */
...
...
@@ -6579,11 +6631,13 @@ ocGetNames_MachO(ObjectCode* oc)
else
{
IF_DEBUG
(
linker
,
debugBelch
(
"ocGetNames_MachO: inserting %s
\n
"
,
nm
));
ghciInsertS
trHash
Table
(
oc
->
fileName
,
symhash
,
nm
,
ghciInsertS
ymbol
Table
(
oc
->
fileName
,
symhash
,
nm
,
image
+
sections
[
nlist
[
i
].
n_sect
-
1
].
offset
-
sections
[
nlist
[
i
].
n_sect
-
1
].
addr
+
nlist
[
i
].
n_value
);
+
nlist
[
i
].
n_value
,
HS_BOOL_FALSE
,
oc
);
oc
->
symbols
[
curSymbol
++
]
=
nm
;
}
}
...
...
@@ -6614,8 +6668,8 @@ ocGetNames_MachO(ObjectCode* oc)
nlist
[
i
].
n_value
=
commonCounter
;
IF_DEBUG
(
linker
,
debugBelch
(
"ocGetNames_MachO: inserting common symbol: %s
\n
"
,
nm
));
ghciInsertS
trHash
Table
(
oc
->
fileName
,
symhash
,
nm
,
(
void
*
)
commonCounter
);
ghciInsertS
ymbol
Table
(
oc
->
fileName
,
symhash
,
nm
,
(
void
*
)
commonCounter
,
HS_BOOL_FALSE
,
oc
);
oc
->
symbols
[
curSymbol
++
]
=
nm
;
commonCounter
+=
sz
;
...
...
@@ -6785,7 +6839,7 @@ machoInitSymbolsWithoutUnderscore(void)
#undef SymI_NeedsProto
#define SymI_NeedsProto(x) \
ghciInsertS
trHashTable("(GHCi built-in symbols)", symhash, #x, *p++
);
ghciInsertS
ymbolTable("(GHCi built-in symbols)", symhash, #x, *p++, HS_BOOL_FALSE, NULL
);
RTS_MACHO_NOUNDERLINE_SYMBOLS
...
...
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