summaryrefslogtreecommitdiff
path: root/src/i386_ld.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-07-07 03:43:47 +0000
committerUlrich Drepper <drepper@redhat.com>2006-07-07 03:43:47 +0000
commit28ed895fdc303b2a793506bb1fcdd35d5fd14e70 (patch)
tree1385a2d5f0e844e26990b9da92b784ca73c73000 /src/i386_ld.c
parent1d3a64d70c8f2aec1fc3ae26d124823c1ef304a9 (diff)
downloadelfutils-28ed895fdc303b2a793506bb1fcdd35d5fd14e70.tar.gz
merge of 2d5572f10b65f0ac7fdf54361b4dae41ebbd51d0
and fda3a25581b7bfac581504e9e887e9b97f234f86
Diffstat (limited to 'src/i386_ld.c')
-rw-r--r--src/i386_ld.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/i386_ld.c b/src/i386_ld.c
index a0c77dbe..c79804cd 100644
--- a/src/i386_ld.c
+++ b/src/i386_ld.c
@@ -72,7 +72,7 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
Elf_Data *data;
/* Iterate over all the input sections. Appropriate data buffers in the
- output sections were already created. I get them iteratively, too. */
+ output sections were already created. */
runp = firstp;
data = NULL;
do
@@ -149,8 +149,8 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
assert (xndx < SHN_LORESERVE || xndx > SHN_HIRESERVE);
/* We fortunately don't have to do much. The relocations
- mostly get only updates of the offset. Only is a
- relocation referred to a section do we have to do
+ mostly get only updates of the offset. Only for a
+ relocation referring to a section do we have to do
something. In this case the reference to the sections
has no direct equivalent since the part the input section
contributes need not start at the same offset as in the
@@ -159,15 +159,13 @@ elf_i386_relocate_section (struct ld_state *statep __attribute__ ((unused)),
itself. */
if (XELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
- Elf32_Word toadd;
-
- /* We expect here on R_386_32 relocations. */
+ /* We expect here only R_386_32 relocations. */
assert (XELF_R_TYPE (rel->r_info) == R_386_32);
/* Avoid writing to the section memory if this is
effectively a no-op since it might save a
copy-on-write operation. */
- toadd = file->scninfo[xndx].offset;
+ Elf32_Word toadd = file->scninfo[xndx].offset;
if (toadd != 0)
add_4ubyte_unaligned (reltgtdata->d_buf + rel->r_offset,
toadd);
@@ -527,13 +525,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 +556,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 +577,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 +703,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 +812,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 +820,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;