[commit: ghc] master: fix RTS Linker on platforms without SHN_XINDEX support (9bea234)
git at git.haskell.org
git at git.haskell.org
Wed Nov 11 21:22:10 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/9bea234dbe3b36957acc42f74f0d54ddc05ad139/ghc
>---------------------------------------------------------------
commit 9bea234dbe3b36957acc42f74f0d54ddc05ad139
Author: Karel Gardas <karel.gardas at centrum.cz>
Date: Wed Nov 11 22:21:50 2015 +0100
fix RTS Linker on platforms without SHN_XINDEX support
Summary:
This patch fixes RTS Linker compilation issues on platforms
where SHN_XINDEX is not defined. Tested on OpenBSD. When SHN_XINDEX
is not defined, the code reverts to the old behavior, that means
behavior of the Linker before D1357 which added SHN_XINDEX based
functionality.
Reviewers: bgamari, austin, erikd
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1446
>---------------------------------------------------------------
9bea234dbe3b36957acc42f74f0d54ddc05ad139
rts/Linker.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/rts/Linker.c b/rts/Linker.c
index 35227c8..9cab5f2 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -4350,9 +4350,16 @@ static Elf_Word elf_shstrndx(Elf_Ehdr* ehdr)
{
Elf_Shdr* shdr = (Elf_Shdr*) ((char*)ehdr + ehdr->e_shoff);
Elf_Half shstrndx = ehdr->e_shstrndx;
+#if defined(SHN_XINDEX)
return shstrndx != SHN_XINDEX ? shstrndx : shdr[0].sh_link;
+#else
+ // some OSes do not support SHN_XINDEX yet, let's revert to
+ // old way
+ return shstrndx;
+#endif
}
+#if defined(SHN_XINDEX)
static Elf_Word*
get_shndx_table(Elf_Ehdr* ehdr)
{
@@ -4368,7 +4375,7 @@ get_shndx_table(Elf_Ehdr* ehdr)
}
return NULL;
}
-
+#endif
/*
* Generic ELF functions
@@ -4542,8 +4549,9 @@ ocVerifyImage_ELF ( ObjectCode* oc )
if (nstrtab == 0) {
IF_DEBUG(linker,debugBelch(" no normal string tables (potentially, but not necessarily a problem)\n"));
}
-
+#if defined(SHN_XINDEX)
Elf_Word* shndxTable = get_shndx_table(ehdr);
+#endif
nsymtabs = 0;
IF_DEBUG(linker,debugBelch( "Symbol tables\n" ));
for (i = 0; i < shnum; i++) {
@@ -4562,11 +4570,13 @@ ocVerifyImage_ELF ( ObjectCode* oc )
}
for (j = 0; j < nent; j++) {
Elf_Word secno = stab[j].st_shndx;
+#if defined(SHN_XINDEX)
/* See Note [Many ELF Sections] */
if (secno == SHN_XINDEX) {
ASSERT(shndxTable);
secno = shndxTable[j];
}
+#endif
IF_DEBUG(linker,debugBelch(" %2d ", j ));
IF_DEBUG(linker,debugBelch(" sec=%-5d size=%-3d val=%5p ",
(int)secno,
@@ -4681,7 +4691,9 @@ ocGetNames_ELF ( ObjectCode* oc )
char* strtab;
Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
Section * sections;
+#if defined(SHN_XINDEX)
Elf_Word* shndxTable = get_shndx_table(ehdr);
+#endif
const Elf_Word shnum = elf_shnum(ehdr);
ASSERT(symhash != NULL);
@@ -4784,13 +4796,13 @@ ocGetNames_ELF ( ObjectCode* oc )
* shndx variable, not the section number in secno. Sections with the
* real number in the SHN_LORESERVE..HIRESERVE range will have shndx
* SHN_XINDEX and a secno with one of the reserved values. */
+ secno = shndx;
+#if defined(SHN_XINDEX)
if (shndx == SHN_XINDEX) {
ASSERT(shndxTable);
secno = shndxTable[j];
- } else {
- secno = shndx;
}
-
+#endif
/* Figure out if we want to add it; if so, set ad to its
address. Otherwise leave ad == NULL. */
@@ -4812,7 +4824,11 @@ ocGetNames_ELF ( ObjectCode* oc )
/* and not an undefined symbol */
&& shndx != SHN_UNDEF
/* and not in a "special section" */
- && (shndx < SHN_LORESERVE || shndx == SHN_XINDEX)
+ && (shndx < SHN_LORESERVE
+#if defined(SHN_XINDEX)
+ || shndx == SHN_XINDEX
+#endif
+ )
&&
/* and it's a not a section or string table or anything silly */
( ELF_ST_TYPE(stab[j].st_info)==STT_FUNC ||
@@ -4909,7 +4925,9 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
int target_shndx = shdr[shnum].sh_info;
int symtab_shndx = shdr[shnum].sh_link;
int strtab_shndx = shdr[symtab_shndx].sh_link;
+#if defined(SHN_XINDEX)
Elf_Word* shndx_table = get_shndx_table((Elf_Ehdr*)ehdrC);
+#endif
stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
strtab= (char*) (ehdrC + shdr[ strtab_shndx ].sh_offset);
@@ -4955,10 +4973,12 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
/* See Note [Many ELF Sections] */
Elf_Word secno = sym.st_shndx;
+#if defined(SHN_XINDEX)
if (secno == SHN_XINDEX) {
ASSERT(shndx_table);
secno = shndx_table[ELF_R_SYM(info)];
}
+#endif
S = (Elf_Addr)oc->sections[ secno ].start +
stab[ELF_R_SYM(info)].st_value;
} else {
@@ -5219,7 +5239,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
int symtab_shndx = shdr[shnum].sh_link;
int strtab_shndx = shdr[symtab_shndx].sh_link;
int target_shndx = shdr[shnum].sh_info;
+#if defined(SHN_XINDEX)
Elf_Word* shndx_table = get_shndx_table((Elf_Ehdr*)ehdrC);
+#endif
#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
/* This #ifdef only serves to avoid unused-var warnings. */
Elf_Addr targ = (Elf_Addr) oc->sections[target_shndx].start;
@@ -5272,9 +5294,11 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
/* See Note [Many ELF Sections] */
Elf_Word secno = sym.st_shndx;
+#if defined(SHN_XINDEX)
if (secno == SHN_XINDEX) {
secno = shndx_table[ELF_R_SYM(info)];
}
+#endif
S = (Elf_Addr)oc->sections[secno].start
+ stab[ELF_R_SYM(info)].st_value;
#ifdef ELF_FUNCTION_DESC
More information about the ghc-commits
mailing list