? dl-startup.c.hidden_GLOBAL ? relro_hello ? ldso/dl-elf.c.dynamic ? ldso/dl-elf.h.h.dynamic ? ldso/dl-startup.c.dynimic ? ldso/ldso.h.dynamic ? ldso/ldso.readelf ? ldso/ldso_exec ? ldso/powerpc/resolve.S.hidden Index: include/dl-elf.h =================================================================== RCS file: /var/cvs/uClibc/ldso/include/dl-elf.h,v retrieving revision 1.17 diff -u -p -r1.17 dl-elf.h --- include/dl-elf.h 7 Oct 2004 13:48:19 -0000 1.17 +++ include/dl-elf.h 29 Oct 2004 23:52:37 -0000 @@ -33,7 +33,9 @@ extern struct elf_resolve *_dl_check_if_ int trace_loaded_objects); extern int _dl_linux_resolve(void); extern int _dl_fixup(struct dyn_elf *rpnt, int flag); +extern void _dl_protect_relro (struct elf_resolve *l); +void parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr); /* * Datatype of a relocation on this platform @@ -42,12 +44,14 @@ extern int _dl_fixup(struct dyn_elf *rpn # define ELF_RELOC ElfW(Rela) # define DT_RELOC_TABLE_ADDR DT_RELA # define DT_RELOC_TABLE_SIZE DT_RELASZ +# define DT_RELOCCOUNT DT_RELACOUNT # define UNSUPPORTED_RELOC_TYPE DT_REL # define UNSUPPORTED_RELOC_STR "REL" #else # define ELF_RELOC ElfW(Rel) # define DT_RELOC_TABLE_ADDR DT_REL # define DT_RELOC_TABLE_SIZE DT_RELSZ +# define DT_RELOCCOUNT DT_RELCOUNT # define UNSUPPORTED_RELOC_TYPE DT_RELA # define UNSUPPORTED_RELOC_STR "RELA" #endif Index: include/dl-hash.h =================================================================== RCS file: /var/cvs/uClibc/ldso/include/dl-hash.h,v retrieving revision 1.8 diff -u -p -r1.8 dl-hash.h --- include/dl-hash.h 7 Oct 2004 13:48:19 -0000 1.8 +++ include/dl-hash.h 29 Oct 2004 23:52:37 -0000 @@ -5,6 +5,17 @@ #define RTLD_NEXT ((void*)-1) #endif +/* OS and/or GNU dynamic extensions */ +#define OS_NUM 1 +#define DT_RELCONT_IDX DT_NUM + +#ifndef ARCH_DYNAMIC_INFO + /* define in arch specific code, if needed */ +# define ARCH_NUM 0 +#endif + +#define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM) + struct init_fini { struct elf_resolve **init_fini; unsigned long nlist; /* Number of entries in init_fini */ @@ -41,18 +52,13 @@ struct elf_resolve{ */ unsigned long nchain; unsigned long * chains; - unsigned long dynamic_info[24]; + unsigned long dynamic_info[DYNAMIC_SIZE]; - unsigned long dynamic_size; unsigned long n_phent; Elf32_Phdr * ppnt; -#if defined(__mips__) - /* Needed for MIPS relocation */ - unsigned long mips_gotsym; - unsigned long mips_local_gotno; - unsigned long mips_symtabno; -#endif + ElfW(Addr) relro_addr; + size_t relro_size; #ifdef __powerpc__ /* this is used to store the address of relocation data words, so Index: ldso/dl-elf.c =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/dl-elf.c,v retrieving revision 1.87 diff -u -p -r1.87 dl-elf.c --- ldso/dl-elf.c 11 Oct 2004 20:57:11 -0000 1.87 +++ ldso/dl-elf.c 29 Oct 2004 23:52:38 -0000 @@ -114,6 +114,25 @@ int _dl_unmap_cache(void) } #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 @@ struct elf_resolve *_dl_load_elf_shared_ { 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 @@ struct elf_resolve *_dl_load_elf_shared_ _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 @@ struct elf_resolve *_dl_load_elf_shared_ 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 @@ struct elf_resolve *_dl_load_elf_shared_ } 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++; - }; - } - + 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 @@ struct elf_resolve *_dl_load_elf_shared_ } 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 @@ struct elf_resolve *_dl_load_elf_shared_ #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 @@ int _dl_fixup(struct dyn_elf *rpnt, int 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 @@ int _dl_fixup(struct dyn_elf *rpnt, int tpnt->dynamic_info[DT_PLTRELSZ]); } } - return goof; } @@ -880,6 +873,38 @@ char *_dl_strdup(const char *string) _dl_strcpy(retval, string); return retval; } + +void parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr) +{ + for (; dpnt->d_tag; dpnt++) { + if (dpnt->d_tag < DT_NUM) { + dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; +#ifndef __mips__ + if (dpnt->d_tag == DT_DEBUG) + dpnt->d_un.d_val = (unsigned long)debug_addr; +#endif + if (dpnt->d_tag == DT_BIND_NOW) + dynamic_info[DT_BIND_NOW] = 1; + if (dpnt->d_tag == DT_FLAGS && + (dpnt->d_un.d_val & DF_BIND_NOW)) + dynamic_info[DT_BIND_NOW] = 1; + if (dpnt->d_tag == DT_TEXTREL) + dynamic_info[DT_TEXTREL] = 1; + } else if (dpnt->d_tag < DT_LOPROC) { + if (dpnt->d_tag == DT_RELOCCOUNT) + dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val; + if (dpnt->d_tag == DT_FLAGS_1 && + (dpnt->d_un.d_val & DF_1_NOW)) + dynamic_info[DT_BIND_NOW] = 1; + } +#ifdef ARCH_DYNAMIC_INFO + else { + ARCH_DYNAMIC_INFO(dpnt, dynamic_info, debug_addr); + } +#endif + } +} + #ifdef __USE_GNU #if ! defined LIBDL || (! defined PIC && ! defined __PIC__) int Index: ldso/dl-hash.c =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/dl-hash.c,v retrieving revision 1.24 diff -u -p -r1.24 dl-hash.c --- ldso/dl-hash.c 26 Aug 2004 14:00:04 -0000 1.24 +++ ldso/dl-hash.c 29 Oct 2004 23:52:38 -0000 @@ -116,7 +116,6 @@ struct elf_resolve *_dl_add_elf_hash_tab 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 @@ struct elf_resolve *_dl_add_elf_hash_tab 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; } Index: ldso/dl-startup.c =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/dl-startup.c,v retrieving revision 1.21 diff -u -p -r1.21 dl-startup.c --- ldso/dl-startup.c 6 Oct 2004 06:59:57 -0000 1.21 +++ ldso/dl-startup.c 29 Oct 2004 23:52:38 -0000 @@ -281,23 +281,8 @@ found_got: #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++; - } + parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL); + tpnt->dynamic_addr = dpnt; #ifdef __SUPPORT_LD_DEBUG_EARLY__ SEND_STDERR("done scanning DYNAMIC section\n"); #endif @@ -335,7 +320,7 @@ found_got: 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 Index: ldso/ldso.c =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/ldso.c,v retrieving revision 1.126 diff -u -p -r1.126 ldso.c --- ldso/ldso.c 27 Oct 2004 22:07:52 -0000 1.126 +++ ldso/ldso.c 29 Oct 2004 23:52:38 -0000 @@ -97,9 +97,11 @@ void _dl_get_ready_to_run(struct elf_res 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 @@ void _dl_get_ready_to_run(struct elf_res * 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 @@ void _dl_get_ready_to_run(struct elf_res 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++; - } + 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,7 +267,13 @@ void _dl_get_ready_to_run(struct elf_res #endif } } - + app_tpnt->relro_addr = relro_addr; + app_tpnt->relro_size = relro_size; +#if 0 + if (app_tpnt->dynamic_info[DT_BIND_NOW] || + app_tpnt->dynamic_info[DT_FLAGS] & DF_BIND_NOW) + unlazy = 0; +#endif /* Now we need to figure out what kind of options are selected. * Note that for SUID programs we ignore the settings in * LD_LIBRARY_PATH. @@ -731,7 +689,7 @@ next_lib2: tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr, tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr, - tpnt->dynamic_size); + 0); tpnt->libtype = program_interpreter; tpnt->usage_count++; tpnt->symbol_scope = _dl_symbol_tables; @@ -791,6 +749,13 @@ next_lib2: 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 Index: ldso/mips/dl-startup.h =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/mips/dl-startup.h,v retrieving revision 1.10 diff -u -p -r1.10 dl-startup.h --- ldso/mips/dl-startup.h 20 Apr 2004 06:33:01 -0000 1.10 +++ ldso/mips/dl-startup.h 29 Oct 2004 23:52:38 -0000 @@ -48,21 +48,21 @@ asm("" \ * Here is a macro to perform the GOT relocation. This is only * used when bootstrapping the dynamic loader. */ -#define PERFORM_BOOTSTRAP_GOT(got) \ +#define PERFORM_BOOTSTRAP_GOT(got, tpnt) \ do { \ Elf32_Sym *sym; \ unsigned long i; \ \ /* Add load address displacement to all local GOT entries */ \ i = 2; \ - while (i < tpnt->mips_local_gotno) \ + while (i < tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \ got[i++] += load_addr; \ \ /* Handle global GOT entries */ \ - got += tpnt->mips_local_gotno; \ + got += tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; \ sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \ - load_addr) + tpnt->mips_gotsym; \ - i = tpnt->mips_symtabno - tpnt->mips_gotsym; \ + load_addr) + tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; \ + i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX];\ \ while (i--) { \ if (sym->st_shndx == SHN_UNDEF || \ @@ -91,8 +91,8 @@ do { \ #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ switch(ELF32_R_TYPE((RELP)->r_info)) { \ case R_MIPS_REL32: \ - if (symtab_index) { \ - if (symtab_index < tpnt->mips_gotsym) \ + if (SYMTAB) { \ + if (symtab_indexdynamic_info[DT_MIPS_GOTSYM_IDX])\ *REL += SYMBOL; \ } \ else { \ Index: ldso/mips/dl-sysdep.h =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/mips/dl-sysdep.h,v retrieving revision 1.12 diff -u -p -r1.12 dl-sysdep.h --- ldso/mips/dl-sysdep.h 23 Sep 2004 07:05:36 -0000 1.12 +++ ldso/mips/dl-sysdep.h 29 Oct 2004 23:52:38 -0000 @@ -8,6 +8,22 @@ /* Define this if the system uses RELOCA. */ #undef ELF_USES_RELOCA +#define ARCH_NUM 3 +#define DT_MIPS_GOTSYM_IDX (DT_NUM + OS_NUM +1) +#define DT_MIPS_LOCAL_GOTNO_IDX (DT_NUM + OS_NUM +2) +#define DT_MIPS_SYMTABNO_IDX (DT_NUM + OS_NUM +3) + +#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \ +do { \ +if (dpnt->d_tag == DT_MIPS_GOTSYM) \ + dynamic[DT_MIPS_GOTSYM_IDX] = dpnt->d_un.d_val; \ +else if(dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) \ + dynamic[DT_MIPS_LOCAL_GOTNO_IDX] = dpnt->d_un.d_val; \ +else if(dpnt->d_tag == DT_MIPS_SYMTABNO) \ + dynamic[DT_MIPS_SYMTABNO_IDX] = dpnt->d_un.d_val; \ +else if (dpnt->d_tag == DT_MIPS_RLD_MAP) \ + *(Elf32_Addr *)(dpnt->d_un.d_ptr) = (Elf32_Addr) debug_addr; \ +} while (0) /* Initialization sequence for the application/library GOT. */ #define INIT_GOT(GOT_BASE,MODULE) \ @@ -24,7 +40,7 @@ do { \ \ /* Add load address displacement to all local GOT entries */ \ i = 2; \ - while (i < MODULE->mips_local_gotno) \ + while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \ GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \ \ } while (0) Index: ldso/mips/elfinterp.c =================================================================== RCS file: /var/cvs/uClibc/ldso/ldso/mips/elfinterp.c,v retrieving revision 1.22 diff -u -p -r1.22 elfinterp.c --- ldso/mips/elfinterp.c 26 Aug 2004 20:43:25 -0000 1.22 +++ ldso/mips/elfinterp.c 29 Oct 2004 23:52:38 -0000 @@ -121,8 +121,8 @@ unsigned long _dl_linux_resolver(unsigne char **got_addr; char *symname; - gotsym = tpnt->mips_gotsym; - local_gotno = tpnt->mips_local_gotno; + gotsym = tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; + local_gotno = tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; sym = ((Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr)) + sym_index; strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); @@ -213,13 +213,13 @@ int _dl_parse_relocation_information(str switch (reloc_type) { case R_MIPS_REL32: if (symtab_index) { - if (symtab_index < tpnt->mips_gotsym) + if (symtab_index < tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]) *reloc_addr += symtab[symtab_index].st_value + (unsigned long) tpnt->loadaddr; else { - *reloc_addr += got[symtab_index + tpnt->mips_local_gotno - - tpnt->mips_gotsym]; + *reloc_addr += got[symtab_index + tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX] - + tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]]; } } else { @@ -270,12 +270,12 @@ void _dl_perform_mips_global_got_relocat /* Setup the loop variables */ got_entry = (unsigned long *) (tpnt->loadaddr + - tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno; + tpnt->dynamic_info[DT_PLTGOT]) + tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + - (unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym; + (unsigned long) tpnt->loadaddr) + tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + (unsigned long) tpnt->loadaddr); - i = tpnt->mips_symtabno - tpnt->mips_gotsym; + i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug_reloc) Index: libdl/libdl.c =================================================================== RCS file: /var/cvs/uClibc/ldso/libdl/libdl.c,v retrieving revision 1.59 diff -u -p -r1.59 libdl.c --- libdl/libdl.c 14 Oct 2004 15:23:51 -0000 1.59 +++ libdl/libdl.c 29 Oct 2004 23:52:39 -0000 @@ -128,7 +128,7 @@ void __attribute__ ((destructor)) dl_cle void *dlopen(const char *libname, int flag) { struct elf_resolve *tpnt, *tfrom, *tcurr; - struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr; + struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr; struct dyn_elf *dpnt; ElfW(Addr) from; struct elf_resolve *tpnt1; @@ -168,6 +168,8 @@ void *dlopen(const char *libname, int fl tfrom = tpnt; } for(rpnt = _dl_symbol_tables; rpnt->next; rpnt=rpnt->next); + + relro_ptr = rpnt; /* Try to load the specified library */ #ifdef __SUPPORT_LD_DEBUG__ if(_dl_debug) @@ -311,6 +313,10 @@ void *dlopen(const char *libname, int fl if (_dl_fixup(dyn_chain, now_flag)) goto oops; + for (rpnt = relro_ptr->next; rpnt; rpnt = rpnt->next) { + if (rpnt->dyn->relro_size) + _dl_protect_relro(rpnt->dyn); + } /* TODO: Should we set the protections of all pages back to R/O now ? */