diff options
author | Roland McGrath <roland@redhat.com> | 2008-04-01 02:30:05 +0000 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2008-04-01 02:30:05 +0000 |
commit | 13b69609bcd5638e6194d940855fea3dd0519605 (patch) | |
tree | ffaa63b3cd050285d68ebc6c437c012edb59ddf9 /backends | |
parent | d11f9cbecac4a5ac3848a68597028d1924f3ff6b (diff) | |
download | elfutils-13b69609bcd5638e6194d940855fea3dd0519605.tar.gz |
backends/
* sparc_symbol.c (sparc_symbol_type_name): New function.
(sparc_dynamic_tag_name): New function.
(sparc_dynamic_tag_check): New function.
* sparc_init.c (sparc_init): Initialize those hooks.
libebl/
* ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag.
Diffstat (limited to 'backends')
-rw-r--r-- | backends/ChangeLog | 10 | ||||
-rw-r--r-- | backends/sparc_init.c | 6 | ||||
-rw-r--r-- | backends/sparc_symbol.c | 80 |
3 files changed, 94 insertions, 2 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog index 681ba94c..c72c2384 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,13 @@ +2008-03-31 Roland McGrath <roland@redhat.com> + + * sparc_symbol.c (sparc_symbol_type_name): New function. + (sparc_dynamic_tag_name): New function. + (sparc_dynamic_tag_check): New function. + * sparc_init.c (sparc_init): Initialize those hooks. + + * sparc_symbol.c (sparc_check_special_section): New function. + * sparc_init.c (sparc_init): Initialize check_special_section hook. + 2008-02-20 Roland McGrath <roland@redhat.com> * ppc_attrs.c: New file. diff --git a/backends/sparc_init.c b/backends/sparc_init.c index 8da845e2..856bd48c 100644 --- a/backends/sparc_init.c +++ b/backends/sparc_init.c @@ -1,5 +1,5 @@ /* Initialization of SPARC specific backend library. - Copyright (C) 2002, 2005, 2006, 2007 Red Hat, Inc. + Copyright (C) 2002, 2005, 2006, 2007, 2008 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -57,6 +57,10 @@ sparc_init (elf, machine, eh, ehlen) sparc_init_reloc (eh); HOOK (eh, reloc_simple_type); HOOK (eh, machine_flag_check); + HOOK (eh, check_special_section); + HOOK (eh, symbol_type_name); + HOOK (eh, dynamic_tag_name); + HOOK (eh, dynamic_tag_check); if (eh->class == ELFCLASS64) eh->core_note = sparc64_core_note; else diff --git a/backends/sparc_symbol.c b/backends/sparc_symbol.c index 237620c9..27de54c0 100644 --- a/backends/sparc_symbol.c +++ b/backends/sparc_symbol.c @@ -1,5 +1,5 @@ /* SPARC specific symbolic name handling. - Copyright (C) 2002, 2003, 2005, 2007 Red Hat, Inc. + Copyright (C) 2002, 2003, 2005, 2007, 2008 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Jakub Jelinek <jakub@redhat.com>, 2002. @@ -66,3 +66,81 @@ sparc_machine_flag_check (GElf_Word flags) | EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3)) == 0); } + +bool +sparc_check_special_section (Ebl *ebl, + int ndx __attribute__ ((unused)), + const GElf_Shdr *shdr, + const char *sname __attribute__ ((unused))) +{ + ebl=ebl; + if ((shdr->sh_flags & (SHF_WRITE | SHF_EXECINSTR)) + == (SHF_WRITE | SHF_EXECINSTR)) + { + /* This is ordinarily flagged, but is valid for a PLT on SPARC. + + Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it. + Its d_ptr should match the .plt section's sh_addr. */ + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr scn_shdr; + if (likely (gelf_getshdr (scn, &scn_shdr) != NULL) + && scn_shdr.sh_type == SHT_DYNAMIC + && scn_shdr.sh_entsize != 0) + { + Elf_Data *data = elf_getdata (scn, NULL); + if (data != NULL) + for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i) + { + GElf_Dyn dyn; + if (unlikely (gelf_getdyn (data, i, &dyn) == NULL)) + break; + if (dyn.d_tag == DT_PLTGOT) + return dyn.d_un.d_ptr == shdr->sh_addr; + } + break; + } + } + } + + return false; +} + +const char * +sparc_symbol_type_name (int type, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (type) + { + case STT_SPARC_REGISTER: + return "SPARC_REGISTER"; + } + return NULL; +} + +const char * +sparc_dynamic_tag_name (int64_t tag, + char *buf __attribute__ ((unused)), + size_t len __attribute__ ((unused))) +{ + switch (tag) + { + case DT_SPARC_REGISTER: + return "SPARC_REGISTER"; + } + return NULL; +} + +bool +sparc_dynamic_tag_check (int64_t tag) +{ + switch (tag) + { + case DT_SPARC_REGISTER: + return true; + } + return false; +} |