summaryrefslogtreecommitdiffstats
path: root/src/i386_ld.c
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2006-07-05 07:34:27 +0000
committerUlrich Drepper <[email protected]>2006-07-05 07:34:27 +0000
commit4ba68f475d305b11e55c83994bad4824dad156d3 (patch)
tree80193be4e20320e129fcef4859685132c23e6b1a /src/i386_ld.c
parentd5a7519085f35bf48c9b33b8698835b24caa2da1 (diff)
Linker work.
GNU hash support. 64-bit SysV hash support.
Diffstat (limited to 'src/i386_ld.c')
-rw-r--r--src/i386_ld.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/i386_ld.c b/src/i386_ld.c
index a0c77dbe..33403eaf 100644
--- a/src/i386_ld.c
+++ b/src/i386_ld.c
@@ -527,13 +527,15 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
/* Symbols in COMDAT group sections which are discarded do
not have to be relocated. */
- if (unlikely (scninfo->fileinfo->symref[r_sym] == NULL))
+ if (r_sym >= scninfo->fileinfo->nlocalsymbols
+ && unlikely (scninfo->fileinfo->symref[r_sym] == NULL))
continue;
switch (XELF_R_TYPE (rel->r_info))
{
case R_386_GOT32:
- if (! scninfo->fileinfo->symref[r_sym]->defined)
+ if (! scninfo->fileinfo->symref[r_sym]->defined
+ || scninfo->fileinfo->symref[r_sym]->in_dso)
relsize += sizeof (Elf32_Rel);
/* This relocation is not emitted in the output file but
@@ -556,6 +558,8 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
if (statep->file_type == dso_file_type)
{
relsize += sizeof (Elf32_Rel);
+ // XXX Do we have to check whether the target
+ // XXX section is read-only first?
statep->dt_flags |= DF_TEXTREL;
}
else
@@ -575,10 +579,9 @@ elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
}
}
else if (statep->file_type == dso_file_type
- && r_sym >= SCNINFO_SHDR (scninfo->fileinfo->scninfo[shdr->sh_link].shdr).sh_info
- && scninfo->fileinfo->symref[r_sym]->outdynsymidx != 0
&& XELF_R_TYPE (rel->r_info) == R_386_32)
relsize += sizeof (Elf32_Rel);
+
break;
case R_386_PLT32:
@@ -702,8 +705,7 @@ elf_i386_create_relocations (struct ld_state *statep,
/* Cache the access to the symbol table data. */
Elf_Data *symdata = elf_getdata (scninfo[rshdr->sh_link].scn, NULL);
- int cnt;
- for (cnt = 0; cnt < nrels; ++cnt)
+ for (int cnt = 0; cnt < nrels; ++cnt)
{
XElf_Rel_vardef (rel);
XElf_Rel *rel2;
@@ -812,8 +814,7 @@ elf_i386_create_relocations (struct ld_state *statep,
}
}
else if (statep->file_type == dso_file_type
- && idx >= SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_info
- && symref[idx]->outdynsymidx != 0)
+ && XELF_R_TYPE (rel->r_info) == R_386_32)
{
#if NATIVE_ELF != 0
xelf_getrel_ptr (reldyndata, nreldyn, rel2);
@@ -821,8 +822,15 @@ elf_i386_create_relocations (struct ld_state *statep,
rel2 = &rel_mem;
#endif
rel2->r_offset = value;
- rel2->r_info
- = XELF_R_INFO (symref[idx]->outdynsymidx, R_386_32);
+
+ /* For symbols we do not export we generate a relative
+ relocation. */
+ if (idx < SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_info
+ || symref[idx]->outdynsymidx == 0)
+ rel2->r_info = XELF_R_INFO (0, R_386_RELATIVE);
+ else
+ rel2->r_info
+ = XELF_R_INFO (symref[idx]->outdynsymidx, R_386_32);
(void) xelf_update_rel (reldyndata, nreldyn, rel2);
++nreldyn;