mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 956398 - Support text relocations in the custom linker. r=nfroyd
This commit is contained in:
parent
3e1e04b07b
commit
b0ff197fa9
@ -64,6 +64,13 @@ void debug_phdr(const char *type, const Phdr *phdr)
|
||||
phdr->p_flags & PF_W ? 'w' : '-', phdr->p_flags & PF_X ? 'x' : '-');
|
||||
}
|
||||
|
||||
static int p_flags_to_mprot(Word flags)
|
||||
{
|
||||
return ((flags & PF_X) ? PROT_EXEC : 0) |
|
||||
((flags & PF_W) ? PROT_WRITE : 0) |
|
||||
((flags & PF_R) ? PROT_READ : 0);
|
||||
}
|
||||
|
||||
void
|
||||
__void_stub(void)
|
||||
{
|
||||
@ -225,6 +232,28 @@ CustomElf::Load(Mappable *mappable, const char *path, int flags)
|
||||
if (!elf->InitDyn(dyn))
|
||||
return nullptr;
|
||||
|
||||
if (elf->has_text_relocs) {
|
||||
for (std::vector<const Phdr *>::iterator it = pt_loads.begin();
|
||||
it < pt_loads.end(); ++it)
|
||||
mprotect(PageAlignedPtr(elf->GetPtr((*it)->p_vaddr)),
|
||||
PageAlignedEndPtr((*it)->p_memsz),
|
||||
p_flags_to_mprot((*it)->p_flags) | PROT_WRITE);
|
||||
}
|
||||
|
||||
if (!elf->Relocate() || !elf->RelocateJumps())
|
||||
return nullptr;
|
||||
|
||||
if (elf->has_text_relocs) {
|
||||
for (std::vector<const Phdr *>::iterator it = pt_loads.begin();
|
||||
it < pt_loads.end(); ++it)
|
||||
mprotect(PageAlignedPtr(elf->GetPtr((*it)->p_vaddr)),
|
||||
PageAlignedEndPtr((*it)->p_memsz),
|
||||
p_flags_to_mprot((*it)->p_flags));
|
||||
}
|
||||
|
||||
if (!elf->CallInit())
|
||||
return nullptr;
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
if (arm_exidx_phdr)
|
||||
elf->arm_exidx.InitSize(elf->GetPtr(arm_exidx_phdr->p_vaddr),
|
||||
@ -423,9 +452,7 @@ CustomElf::LoadSegment(const Phdr *pt_load) const
|
||||
return false;;
|
||||
}
|
||||
|
||||
int prot = ((pt_load->p_flags & PF_X) ? PROT_EXEC : 0) |
|
||||
((pt_load->p_flags & PF_W) ? PROT_WRITE : 0) |
|
||||
((pt_load->p_flags & PF_R) ? PROT_READ : 0);
|
||||
int prot = p_flags_to_mprot(pt_load->p_flags);
|
||||
|
||||
/* Mmap at page boundary */
|
||||
Addr align = PageSize();
|
||||
@ -549,8 +576,8 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
|
||||
}
|
||||
break;
|
||||
case DT_TEXTREL:
|
||||
LOG("%s: Text relocations are not supported", GetPath());
|
||||
return false;
|
||||
has_text_relocs = true;
|
||||
break;
|
||||
case DT_STRSZ: /* Ignored */
|
||||
debug_dyn("DT_STRSZ", dyn);
|
||||
break;
|
||||
@ -620,8 +647,7 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
|
||||
Addr flags = dyn->d_un.d_val;
|
||||
/* Treat as a DT_TEXTREL tag */
|
||||
if (flags & DF_TEXTREL) {
|
||||
LOG("%s: Text relocations are not supported", GetPath());
|
||||
return false;
|
||||
has_text_relocs = true;
|
||||
}
|
||||
/* we can treat this like having a DT_SYMBOLIC tag */
|
||||
flags &= ~DF_SYMBOLIC;
|
||||
@ -677,8 +703,7 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
|
||||
dependencies.push_back(handle);
|
||||
}
|
||||
|
||||
/* Finish initialization */
|
||||
return Relocate() && RelocateJumps() && CallInit();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -76,7 +76,12 @@ private:
|
||||
* Private constructor
|
||||
*/
|
||||
CustomElf(Mappable *mappable, const char *path)
|
||||
: LibHandle(path), mappable(mappable), init(0), fini(0), initialized(false)
|
||||
: LibHandle(path)
|
||||
, mappable(mappable)
|
||||
, init(0)
|
||||
, fini(0)
|
||||
, initialized(false)
|
||||
, has_text_relocs(false)
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -193,6 +198,8 @@ private:
|
||||
|
||||
bool initialized;
|
||||
|
||||
bool has_text_relocs;
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
/* ARM.exidx information used by FindExidx */
|
||||
Array<uint32_t[2]> arm_exidx;
|
||||
|
Loading…
Reference in New Issue
Block a user