[uClibc-cvs] CVS uClibc/ldso/ldso
CVS User jocke
jocke at codepoet.org
Tue Nov 2 08:14:46 UTC 2004
Update of /var/cvs/uClibc/ldso/ldso
In directory nail:/tmp/cvs-serv19564/ldso
Modified Files:
Makefile dl-elf.c dl-hash.c dl-startup.c ldso.c
Log Message:
- Remove dynamic_size from struct elf_resolve.
- Replace all open coded dynamic handling with a function. Reduces size.
- Fold special MIPS dynamic code into the dynamic_info item.
- Add RELRO support.
- Support linking with "-z now".
- prepare for DT_RELACOUNT/DT_RELCOUNT optimization.
- Add -z now to ld.so linking, this is what ld.so does anyway so
let the linker know that.
--- /var/cvs/uClibc/ldso/ldso/Makefile 2004/10/06 06:59:56 1.63
+++ /var/cvs/uClibc/ldso/ldso/Makefile 2004/11/02 08:14:45 1.64
@@ -40,7 +40,7 @@
XXFLAGS :=$(XXFLAGS:-O0=-O1)
XXFLAGS+=$(shell $(CC) -print-search-dirs | sed -ne "s/install: *\(.*\)/-I\1include/gp")
-LDFLAGS=$(CPU_LDFLAGS-y) -Bsymbolic -shared --warn-common --export-dynamic --sort-common \
+LDFLAGS=$(CPU_LDFLAGS-y) -z now -Bsymbolic -shared --warn-common --export-dynamic --sort-common \
-z combreloc --discard-locals --discard-all --no-undefined
CSRC= ldso.c
--- /var/cvs/uClibc/ldso/ldso/dl-elf.c 2004/10/11 20:57:11 1.87
+++ /var/cvs/uClibc/ldso/ldso/dl-elf.c 2004/11/02 08:14:45 1.88
@@ -114,6 +114,25 @@
}
#endif
+
+void
+_dl_protect_relro (struct elf_resolve *l)
+{
+ ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
+ & ~(_dl_pagesize - 1));
+ ElfW(Addr) end = ((l->loadaddr + l->relro_addr + l->relro_size)
+ & ~(_dl_pagesize - 1));
+#if defined (__SUPPORT_LD_DEBUG__)
+ if (_dl_debug)
+ _dl_dprintf(2, "RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end);
+#endif
+ if (start != end &&
+ _dl_mprotect ((void *) start, end - start, PROT_READ) < 0) {
+ _dl_dprintf(2, "%s: cannot apply additional memory protection after relocation", l->libname);
+ _dl_exit(0);
+ }
+}
+
/* This function's behavior must exactly match that
* in uClibc/ldso/util/ldd.c */
static struct elf_resolve *
@@ -390,16 +409,17 @@
{
ElfW(Ehdr) *epnt;
unsigned long dynamic_addr = 0;
- unsigned long dynamic_size = 0;
Elf32_Dyn *dpnt;
struct elf_resolve *tpnt;
ElfW(Phdr) *ppnt;
char *status, *header;
- unsigned long dynamic_info[24];
+ unsigned long dynamic_info[DYNAMIC_SIZE];
unsigned long *lpnt;
unsigned long libaddr;
unsigned long minvma = 0xffffffff, maxvma = 0;
int i, flags, piclib, infile;
+ ElfW(Addr) relro_addr = 0;
+ size_t relro_size = 0;
/* If this file is already loaded, skip this step */
tpnt = _dl_check_hashed_files(libname);
@@ -493,7 +513,6 @@
_dl_dprintf(2, "%s: '%s' has more than one dynamic section\n",
_dl_progname, libname);
dynamic_addr = ppnt->p_vaddr;
- dynamic_size = ppnt->p_filesz;
};
if (ppnt->p_type == PT_LOAD) {
@@ -535,6 +554,10 @@
ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
for (i = 0; i < epnt->e_phnum; i++) {
+ if (ppnt->p_type == PT_GNU_RELRO) {
+ relro_addr = ppnt->p_vaddr;
+ relro_size = ppnt->p_memsz;
+ }
if (ppnt->p_type == PT_LOAD) {
/* See if this is a PIC library. */
@@ -627,40 +650,8 @@
}
dpnt = (Elf32_Dyn *) dynamic_addr;
-
- dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-
-#if defined(__mips__)
- {
-
- int indx = 1;
- Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
-
- while(dpnt->d_tag) {
- dpnt++;
- indx++;
- }
- dynamic_size = indx;
- }
-#endif
-
- {
- unsigned long indx;
-
- for (indx = 0; indx < dynamic_size; indx++)
- {
- if (dpnt->d_tag > DT_JMPREL) {
- dpnt++;
- continue;
- }
- dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_TEXTREL)
- dynamic_info[DT_TEXTREL] = 1;
- dpnt++;
- };
- }
-
+ _dl_parse_dynamic_info(dpnt, dynamic_info, NULL);
/* If the TEXTREL is set, this means that we need to make the pages
writable before we perform relocations. Do this now. They get set
back again later. */
@@ -682,8 +673,9 @@
}
tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info,
- dynamic_addr, dynamic_size);
-
+ dynamic_addr, 0);
+ tpnt->relro_addr = relro_addr;
+ tpnt->relro_size = relro_size;
tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
tpnt->n_phent = epnt->e_phnum;
@@ -718,8 +710,8 @@
#if defined (__SUPPORT_LD_DEBUG__)
if(_dl_debug) {
_dl_dprintf(2, "\n\tfile='%s'; generating link map\n", libname);
- _dl_dprintf(2, "\t\tdynamic: %x base: %x size: %x\n",
- dynamic_addr, libaddr, dynamic_size);
+ _dl_dprintf(2, "\t\tdynamic: %x base: %x\n",
+ dynamic_addr, libaddr);
_dl_dprintf(2, "\t\t entry: %x phdr: %x phnum: %x\n\n",
epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
@@ -769,6 +761,8 @@
tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],
reloc_size);
}
+ if (tpnt->dynamic_info[DT_BIND_NOW])
+ now_flag = RTLD_NOW;
if (tpnt->dynamic_info[DT_JMPREL] &&
(!(tpnt->init_flag & JMP_RELOCS_DONE) ||
(now_flag && !(tpnt->rtld_flags & now_flag)))) {
@@ -784,7 +778,6 @@
tpnt->dynamic_info[DT_PLTRELSZ]);
}
}
-
return goof;
}
@@ -880,6 +873,11 @@
_dl_strcpy(retval, string);
return retval;
}
+
+void _dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr)
+{
+ __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr);
+}
#ifdef __USE_GNU
#if ! defined LIBDL || (! defined PIC && ! defined __PIC__)
int
--- /var/cvs/uClibc/ldso/ldso/dl-hash.c 2004/08/26 14:00:04 1.24
+++ /var/cvs/uClibc/ldso/ldso/dl-hash.c 2004/11/02 08:14:45 1.25
@@ -116,7 +116,6 @@
tpnt->init_flag = 0;
tpnt->libname = _dl_strdup(libname);
tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
- tpnt->dynamic_size = dynamic_size;
tpnt->libtype = loaded_file;
if (dynamic_info[DT_HASH] != 0) {
@@ -128,23 +127,8 @@
tpnt->chains = hash_addr;
}
tpnt->loadaddr = (ElfW(Addr))loadaddr;
- for (i = 0; i < 24; i++)
+ for (i = 0; i < DYNAMIC_SIZE; i++)
tpnt->dynamic_info[i] = dynamic_info[i];
-#ifdef __mips__
- {
- Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
-
- while(dpnt->d_tag) {
- if (dpnt->d_tag == DT_MIPS_GOTSYM)
- tpnt->mips_gotsym = dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
- tpnt->mips_local_gotno = dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_SYMTABNO)
- tpnt->mips_symtabno = dpnt->d_un.d_val;
- dpnt++;
- }
- }
-#endif
return tpnt;
}
--- /var/cvs/uClibc/ldso/ldso/dl-startup.c 2004/10/06 06:59:57 1.21
+++ /var/cvs/uClibc/ldso/ldso/dl-startup.c 2004/11/02 08:14:45 1.22
@@ -281,23 +281,14 @@
#ifdef __SUPPORT_LD_DEBUG_EARLY__
SEND_STDERR("scanning DYNAMIC section\n");
#endif
- while (dpnt->d_tag) {
-#if defined(__mips__)
- if (dpnt->d_tag == DT_MIPS_GOTSYM)
- tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
- tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_SYMTABNO)
- tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#endif
- if (dpnt->d_tag < 24) {
- tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_TEXTREL) {
- tpnt->dynamic_info[DT_TEXTREL] = 1;
- }
- }
- dpnt++;
- }
+ tpnt->dynamic_addr = dpnt;
+#ifdef __mips__
+ /* MIPS cannot call functions here, must inline */
+ __dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL);
+#else
+ _dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL);
+#endif
+
#ifdef __SUPPORT_LD_DEBUG_EARLY__
SEND_STDERR("done scanning DYNAMIC section\n");
#endif
@@ -335,7 +326,7 @@
SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
#endif
/* For MIPS we have to do stuff to the GOT before we do relocations. */
- PERFORM_BOOTSTRAP_GOT(got);
+ PERFORM_BOOTSTRAP_GOT(got, tpnt);
#endif
/* OK, now do the relocations. We do not do a lazy binding here, so
--- /var/cvs/uClibc/ldso/ldso/ldso.c 2004/10/27 22:07:52 1.126
+++ /var/cvs/uClibc/ldso/ldso/ldso.c 2004/11/02 08:14:45 1.127
@@ -97,9 +97,11 @@
struct elf_resolve app_tpnt_tmp;
struct elf_resolve *app_tpnt = &app_tpnt_tmp;
struct r_debug *debug_addr;
- unsigned long brk_addr, *lpnt;
+ unsigned long *lpnt;
int (*_dl_atexit) (void *);
unsigned long *_dl_envp; /* The environment address */
+ ElfW(Addr) relro_addr = 0;
+ size_t relro_size = 0;
#if defined (__SUPPORT_LD_DEBUG__)
int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
#endif
@@ -132,23 +134,6 @@
* go from there. Eventually we will run across ourself, and we
* will need to properly deal with that as well.
*/
- {
- ElfW(Ehdr) *epnt;
- ElfW(Phdr) *myppnt;
- int j;
-
- epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
- tpnt->n_phent = epnt->e_phnum;
- tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
- for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
- if (myppnt->p_type == PT_DYNAMIC) {
- tpnt->dynamic_addr = (ElfW(Dyn) *)(myppnt->p_vaddr + load_addr);
- tpnt->dynamic_size = myppnt->p_filesz;
- }
- }
- }
-
- brk_addr = 0;
rpnt = NULL;
if (_dl_getenv("LD_BIND_NOW", envp))
unlazy = RTLD_NOW;
@@ -189,46 +174,13 @@
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
- if (ppnt->p_type == PT_LOAD) {
- if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr)
- brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
+ if (ppnt->p_type == PT_GNU_RELRO) {
+ relro_addr = ppnt->p_vaddr;
+ relro_size = ppnt->p_memsz;
}
if (ppnt->p_type == PT_DYNAMIC) {
dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
- while (dpnt->d_tag) {
-#if defined(__mips__)
- if (dpnt->d_tag == DT_MIPS_GOTSYM)
- app_tpnt->mips_gotsym =
- (unsigned long) dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
- app_tpnt->mips_local_gotno =
- (unsigned long) dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_MIPS_SYMTABNO)
- app_tpnt->mips_symtabno =
- (unsigned long) dpnt->d_un.d_val;
- /* Remember... DT_MIPS_RLD_MAP > DT_JMPREL. */
- if (dpnt->d_tag == DT_MIPS_RLD_MAP) {
- *(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr;
- }
- if (dpnt->d_tag > DT_JMPREL) {
- dpnt++;
- continue;
- }
- app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-#else
- if (dpnt->d_tag > DT_JMPREL) {
- dpnt++;
- continue;
- }
- app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
- if (dpnt->d_tag == DT_DEBUG) {
- dpnt->d_un.d_val = (unsigned long) debug_addr;
- }
-#endif
- if (dpnt->d_tag == DT_TEXTREL)
- app_tpnt->dynamic_info[DT_TEXTREL] = 1;
- dpnt++;
- }
+ _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr);
#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
/* Ugly, ugly. We need to call mprotect to change the
* protection of the text pages so that we can do the
@@ -315,6 +267,8 @@
#endif
}
}
+ app_tpnt->relro_addr = relro_addr;
+ app_tpnt->relro_size = relro_size;
/* Now we need to figure out what kind of options are selected.
* Note that for SUID programs we ignore the settings in
@@ -728,10 +682,24 @@
* again once all libs are loaded.
*/
if (tpnt) {
+ ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+ ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
+ int j;
+
tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
tpnt->dynamic_info,
(unsigned long)tpnt->dynamic_addr,
- tpnt->dynamic_size);
+ 0);
+
+ tpnt->n_phent = epnt->e_phnum;
+ tpnt->ppnt = myppnt;
+ for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
+ if (myppnt->p_type == PT_GNU_RELRO) {
+ tpnt->relro_addr = myppnt->p_vaddr;
+ tpnt->relro_size = myppnt->p_memsz;
+ break;
+ }
+ }
tpnt->libtype = program_interpreter;
tpnt->usage_count++;
tpnt->symbol_scope = _dl_symbol_tables;
@@ -791,6 +759,13 @@
if (_dl_symbol_tables)
goof += _dl_fixup(_dl_symbol_tables, unlazy);
+ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+ if (tpnt->relro_size)
+ _dl_protect_relro (tpnt);
+ }
+
+
+
/* OK, at this point things are pretty much ready to run. Now we need
* to touch up a few items that are required, and then we can let the
More information about the uClibc-cvs
mailing list