[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gcl-devel] Re: ld from 2.14.90.0.8 puts no value into undefined symbols
From: |
Camm Maguire |
Subject: |
[Gcl-devel] Re: ld from 2.14.90.0.8 puts no value into undefined symbols |
Date: |
01 Apr 2004 15:39:44 -0500 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 |
Greetings, and thanks for your helpful feedback here!
You've implemented a fix quite similar to what we've adopted in GCL.
It works for now, but we have been warned, and have since
independently verified, that the plt table is not output by the linker
on all architectures (e.g. ia64). Fortunately, these happen to be the
architectures where we can't yet natively relocate objects anyway.
Due to this fact, and the implicit conclusion that the .plt table may
go away in some future incarnation of ld, we've implemented an
additional attempt to capture a minimal set of needed addresses by
making explicit reference to them as function pointers in a C stub
routine. This effectively disables the new optimization zeroing out
the address in recent binutils. I'm assuming it will continue to do
so.
This likely will not work for you, as you won't be able to specify
function pointers ahead of time when compiling, but I thought I'd
mention it.
Take care,
Bernhard Kaindl <address@hidden> writes:
> Hi,
> ltrace was also hit by the binutils change in 2.14.90.0.8
> which was discussed under this subject here and on the bintutils
> list:
>
> http://mail.gnu.org/archive/html/gcl-devel/2004-02/msg00258.html
> http://sources.redhat.com/ml/binutils/2004-03/msg00008.html
>
> I had to implement a fix for ltrace and I had no chance to do
> some workaround as it was apparently done here as far as I
> could understand.
>
> ltrace was also affected (apparently like gcl) by no longer having
> the address of the PLT table entries of the non-local function in
> available in the symbol table.
>
> ltrace relies on the PLT table entry address to be able to set
> break points for library call traceing(it's purpose)
>
> I fixed ltrace to calculate missing PLT table entry addresses
> so that it works again (I've seen it on i386, but it should
> still work on all architectures, I assume):
>
> The fix is:
>
> for(i = 0; i < ehdr->e_shnum; i++) {
>
> + char * secname = maddr
> + + shdr[ehdr->e_shstrndx].sh_offset+shdr[i].sh_name;
> +
> + if (!strncmp(secname, ".plt", 5)) {
> + lte->plt_start = (void *)shdr[i].sh_addr;
> + lte->plt_entsize = shdr[i].sh_entsize;
> + }
>
> Here(where ltrace loops over all sections to find the section of
> the symbol table), I'm adding a check which also checks for the
> section called ".plt", because the address where it's mapped into
> memory is the PLT table entry of the first non-local function.
>
> + lte.plt_addr = lte.plt_start;
> for(i = 0; i < lte.symtab_len / sizeof(Elf_Sym); i++) {
> Elf_Sym *symtab = lte.symtab;
> char *strtab = lte.strtab;
>
> - if (!symtab[i].st_shndx && symtab[i].st_value) {
> + if (!symtab[i].st_shndx
> + && ELF32_ST_BIND(symtab[i].st_info) != STB_LOCAL
> + && ELF32_ST_TYPE(symtab[i].st_info) == STT_FUNC) {
> +
> + /* Address of next entry in plt table */
> + lte.plt_addr += lte.plt_entsize * sizeof(void *);
>
> Then, when looping over the symbol table, I check if the entry is a
> non-local function, and only if it is, I'm incrementing the pointer
> into the PLT table which I just got before.
>
> + if (lte->symtab[i].st_value)
> + library_symbols->enter_addr = (void *)lte->symtab[i].st_value;
> + else
> + library_symbols->enter_addr = lte->plt_addr;
>
> Then, if the toolchain of the does not provide a address value in the
> symbol table, I use the calculated PLT entry address.
>
> The structures and macros used here are defined on Linux in /usr/include/elf.h
>
> The code above worked as far as I could see.
>
> Bernhard
> ==============================================================
>
> PS:
>
> I'm sure libbfd can provide the same ELF section information.
>
> (ltrace just mmaps the binary and addresses it directly using elf.h)
>
> Here you can see the PLT start address as it's displayed by objdump
> from binutils which used libbfd:
>
> objdump -h /usr/bin/printf | fgrep ' .plt'
> 10 .plt 000002f0 08048aa8 08048aa8 00000aa8 2**2
> ----------------------------^^^^^^^^
>
> And objdump -T displays the symbol table:
>
> objdump -T /usr/bin/printf
>
> /usr/bin/printf: file format elf32-i386
>
> DYNAMIC SYMBOL TABLE:
> 00000000 DF *UND* 0000008c GLIBC_2.0 nl_langinfo
> ...
>
> Only increase the pointer into the PLT on such functions, not
> on locally defined smybols like these:
>
> 0804bc84 g DO .rodata 00000004 Base _IO_stdin_used
> 0804dcec g DO .bss 00000004 GLIBC_2.0 optind
>
>
>
--
Camm Maguire address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gcl-devel] Re: ld from 2.14.90.0.8 puts no value into undefined symbols,
Camm Maguire <=