|
Message-ID: <20130116164943.GD20323@brightrain.aerifal.cx> Date: Wed, 16 Jan 2013 11:49:43 -0500 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Re: dladdr() On Wed, Jan 16, 2013 at 03:24:24PM +0100, musl wrote: > > i ran hello in gdb and it seems > > sym->st_shndx==0 > > for the "puts" symbol, i dont know the semantics of > > st_shndx, but the following patch makes hello.c work: > > > > diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c > > index 935367e..ba0bd8f 100644 > > --- a/src/ldso/dynlink.c > > +++ b/src/ldso/dynlink.c > > @@ -1178,7 +1178,7 @@ int __dladdr(void *addr, Dl_info *info) > > } > > > > for (; nsym; nsym--, sym++) { > > - if (sym->st_shndx && sym->st_value > > + if (/*sym->st_shndx &&*/ sym->st_value > > && (1<<(sym->st_info&0xf) & OK_TYPES) > > && (1<<(sym->st_info>>4) & OK_BINDS)) { > > void *symaddr = p->base + sym->st_value; > > > > You're right, sym->st_shndx only tells if the symbol is external > (resolved during relocation process) or internal (defined in the > current shared object). st_shndx==0 is used for PLT entries. Oddly, I get (for hello.c): Symbol table '.dynsym' contains 9 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FUNC GLOBAL DEFAULT UND printf 2: 080482c0 0 FUNC GLOBAL DEFAULT UND puts 3: 00000000 0 FUNC GLOBAL DEFAULT UND dladdr So the symbol value (the address of the PLT entry) seems to be filled in only for symbols which are also used to take the address of a function. Other symbols in the PLT (which are used only for resolving the PLT entry at load time) lack addresses. I suspect this could prevent correct dladdr behavior in some cases, but I can't think of a serious usage case that would be broken right off. Anyway, I'm applying nsz's patch (without the commented code :) which should make the situation much better (hopefully as good as glibc's). > BTW dli_fbase is still wrong. It should be > > info->dli_fbase = p->map; > > and not > > info->dli_fbase = p->base; I notice it disagrees with glibc, but I'm not sure I agree it's wrong. The man page states that dli_fbase is the "Address at which shared object is loaded", which is never clearly defined. On the other hand, dl_iterate_phdr's dlpi_addr is specified to contain the "Base address of object", which is defined below as "the difference between the virtual memory address of the shared object and the offset of that object in the file from which it was loaded". To me, this seems like the main/only "load address" that would be of interest to a program. However, there's also an interest in matching historical practice, especially since dladdr is not a standard function and the existing implementations could be seen as the "real" specification. Do you know what other systems like BSD do? Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.