X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=bfd%2Felf-vxworks.c;fp=bfd%2Felf-vxworks.c;h=06edf8dce61def3f9ce6f5384f297fa8cdea3630;hp=98d2dfca98d4779608a281654e3c1ffed6145b94;hb=d5da4f291af551c0b8b79e1d4a9b173d60e5c10e;hpb=7b5ea4fcdf2819e070665ab5610f8b48e3867c10 diff --git a/bfd/elf-vxworks.c b/bfd/elf-vxworks.c index 98d2dfc..06edf8d 100644 --- a/bfd/elf-vxworks.c +++ b/bfd/elf-vxworks.c @@ -1,5 +1,5 @@ /* VxWorks support for ELF - Copyright 2005, 2007 Free Software Foundation, Inc. + Copyright 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -25,6 +25,7 @@ #include "libbfd.h" #include "elf-bfd.h" #include "elf-vxworks.h" +#include "elf/vxworks.h" /* Return true if symbol NAME, as defined by ABFD, is one of the special __GOTT_BASE__ or __GOTT_INDEX__ symbols. */ @@ -126,7 +127,7 @@ elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info, } /* Tweak magic VxWorks symbols as they are written to the output file. */ -bfd_boolean +int elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *name, @@ -140,11 +141,10 @@ elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info && elf_vxworks_gott_symbol_p (h->root.u.undef.abfd, name)) sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info)); - return TRUE; + return 1; } - -/* Copy relocations into the output file. Fixes up relocations againt PLT +/* Copy relocations into the output file. Fixes up relocations against PLT entries, then calls the generic routine. */ bfd_boolean @@ -155,49 +155,55 @@ elf_vxworks_emit_relocs (bfd *output_bfd, struct elf_link_hash_entry **rel_hash) { const struct elf_backend_data *bed; - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; int j; bed = get_elf_backend_data (output_bfd); - irela = internal_relocs; - irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) - * bed->s->int_rels_per_ext_rel); - while (irela < irelaend) + if (output_bfd->flags & (DYNAMIC|EXEC_P)) { - if ((output_bfd->flags & (DYNAMIC|EXEC_P)) - && *rel_hash - && (*rel_hash)->def_dynamic - && !(*rel_hash)->def_regular - && ((*rel_hash)->root.type == bfd_link_hash_defined - || (*rel_hash)->root.type == bfd_link_hash_defweak) - && (*rel_hash)->root.u.def.section->output_section != NULL) + Elf_Internal_Rela *irela; + Elf_Internal_Rela *irelaend; + struct elf_link_hash_entry **hash_ptr; + + for (irela = internal_relocs, + irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) + * bed->s->int_rels_per_ext_rel), + hash_ptr = rel_hash; + irela < irelaend; + irela += bed->s->int_rels_per_ext_rel, + hash_ptr++) { - /* This is a relocation from an executable or shared library - against a symbol in a different shared library. We are - creating a definition in the output file but it does not come - from any of our normal (.o) files. ie. a PLT stub. - Normally this would be a relocation against against SHN_UNDEF - with the VMA of the PLT stub. This upsets the VxWorks loader. - Convert it to a section-relative relocation. - This gets some other symbols (for instance .dynbss), - but is conservatively correct. */ - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) + if (*hash_ptr + && (*hash_ptr)->def_dynamic + && !(*hash_ptr)->def_regular + && ((*hash_ptr)->root.type == bfd_link_hash_defined + || (*hash_ptr)->root.type == bfd_link_hash_defweak) + && (*hash_ptr)->root.u.def.section->output_section != NULL) { - asection *sec = (*rel_hash)->root.u.def.section; - int this_idx = sec->output_section->target_index; - - irela[j].r_info = ELF32_R_INFO (this_idx, - ELF32_R_TYPE (irela[j].r_info)); - irela[j].r_addend += (*rel_hash)->root.u.def.value; - irela[j].r_addend += sec->output_offset; + /* This is a relocation from an executable or shared + library against a symbol in a different shared + library. We are creating a definition in the output + file but it does not come from any of our normal (.o) + files. ie. a PLT stub. Normally this would be a + relocation against against SHN_UNDEF with the VMA of + the PLT stub. This upsets the VxWorks loader. + Convert it to a section-relative relocation. This + gets some other symbols (for instance .dynbss), but + is conservatively correct. */ + for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) + { + asection *sec = (*hash_ptr)->root.u.def.section; + int this_idx = sec->output_section->target_index; + + irela[j].r_info + = ELF32_R_INFO (this_idx, ELF32_R_TYPE (irela[j].r_info)); + irela[j].r_addend += (*hash_ptr)->root.u.def.value; + irela[j].r_addend += sec->output_offset; + } + /* Stop the generic routine adjusting this entry. */ + *hash_ptr = NULL; } - /* Stop the generic routine adjusting this entry. */ - *rel_hash = NULL; } - irela += bed->s->int_rels_per_ext_rel; - rel_hash++; } return _bfd_elf_link_output_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs, @@ -225,3 +231,69 @@ elf_vxworks_final_write_processing (bfd *abfd, if (sec) d->this_hdr.sh_info = elf_section_data (sec)->this_idx; } + +/* Add the dynamic entries required by VxWorks. These point to the + tls sections. */ + +bfd_boolean +elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info) +{ + if (bfd_get_section_by_name (output_bfd, ".tls_data")) + { + if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0)) + return FALSE; + } + if (bfd_get_section_by_name (output_bfd, ".tls_vars")) + { + if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0) + || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0)) + return FALSE; + } + return TRUE; +} + +/* If *DYN is one of the VxWorks-specific dynamic entries, then fill + in the value now and return TRUE. Otherwise return FALSE. */ + +bfd_boolean +elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn) +{ + asection *sec; + + switch (dyn->d_tag) + { + default: + return FALSE; + + case DT_VX_WRS_TLS_DATA_START: + sec = bfd_get_section_by_name (output_bfd, ".tls_data"); + dyn->d_un.d_ptr = sec->vma; + break; + + case DT_VX_WRS_TLS_DATA_SIZE: + sec = bfd_get_section_by_name (output_bfd, ".tls_data"); + dyn->d_un.d_val = sec->size; + break; + + case DT_VX_WRS_TLS_DATA_ALIGN: + sec = bfd_get_section_by_name (output_bfd, ".tls_data"); + dyn->d_un.d_val + = (bfd_size_type)1 << bfd_get_section_alignment (abfd, sec); + break; + + case DT_VX_WRS_TLS_VARS_START: + sec = bfd_get_section_by_name (output_bfd, ".tls_vars"); + dyn->d_un.d_ptr = sec->vma; + break; + + case DT_VX_WRS_TLS_VARS_SIZE: + sec = bfd_get_section_by_name (output_bfd, ".tls_vars"); + dyn->d_un.d_val = sec->size; + break; + } + return TRUE; +} + +