- To: Kenneth Block <block at zk3 dot dec dot com>
- Subject: Patch for RELATIVE relocation for an non-loaded section
- From: Ken Block USG <block at zk3 dot dec dot com>
- Date: Fri, 10 Mar 2000 13:32:31 -0500
Problem description:
Here is the new bug that's been fixed: The DWARF-2 sections .debug_info
and .debug_line are never actually loaded into virtual memory. They do
contain addresses and offsets of other things in the object file and
therefore the compiler emits the appropriate REFLONG and REFQUAD
relocations. If the resulting object file is linked into an executable
image, the linker fully resolves the REFLONG and REFQUAD relocations and
all is well. However,if the object file is linked into a shared object,
the linker cannot fully resolve the relocations. It determines the
hared-object-relative offsets of the items in question, then it puts
RELATIVE relocations in the shared object so that the run-time loader
can change the relative offsets into virtual addresses once the shared
object's base virtual address is known. But this run-time operation
cannot, and should not, be done for sections that are never actually
loaded into virtual memory. The run-time loader gets a segmentation
fault trying to process a RELATIVE relocation for an non-loaded
section. The fix is for the linker not to emit RELATIVE relocations for
REFLONGs and REFQUADs in sections that aren't loaded.
--PSW
Test case:
catch.zko.dec.com> ccc -c -g foo.c
catch.zko.dec.com> ccc foo.o -shared -o libfoo.so
catch.zko.dec.com> ccc -o main main.c ./libfoo.so
catch.zko.dec.com> ./main
foo
Relink using the old RH5.2 ld.
catch.zko.dec.com> $DECC_STABLE/ld -o libfoo.so -O1 -m elf64alpha -G 8
-shared -
L/usr/lib/compaq/ccc-6.2.9.002-2/alpha-linux/lib -L/usr/local/lib
-L/usr/alpha-r
edhat-linux/lib -L/usr/lib/gcc-lib/alpha-redhat-linux/egcs-2.90.29
/usr/lib/comp
aq/ccc-6.2.9.002-2/alpha-linux/bin/crti.o
/usr/lib/compaq/ccc-6.2.9.002-2/alpha-
linux/bin/crtbegin.o foo.o -lgcc -lc -lgcc -lots
/usr/lib/compaq/ccc-6.2.9.002-2
/alpha-linux/bin/crtend.o
/usr/lib/compaq/ccc-6.2.9.002-2/alpha-linux/bin/crtn.o
catch.zko.dec.com> ccc -o main main.c ./libfoo.so
catch.zko.dec.com> ./main
Segmentation fault (core dumped)
catch.zko.dec.com> cat foo.c
#include <stdio.h>
void foo(void)
{
printf("foo\n");
}
catch.zko.dec.com> cat main.c
int main(int argc, char *argv[])
{
foo();
}
*** ../../binutils-2.9.1.0.15/bfd/elf64-alpha.c Thu Oct 1 11:33:50 1998
--- elf64-alpha.c Tue Sep 28 18:26:11 1999
***************
*** 1922,1934 ****
h->reloc_entries = rent;
}
else
rent->count++;
}
! else if (info->shared)
{
! /* If this is a shared library, we need a RELATIVE reloc.
*/
sreloc->_raw_size += sizeof (Elf64_External_Rela);
}
break;
}
}
--- 1922,1935 ----
h->reloc_entries = rent;
}
else
rent->count++;
}
! else if (info->shared && (sec->flags & SEC_ALLOC))
{
! /* If this is a shared library, and the section is to be
loaded
! into memory, we need a RELATIVE reloc. */
sreloc->_raw_size += sizeof (Elf64_External_Rela);
}
break;
}
}
***************
*** 3002,3012 ****
BFD_ASSERT(h->root.dynindx != -1);
outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type);
outrel.r_addend = addend;
addend = 0, relocation = 0;
}
! else if (info->shared)
{
outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
outrel.r_addend = 0;
}
else
--- 3003,3015 ----
BFD_ASSERT(h->root.dynindx != -1);
outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type);
outrel.r_addend = addend;
addend = 0, relocation = 0;
}
! /* A RELATIVE relocation makes no sense if this section
isn't
! to be loaded into memory */
! else if (info->shared && (input_section->flags & SEC_ALLOC))
{
outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
outrel.r_addend = 0;
}
else
Ke
begin:vcard
n:Block;Kenneth
x-mozilla-html:FALSE
org:CTG C/C++ Compiler
version:2.1
email;internet:block@zk3.dec.com
adr;quoted-printable:;;110 Spit Brook Road=0D=0AM/S ZKO3-2/W02;Nashua;NH;03062;USA
x-mozilla-cpt:;0
tel;work:603-884-2819
fn:Kenneth Block
end:vcard