]>
Commit | Line | Data |
---|---|---|
eac338cf PB |
1 | /* VxWorks support for ELF |
2 | Copyright 2005 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of BFD, the Binary File Descriptor library. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | */ | |
20 | ||
21 | /* This file provides routines used by all VxWorks targets. */ | |
22 | ||
23 | #include "bfd.h" | |
24 | #include "sysdep.h" | |
25 | #include "libbfd.h" | |
26 | #include "elf-bfd.h" | |
27 | #include "elf-vxworks.h" | |
28 | ||
29 | /* Tweak magic VxWorks symbols as they are loaded. */ | |
30 | bfd_boolean | |
31 | elf_vxworks_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED, | |
32 | struct bfd_link_info *info, | |
33 | Elf_Internal_Sym *sym, | |
34 | const char **namep, | |
35 | flagword *flagsp, | |
36 | asection **secp ATTRIBUTE_UNUSED, | |
37 | bfd_vma *valp ATTRIBUTE_UNUSED) | |
38 | { | |
39 | /* Ideally these "magic" symbols would be exported by libc.so.1 | |
40 | which would be found via a DT_NEEDED tag, and then handled | |
41 | specially by the linker at runtime. Except shared libraries | |
42 | don't even link to libc.so.1 by default... | |
43 | If the symbol is imported from, or will be put in a shared library, | |
44 | give the symbol weak binding to get the desired samantics. | |
45 | This transformation will be undone in | |
46 | elf_i386_vxworks_link_output_symbol_hook. */ | |
47 | if ((info->shared || abfd->flags & DYNAMIC) | |
48 | && (strcmp (*namep, "__GOTT_INDEX__") == 0 | |
49 | || strcmp (*namep, "__GOTT_BASE__") == 0)) | |
50 | { | |
51 | sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info)); | |
52 | *flagsp |= BSF_WEAK; | |
53 | } | |
54 | ||
55 | return TRUE; | |
56 | } | |
57 | ||
58 | ||
59 | /* Tweak magic VxWorks symbols as they are written to the output file. */ | |
60 | bfd_boolean | |
9c72ff84 RS |
61 | elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info |
62 | ATTRIBUTE_UNUSED, | |
63 | const char *name, | |
64 | Elf_Internal_Sym *sym, | |
65 | asection *input_sec ATTRIBUTE_UNUSED, | |
66 | struct elf_link_hash_entry *h | |
67 | ATTRIBUTE_UNUSED) | |
eac338cf | 68 | { |
9c72ff84 RS |
69 | /* Ignore the first dummy symbol. */ |
70 | if (!name) | |
71 | return TRUE; | |
72 | ||
eac338cf PB |
73 | /* Reverse the effects of the hack in elf_vxworks_add_symbol_hook. */ |
74 | if (strcmp (name, "__GOTT_INDEX__") == 0 | |
75 | || strcmp (name, "__GOTT_BASE__") == 0) | |
76 | sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info)); | |
77 | ||
78 | return TRUE; | |
79 | } | |
80 | ||
81 | ||
82 | /* Copy relocations into the output file. Fixes up relocations againt PLT | |
83 | entries, then calls the generic routine. */ | |
84 | ||
85 | bfd_boolean | |
86 | elf_vxworks_emit_relocs (bfd *output_bfd, | |
87 | asection *input_section, | |
88 | Elf_Internal_Shdr *input_rel_hdr, | |
89 | Elf_Internal_Rela *internal_relocs, | |
90 | struct elf_link_hash_entry **rel_hash) | |
91 | { | |
92 | const struct elf_backend_data *bed; | |
93 | Elf_Internal_Rela *irela; | |
94 | Elf_Internal_Rela *irelaend; | |
95 | int j; | |
96 | ||
97 | bed = get_elf_backend_data (output_bfd); | |
98 | ||
99 | irela = internal_relocs; | |
100 | irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) | |
101 | * bed->s->int_rels_per_ext_rel); | |
102 | while (irela < irelaend) | |
103 | { | |
104 | if ((output_bfd->flags & (DYNAMIC|EXEC_P)) | |
105 | && *rel_hash | |
106 | && (*rel_hash)->def_dynamic | |
107 | && !(*rel_hash)->def_regular | |
108 | && (*rel_hash)->root.type == bfd_link_hash_defined | |
109 | && (*rel_hash)->root.u.def.section->output_section != NULL) | |
110 | { | |
111 | /* This is a relocation from an executable or shared library | |
112 | against a symbol in a different shared library. We are | |
113 | creating a definition in the output file but it does not come | |
114 | from any of our normal (.o) files. ie. a PLT stub. | |
115 | Normally this would be a relocation against against SHN_UNDEF | |
116 | with the VMA of the PLT stub. This upsets the VxWorks loader. | |
117 | Convert it to a section-relative relocation. | |
118 | This gets some other symbols (for instance .dynbss), | |
119 | but is conservatively correct. */ | |
120 | for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) | |
121 | { | |
122 | asection *sec = (*rel_hash)->root.u.def.section; | |
123 | int this_idx = | |
124 | elf_section_data (sec->output_section)->this_idx; | |
125 | ||
126 | irela[j].r_info = ELF32_R_INFO (this_idx, | |
127 | ELF32_R_TYPE (irela[j].r_info)); | |
128 | irela[j].r_addend += (*rel_hash)->root.u.def.value; | |
129 | irela[j].r_addend += sec->output_offset; | |
130 | } | |
131 | /* Stop the generic routine adjusting this entry. */ | |
132 | *rel_hash = NULL; | |
133 | } | |
134 | irela += bed->s->int_rels_per_ext_rel; | |
135 | rel_hash++; | |
136 | } | |
137 | return _bfd_elf_link_output_relocs (output_bfd, input_section, | |
138 | input_rel_hdr, internal_relocs, | |
139 | rel_hash); | |
140 | } | |
141 | ||
142 | ||
143 | /* Set the sh_link and sh_info fields on the static plt relocation secton. */ | |
144 | ||
145 | void | |
146 | elf_vxworks_final_write_processing (bfd *abfd, | |
147 | bfd_boolean linker ATTRIBUTE_UNUSED) | |
148 | { | |
149 | asection * sec; | |
150 | struct bfd_elf_section_data *d; | |
151 | ||
152 | sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded"); | |
9d8504b1 PB |
153 | if (!sec) |
154 | sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded"); | |
eac338cf PB |
155 | if (!sec) |
156 | return; | |
157 | d = elf_section_data (sec); | |
158 | d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section; | |
159 | sec = bfd_get_section_by_name (abfd, ".plt"); | |
160 | if (sec) | |
161 | d->this_hdr.sh_info = elf_section_data (sec)->this_idx; | |
162 | } |