linker: improve loadable segment protection.

Use the functions in linker_phdr.c to load the PT_LOAD segments
in memory, and toggle their mapping's writable protection bit
as needed. In particular:

  - when loading a library, load the segments then unprotected
    them to allow relocations to work.

  - when relocating the linker of the executable, unprotect
    the segments loaded by the kernel to make relocations work
    too.

  - after all relocations are done, re-protect the segments,
    and apply GNU RELRO protection if needed.

  - just before calling the destructors, undo the GNU RELRO
    protection.

Change-Id: I50e709f03958204b8d6140c0f51ebe24fe089a1b
This commit is contained in:
David 'Digit' Turner
2012-06-19 01:24:17 +02:00
parent 63f99f4a4e
commit b52e4385c4
2 changed files with 99 additions and 443 deletions

View File

@@ -107,7 +107,7 @@ typedef struct soinfo soinfo;
struct soinfo
{
const char name[SOINFO_NAME_LEN];
Elf32_Phdr *phdr;
const Elf32_Phdr *phdr;
int phnum;
unsigned entry;
unsigned base;
@@ -117,8 +117,8 @@ struct soinfo
unsigned *dynamic;
unsigned wrprotect_start;
unsigned wrprotect_end;
unsigned unused2; // DO NOT USE, maintained for compatibility
unsigned unused3; // DO NOT USE, maintained for compatibility
soinfo *next;
unsigned flags;
@@ -161,9 +161,6 @@ struct soinfo
int constructors_called;
Elf32_Addr gnu_relro_start;
unsigned gnu_relro_len;
/* When you read a virtual address from the ELF file, add this
* value to get the corresponding address in the process' address space */
Elf32_Addr load_bias;