Skip to content

Commit

Permalink
Bug 956398 - Support text relocations in the custom linker. r=nfroyd
Browse files Browse the repository at this point in the history
  • Loading branch information
glandium committed Jan 16, 2014
1 parent 4bae5da commit ec7b1e0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
43 changes: 34 additions & 9 deletions mozglue/linker/CustomElf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -677,8 +703,7 @@ CustomElf::InitDyn(const Phdr *pt_dyn)
dependencies.push_back(handle);
}

/* Finish initialization */
return Relocate() && RelocateJumps() && CallInit();
return true;
}

bool
Expand Down
9 changes: 8 additions & 1 deletion mozglue/linker/CustomElf.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ class CustomElf: public LibHandle, private ElfLoader::link_map
* 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)
{ }

/**
Expand Down Expand Up @@ -193,6 +198,8 @@ class CustomElf: public LibHandle, private ElfLoader::link_map

bool initialized;

bool has_text_relocs;

#ifdef __ARM_EABI__
/* ARM.exidx information used by FindExidx */
Array<uint32_t[2]> arm_exidx;
Expand Down

0 comments on commit ec7b1e0

Please sign in to comment.