X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-score.c;h=7b16ea2d15a507cfe7db6893aa45f86974142840;hb=95830fd17d6ae253d8f6c2595188cadd59058799;hp=d5e21b5383d5ecfbe90a5aa9cb7916a6bedd6f9f;hpb=c3b7224ae49a815ca1e60d058acc980530832881;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c index d5e21b5383..7b16ea2d15 100644 --- a/bfd/elf32-score.c +++ b/bfd/elf32-score.c @@ -1,5 +1,6 @@ /* 32-bit ELF support for S+core. - Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 + Free Software Foundation, Inc. Contributed by Brain.lin (brain.lin@sunplusct.com) Mei Ligang (ligang@sunnorth.com.cn) @@ -37,13 +38,6 @@ int score3 = 0; int score7 = 1; -/* Score ELF linker hash table. */ -struct score_elf_link_hash_table -{ - /* The main hash table. */ - struct elf_link_hash_table root; -}; - /* The SCORE ELF linker needs additional information for each symbol in the global hash table. */ struct score_elf_link_hash_entry @@ -68,14 +62,10 @@ struct score_elf_link_hash_entry /* Traverse a score ELF linker hash table. */ #define score_elf_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ - (&(table)->root, \ + ((table), \ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) -/* Get the SCORE elf linker hash table from a link_info structure. */ -#define score_elf_hash_table(info) \ - ((struct score_elf_link_hash_table *) ((info)->hash)) - /* This structure is used to hold .got entries while estimating got sizes. */ struct score_got_entry { @@ -1048,9 +1038,6 @@ score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data) { struct score_elf_hash_sort_data *hsd = data; - if (h->root.root.type == bfd_link_hash_warning) - h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link; - /* Symbols without dynamic symbol table entries aren't interesting at all. */ if (h->root.dynindx == -1) return TRUE; @@ -1079,7 +1066,7 @@ score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data) static asection * score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded) { - asection *sgot = bfd_get_section_by_name (abfd, ".got"); + asection *sgot = bfd_get_linker_section (abfd, ".got"); if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0)) return NULL; @@ -1135,10 +1122,9 @@ score_elf_sort_hash_table (struct bfd_link_info *info, too large offsets. */ - (g->next ? g->assigned_gotno : 0); hsd.max_non_got_dynindx = max_local; - score_elf_link_hash_traverse (((struct score_elf_link_hash_table *) - elf_hash_table (info)), - score_elf_sort_hash_table_f, - &hsd); + score_elf_link_hash_traverse (elf_hash_table (info), + score_elf_sort_hash_table_f, + &hsd); /* There should have been enough room in the symbol table to accommodate both the GOT and non-GOT symbols. */ @@ -1154,22 +1140,23 @@ score_elf_sort_hash_table (struct bfd_link_info *info, } /* Create an entry in an score ELF linker hash table. */ + static struct bfd_hash_entry * score_elf_link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string) { - struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *)entry; + struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry; /* Allocate the structure if it has not already been allocated by a subclass. */ if (ret == NULL) ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry)); if (ret == NULL) - return (struct bfd_hash_entry *)ret; + return (struct bfd_hash_entry *) ret; /* Call the allocation method of the superclass. */ ret = ((struct score_elf_link_hash_entry *) - _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *)ret, table, string)); + _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); if (ret != NULL) { @@ -1179,7 +1166,7 @@ score_elf_link_hash_newfunc (struct bfd_hash_entry *entry, ret->forced_local = FALSE; } - return (struct bfd_hash_entry *)ret; + return (struct bfd_hash_entry *) ret; } /* Returns the first relocation of type r_type found, beginning with @@ -1260,16 +1247,16 @@ score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p) static const char dname[] = ".rel.dyn"; asection *sreloc; - sreloc = bfd_get_section_by_name (dynobj, dname); + sreloc = bfd_get_linker_section (dynobj, dname); if (sreloc == NULL && create_p) { - sreloc = bfd_make_section_with_flags (dynobj, dname, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)); + sreloc = bfd_make_section_anyway_with_flags (dynobj, dname, + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED + | SEC_READONLY)); if (sreloc == NULL || ! bfd_set_section_alignment (dynobj, sreloc, SCORE_ELF_LOG_FILE_ALIGN (dynobj))) @@ -1442,7 +1429,7 @@ score_elf_create_got_section (bfd *abfd, /* We have to use an alignment of 2**4 here because this is hardcoded in the function stub generation and in the linker script. */ - s = bfd_make_section_with_flags (abfd, ".got", flags); + s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4)) return FALSE; @@ -1755,7 +1742,7 @@ score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, static bfd_vma score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h) { - bfd_vma index; + bfd_vma got_index; asection *sgot; struct score_got_info *g; long global_got_dynindx = 0; @@ -1769,25 +1756,27 @@ score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h) indices into the GOT. That makes it easy to calculate the GOT offset. */ BFD_ASSERT (h->dynindx >= global_got_dynindx); - index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd)); - BFD_ASSERT (index < sgot->size); + got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd)); + BFD_ASSERT (got_index < sgot->size); - return index; + return got_index; } /* Returns the offset for the entry at the INDEXth position in the GOT. */ + static bfd_vma -score_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd, - bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma index) +score_elf_got_offset_from_index (bfd *dynobj, + bfd *output_bfd, + bfd *input_bfd ATTRIBUTE_UNUSED, + bfd_vma got_index) { asection *sgot; bfd_vma gp; - struct score_got_info *g; - g = score_elf_got_info (dynobj, &sgot); + score_elf_got_info (dynobj, &sgot); gp = _bfd_get_gp_value (output_bfd); - return sgot->output_section->vma + sgot->output_offset + index - gp; + return sgot->output_section->vma + sgot->output_offset + got_index - gp; } /* Follow indirect and warning hash entries so that each got entry @@ -1995,8 +1984,6 @@ score_elf_final_link_relocate (reloc_howto_type *howto, bfd_vma gp = MINUS_ONE; /* The place (section offset or address) of the storage unit being relocated. */ bfd_vma rel_addr; - /* The value of GP used to create the relocatable object. */ - bfd_vma gp0 = MINUS_ONE; /* The offset into the global offset table at which the address of the relocation entry symbol, adjusted by the addend, resides during execution. */ bfd_vma g = MINUS_ONE; @@ -2080,7 +2067,7 @@ score_elf_final_link_relocate (reloc_howto_type *howto, { g = score_elf_global_got_index (elf_hash_table (info)->dynobj, (struct elf_link_hash_entry *) h); - if ((! elf_hash_table(info)->dynamic_sections_created + if ((! elf_hash_table (info)->dynamic_sections_created || (info->shared && (info->symbolic || h->root.dynindx == -1) && h->root.def_regular))) @@ -2115,7 +2102,6 @@ score_elf_final_link_relocate (reloc_howto_type *howto, case R_SCORE_HI16: case R_SCORE_LO16: case R_SCORE_GPREL32: - gp0 = _bfd_get_gp_value (input_bfd); gp = _bfd_get_gp_value (output_bfd); break; @@ -2138,7 +2124,7 @@ score_elf_final_link_relocate (reloc_howto_type *howto, && h != NULL && h->root.def_dynamic && !h->root.def_regular)) - && r_symndx != 0 + && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) != 0) { /* If we're creating a shared library, or this relocation is against a symbol @@ -2151,8 +2137,8 @@ score_elf_final_link_relocate (reloc_howto_type *howto, input_section)) return bfd_reloc_undefined; } - else if (r_symndx == 0) - /* r_symndx will be zero only for relocs against symbols + else if (r_symndx == STN_UNDEF) + /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols from removed linkonce sections, or sections discarded by a linker script. */ value = 0; @@ -2416,7 +2402,6 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd, asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; const char *name; @@ -2447,7 +2432,6 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd, symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info; - sym_hashes = elf_sym_hashes (input_bfd); rel = relocs; relend = relocs + input_section->reloc_count; for (; rel < relend; rel++) @@ -2688,16 +2672,9 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd, } } - if (sec != NULL && elf_discarded_section (sec)) - { - /* For relocs against symbols from removed linkonce sections, - or sections discarded by a linker script, we just want the - section contents zeroed. Avoid any special processing. */ - _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); - rel->r_info = 0; - rel->r_addend = 0; - continue; - } + if (sec != NULL && discarded_section (sec)) + RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, + rel, 1, relend, howto, 0, contents); if (info->relocatable) { @@ -3068,7 +3045,7 @@ s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym) } } -static bfd_boolean +static int s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym, @@ -3081,7 +3058,7 @@ s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_U if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0) sym->st_shndx = SHN_SCORE_SCOMMON; - return TRUE; + return 1; } static bfd_boolean @@ -3146,7 +3123,7 @@ s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info, if (!h->def_regular) { /* We need .stub section. */ - s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME); + s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); BFD_ASSERT (s != NULL); h->root.u.def.section = s; @@ -3282,7 +3259,7 @@ s3_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i /* Set the contents of the .interp section to the interpreter. */ if (!info->shared) { - s = bfd_get_section_by_name (dynobj, ".interp"); + s = bfd_get_linker_section (dynobj, ".interp"); BFD_ASSERT (s != NULL); s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER; @@ -3440,7 +3417,7 @@ s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) | SEC_LINKER_CREATED | SEC_READONLY); /* ABI requests the .dynamic section to be read only. */ - s = bfd_get_section_by_name (abfd, ".dynamic"); + s = bfd_get_linker_section (abfd, ".dynamic"); if (s != NULL) { if (!bfd_set_section_flags (abfd, s, flags)) @@ -3455,10 +3432,10 @@ s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) return FALSE; /* Create .stub section. */ - if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL) + if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL) { - s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME, - flags | SEC_CODE); + s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME, + flags | SEC_CODE); if (s == NULL || !bfd_set_section_alignment (abfd, s, 2)) @@ -3512,7 +3489,7 @@ s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd, /* This symbol has a stub. Set it up. */ BFD_ASSERT (h->dynindx != -1); - s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME); + s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); BFD_ASSERT (s != NULL); /* FIXME: Can h->dynindex be more than 64K? */ @@ -3560,7 +3537,8 @@ s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd, /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ name = h->root.root.string; - if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + if (h == elf_hash_table (info)->hdynamic + || h == elf_hash_table (info)->hgot) sym->st_shndx = SHN_ABS; else if (strcmp (name, "_DYNAMIC_LINK") == 0) { @@ -3591,7 +3569,7 @@ s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd, dynobj = elf_hash_table (info)->dynobj; - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + sdyn = bfd_get_linker_section (dynobj, ".dynamic"); sgot = score_elf_got_section (dynobj, FALSE); if (sgot == NULL) @@ -3931,7 +3909,7 @@ s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) elf_tdata (abfd)->core_signal = score_bfd_get_16 (abfd, note->descdata + 12); /* pr_pid */ - elf_tdata (abfd)->core_pid = score_bfd_get_32 (abfd, note->descdata + 24); + elf_tdata (abfd)->core_lwpid = score_bfd_get_32 (abfd, note->descdata + 24); /* pr_reg */ offset = 72; @@ -4003,28 +3981,6 @@ elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, return NULL; } -/* Create a score elf linker hash table. */ - -static struct bfd_link_hash_table * -s3_elf32_score_link_hash_table_create (bfd *abfd) -{ - struct score_elf_link_hash_table *ret; - bfd_size_type amt = sizeof (struct score_elf_link_hash_table); - - ret = bfd_malloc (amt); - if (ret == NULL) - return NULL; - - if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc, - sizeof (struct score_elf_link_hash_entry))) - { - free (ret); - return NULL; - } - - return &ret->root.root; -} - static bfd_boolean s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr) { @@ -4179,7 +4135,7 @@ _bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym) return s7_bfd_score_elf_symbol_processing (abfd, asym); } -static bfd_boolean +static int _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym, @@ -4194,7 +4150,7 @@ _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNU common in the output file. */ if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0) sym->st_shndx = SHN_SCORE_SCOMMON; - return TRUE; + return 1; } if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) @@ -4391,13 +4347,29 @@ elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_t return s7_elf32_score_reloc_type_lookup (abfd, code); } +/* Create a score elf linker hash table. + This is a copy of _bfd_elf_link_hash_table_create() except with a + different hash table entry creation function. */ + static struct bfd_link_hash_table * elf32_score_link_hash_table_create (bfd *abfd) { - if (bfd_get_mach (abfd) == bfd_mach_score3) - return s3_elf32_score_link_hash_table_create (abfd); - else - return s7_elf32_score_link_hash_table_create (abfd); + struct elf_link_hash_table *ret; + bfd_size_type amt = sizeof (struct elf_link_hash_table); + + ret = (struct elf_link_hash_table *) bfd_malloc (amt); + if (ret == NULL) + return NULL; + + if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc, + sizeof (struct score_elf_link_hash_entry), + GENERIC_ELF_DATA)) + { + free (ret); + return NULL; + } + + return &ret->root; } static bfd_boolean