Problem of execution order of entries in .fini_array
Jing Yu
jingyu@google.com
Fri Apr 17 14:32:00 GMT 2009
I find under newlib/libc/sys/linux/dl directory, the dl-*.* files are
copied from glibc/libc/elf/ directory. These dl-* files have been
updated in glibc, but not in newlib.
I only search for "FINI", and find the following two places that may
need to change.
newlib/libc/sys/linux/dl/dl-close.c:
void internal_function _dl_close (void *_map)
{
...
if (imap->l_info[DT_FINI_ARRAY] != NULL)
{
ElfW(Addr) *array =
(ElfW(Addr) *) (imap->l_addr
+ imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
/ sizeof (ElfW(Addr)));
unsigned int cnt;
for (cnt = 0; cnt < sz; ++cnt)
<----------- changed in new glibc
((fini_t) (imap->l_addr + array[cnt])) ();
<------------changed
}
...
In glibc/libc/elf/dl-close.c, the arrowed two lines have been changed into:
while (sz-- > 0)
((fini_t) array[sz]) ();
newlib/libc/sys/linux/dl/dl-fini.c:
void internal_function _dl_fini (void)
{
...
if (l->l_info[DT_FINI_ARRAY] != NULL)
{
ElfW(Addr) *array =
(ElfW(Addr) *) (l->l_addr
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
unsigned int sz =
(l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val <---Changed
/ sizeof (ElfW(Addr)));
unsigned int cnt; <----- changed
for (cnt = 0; cnt < sz; ++cnt) <-----------
Changed in new glibc
((fini_t) (l->l_addr + array[cnt])) (); <----------- Changed
}
/* Next try the old-style destructor. */
if (l->l_info[DT_FINI] != NULL)
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr +
l->l_info[DT_FINI]->d_un.d_ptr)) ();
}
}
The arrowed four lines have been updated in glibc/libc/elf/dl-fini.c:
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
/ sizeof (ElfW(Addr)));
while (i-- > 0)
((fini_t) array[i]) ();
Thanks,
Jing
On Thu, Apr 16, 2009 at 12:20 PM, Jeff Johnston <jjohnstn@redhat.com> wrote:
> Hans-Peter Nilsson wrote:
>>>
>>> Received-SPF: none (bart: domain of
>>> newlib-return-7494-hp=axis.com@sourceware.org does not designate permitted
>>> sender hosts) client ip=209.132.176.174;
>>> envelope-from=newlib-return-7494-hp=axis.com@sourceware.org;
>>> helo=sourceware.org;
>>> X-SWARE-Spam-Status: No, hits=-0.4 required=5.0
>>> tests=AWL,BAYES_00,SARE_MSGID_LONG40,SPF_PASS
>>> X-Spam-Check-By: sourceware.org
>>> MIME-Version: 1.0
>>> Date: Wed, 15 Apr 2009 16:08:17 -0700
>>> From: Jing Yu <jingyu@google.com>
>>>
>>
>> (Long analysis cut short)
>>
>>>
>>> Should we change the access order or fini_array?
>>>
>>
>> I'd suggest correcting the access order, as opposed to hacking
>> the linker. See for example glibc.
>>
>> (Note that there are *three* files in newlib doing the access in
>> the wrong order. And I'm not counting the misguided
>> newlib/libc/sys/arm/crt0.S in which fini_array is treated like a
>> synonym for _fini!)
>>
>> brgds, H-P
>>
>
> Agreed. I have checked in a patch for misc/init.c. Where are the other 2
> accesses?
>
> -- Jeff J.
>
More information about the Newlib
mailing list