From 8323008c642b50b3d3d1258ce87bae40c79df55e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 27 Sep 2002 07:29:51 +0000 Subject: [PATCH] * elf/dl-addr.c (_dl_addr): Set dli_fbase to l_map_start unconditionally. Set dli_fname to _dl_argv[0] only for main program. 2002-09-27 Roland McGrath * elf/dl-addr.c (_dl_addr): Add a cast. * sysdeps/x86_64/dl-machine.h (elf_machine_rela) [USE_TLS]: Handle new TLS relocs R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, and R_X86_64_TPOFF64. * elf/elf.h (R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, R_X86_64_TPOFF64, R_X86_64_TLSGD, R_X86_64_TLSLD, R_X86_64_DTPOFF32, R_x86_64_GOTTPOFF, R_X86_64_TPOFF32): New macros. (R_X86_64_NUM): Update the value. --- ChangeLog | 17 ++++++++++ elf/dl-addr.c | 12 +++---- elf/elf.h | 17 ++++++++-- sysdeps/x86_64/dl-machine.h | 65 ++++++++++++++++++++++++++++++++++--- 4 files changed, 96 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index c047785e60..f7e54f5a79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-09-27 Jakub Jelinek + + * elf/dl-addr.c (_dl_addr): Set dli_fbase to l_map_start + unconditionally. Set dli_fname to _dl_argv[0] only for main program. + +2002-09-27 Roland McGrath + + * elf/dl-addr.c (_dl_addr): Add a cast. + + * sysdeps/x86_64/dl-machine.h (elf_machine_rela) [USE_TLS]: Handle new + TLS relocs R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, and R_X86_64_TPOFF64. + + * elf/elf.h (R_X86_64_DTPMOD64, R_X86_64_DTPOFF64, R_X86_64_TPOFF64, + R_X86_64_TLSGD, R_X86_64_TLSLD, R_X86_64_DTPOFF32, + R_x86_64_GOTTPOFF, R_X86_64_TPOFF32): New macros. + (R_X86_64_NUM): Update the value. + 2002-09-24 Jakub Jelinek * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_load_address): Don't diff --git a/elf/dl-addr.c b/elf/dl-addr.c index 66cec39eb4..e560c74ab5 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -60,14 +60,12 @@ _dl_addr (const void *address, Dl_info *info) /* Now we know what object the address lies in. */ info->dli_fname = match->l_name; - info->dli_fbase = (void *) match->l_addr; + info->dli_fbase = (void *) match->l_map_start; /* If this is the main program the information is incomplete. */ - if (__builtin_expect (info->dli_fbase == NULL, 0)) - { - info->dli_fname = _dl_argv[0]; - info->dli_fbase = (void *) match->l_map_start; - } + if (__builtin_expect (l->l_name[0], 'a') == '\0' + && l->l_type == lt_executable) + info->dli_fname = _dl_argv[0]; symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]); strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]); @@ -81,7 +79,7 @@ _dl_addr (const void *address, Dl_info *info) dynamic symbol table and no hash table is present. The ELF binary is ill-formed but what shall we do? Use the beginning of the string table which generally follows the symbol table. */ - symtabend = strtab; + symtabend = (const ElfW(Sym) *) strtab; /* We assume that the string table follows the symbol table, because there is no way in ELF to know the size of the dynamic symbol table!! */ diff --git a/elf/elf.h b/elf/elf.h index b664c5d279..2d79be2f65 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -2294,7 +2294,7 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ #define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */ #define R_X86_64_32 10 /* Direct 32 bit zero extended */ #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ @@ -2302,8 +2302,19 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ #define R_X86_64_8 14 /* Direct 8 bit sign extended */ #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ - -#define R_X86_64_NUM 16 +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define r_x86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ + +#define R_X86_64_NUM 24 __END_DECLS diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 2800a9e958..6179bba3f7 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -283,13 +283,24 @@ _dl_start_user:\n\ .previous\n\ "); -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ - ((((type) == R_X86_64_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ +#ifdef USE_TLS +# define elf_machine_type_class(type) \ + ((((type) == R_X86_64_JUMP_SLOT + || (type) == R_X86_64_DTPMOD64 + || (type) == R_X86_64_DTPOFF64 || (type) == R_X86_64_DTPOFF32 + || (type) == R_X86_64_TPOFF64 || (type) == R_X86_64_TPOFF32) + * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ + ((((type) == R_X86_64_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_X86_64_JUMP_SLOT @@ -366,14 +377,19 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, #ifndef RTLD_BOOTSTRAP const Elf64_Sym *const refsym = sym; #endif +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; +#else Elf64_Addr value = RESOLVE (&sym, version, r_type); # ifndef RTLD_BOOTSTRAP if (sym != NULL) # endif value += sym->st_value; +#endif -#ifdef RTLD_BOOTSTRAP +#if defined RTLD_BOOTSTRAP && !(USE_TLS && HAVE___THREAD) assert (r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT); *reloc_addr = value + reloc->r_addend; #else @@ -383,6 +399,44 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, case R_X86_64_JUMP_SLOT: *reloc_addr = value + reloc->r_addend; break; + +#ifdef USE_TLS + case R_X86_64_DTPMOD64: +# ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always the module + with index 1. + XXX If this relocation is necessary move before RESOLVE + call. */ + *reloc_addr = 1; +# else + /* Get the information from the link map returned by the + resolve function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +# endif + break; + case R_X86_64_DTPOFF64: +# ifndef RTLD_BOOTSTRAP + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + if (sym != NULL) + *reloc_addr = sym->st_value + reloc->r_addend; +# endif + break; + case R_X86_64_TPOFF64: + /* The offset is negative, forward from the thread pointer. */ +# ifndef RTLD_BOOTSTRAP + if (sym != NULL) +# endif + /* We know the offset of the object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + *reloc_addr = (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset); + break; +#endif /* use TLS */ + +#ifndef RTLD_BOOTSTRAP case R_X86_64_64: *reloc_addr = value + reloc->r_addend; break; @@ -439,6 +493,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, default: _dl_reloc_bad_type (map, r_type, 0); break; +#endif } #endif } -- 2.43.5