gcl-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]