mirror of git://sourceware.org/git/glibc.git
Update.
2001-11-12 Ulrich Drepper <drepper@redhat.com> * elf/dl-reloc.c (_dl_relocate_object): Avoid iterating over program header twice. Construct list with the needed information.
This commit is contained in:
parent
e5b27fe5d1
commit
f133c09767
|
@ -1,3 +1,8 @@
|
||||||
|
2001-11-12 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-reloc.c (_dl_relocate_object): Avoid iterating over
|
||||||
|
program header twice. Construct list with the needed information.
|
||||||
|
|
||||||
2001-11-10 Ulrich Drepper <drepper@redhat.com>
|
2001-11-10 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* po/ca.po: Update from translation team.
|
* po/ca.po: Update from translation team.
|
||||||
|
|
|
@ -35,6 +35,16 @@ void
|
||||||
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
int lazy, int consider_profiling)
|
int lazy, int consider_profiling)
|
||||||
{
|
{
|
||||||
|
struct textrels
|
||||||
|
{
|
||||||
|
caddr_t start;
|
||||||
|
size_t len;
|
||||||
|
int prot;
|
||||||
|
struct textrels *next;
|
||||||
|
} *textrels = NULL;
|
||||||
|
/* Initialize it to make the compiler happy. */
|
||||||
|
const char *errstring = NULL;
|
||||||
|
|
||||||
if (l->l_relocated)
|
if (l->l_relocated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -48,6 +58,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
_dl_printf ("\nrelocation processing: %s%s\n",
|
_dl_printf ("\nrelocation processing: %s%s\n",
|
||||||
l->l_name[0] ? l->l_name : _dl_argv[0], lazy ? " (lazy)" : "");
|
l->l_name[0] ? l->l_name : _dl_argv[0], lazy ? " (lazy)" : "");
|
||||||
|
|
||||||
|
/* DT_TEXTREL is now in level 2 and might phase out at some time.
|
||||||
|
But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make
|
||||||
|
testing easier and therefore it will be available at all time. */
|
||||||
if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0))
|
if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0))
|
||||||
{
|
{
|
||||||
/* Bletch. We must make read-only segments writable
|
/* Bletch. We must make read-only segments writable
|
||||||
|
@ -56,15 +69,36 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
|
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
|
||||||
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
|
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
|
||||||
{
|
{
|
||||||
caddr_t mapstart = ((caddr_t) l->l_addr +
|
struct textrels *newp;
|
||||||
(ph->p_vaddr & ~(_dl_pagesize - 1)));
|
|
||||||
caddr_t mapend = ((caddr_t) l->l_addr +
|
newp = (struct textrels *) alloca (sizeof (*newp));
|
||||||
((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
|
newp->len = (((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
|
||||||
& ~(_dl_pagesize - 1)));
|
& ~(_dl_pagesize - 1))
|
||||||
if (__builtin_expect (__mprotect (mapstart, mapend - mapstart,
|
- (ph->p_vaddr & ~(_dl_pagesize - 1)));
|
||||||
PROT_READ|PROT_WRITE), 0) < 0)
|
newp->start = ((ph->p_vaddr & ~(_dl_pagesize - 1))
|
||||||
_dl_signal_error (errno, l->l_name, NULL, N_("\
|
+ (caddr_t) l->l_addr);
|
||||||
cannot make segment writable for relocation"));
|
|
||||||
|
if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0)
|
||||||
|
{
|
||||||
|
errstring = N_("cannot make segment writable for relocation");
|
||||||
|
call_error:
|
||||||
|
_dl_signal_error (errno, l->l_name, NULL, errstring);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
|
||||||
|
newp->prot = (PF_TO_PROT
|
||||||
|
>> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
|
||||||
|
#else
|
||||||
|
newp->prot = 0;
|
||||||
|
if (ph->p_flags & PF_R)
|
||||||
|
newp->prot |= PROT_READ;
|
||||||
|
if (ph->p_flags & PF_W)
|
||||||
|
newp->prot |= PROT_WRITE;
|
||||||
|
if (ph->p_flags & PF_X)
|
||||||
|
newp->prot |= PROT_EXEC;
|
||||||
|
#endif
|
||||||
|
newp->next = textrels;
|
||||||
|
textrels = newp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +156,6 @@ cannot make segment writable for relocation"));
|
||||||
|
|
||||||
if (__builtin_expect (consider_profiling, 0))
|
if (__builtin_expect (consider_profiling, 0))
|
||||||
{
|
{
|
||||||
const char *errstring = NULL;
|
|
||||||
|
|
||||||
/* Allocate the array which will contain the already found
|
/* Allocate the array which will contain the already found
|
||||||
relocations. If the shared object lacks a PLT (for example
|
relocations. If the shared object lacks a PLT (for example
|
||||||
if it only contains lead function) the l_info[DT_PLTRELSZ]
|
if it only contains lead function) the l_info[DT_PLTRELSZ]
|
||||||
|
@ -152,45 +184,16 @@ cannot make segment writable for relocation"));
|
||||||
/* Mark the object so we know this work has been done. */
|
/* Mark the object so we know this work has been done. */
|
||||||
l->l_relocated = 1;
|
l->l_relocated = 1;
|
||||||
|
|
||||||
/* DT_TEXTREL is now in level 2 and might phase out at some time.
|
/* Undo the segment protection changes. */
|
||||||
But we rewrite the DT_FLAGS entry to make testing easier and
|
while (__builtin_expect (textrels != NULL, 0))
|
||||||
therefore it will be available at all time. */
|
|
||||||
if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0))
|
|
||||||
{
|
{
|
||||||
/* Undo the protection change we made before relocating. */
|
if (__mprotect (textrels->start, textrels->len, textrels->prot) < 0)
|
||||||
const ElfW(Phdr) *ph;
|
{
|
||||||
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
|
errstring = N_("cannot restore segment prot after reloc");
|
||||||
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
|
goto call_error;
|
||||||
{
|
}
|
||||||
caddr_t mapstart = ((caddr_t) l->l_addr +
|
|
||||||
(ph->p_vaddr & ~(_dl_pagesize - 1)));
|
|
||||||
caddr_t mapend = ((caddr_t) l->l_addr +
|
|
||||||
((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
|
|
||||||
& ~(_dl_pagesize - 1)));
|
|
||||||
int prot;
|
|
||||||
|
|
||||||
#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
|
textrels = textrels->next;
|
||||||
prot = (PF_TO_PROT
|
|
||||||
>> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
|
|
||||||
#else
|
|
||||||
prot = 0;
|
|
||||||
if (ph->p_flags & PF_R)
|
|
||||||
prot |= PROT_READ;
|
|
||||||
if (ph->p_flags & PF_W)
|
|
||||||
prot |= PROT_WRITE;
|
|
||||||
if (ph->p_flags & PF_X)
|
|
||||||
prot |= PROT_EXEC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (__builtin_expect (__mprotect (mapstart, mapend - mapstart,
|
|
||||||
prot), 0) < 0)
|
|
||||||
_dl_signal_error (errno, l->l_name, NULL,
|
|
||||||
N_("can't restore segment prot after reloc"));
|
|
||||||
|
|
||||||
#ifdef CLEAR_CACHE
|
|
||||||
CLEAR_CACHE (mapstart, mapend);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue