OLD | NEW |
1 /* 32-bit ELF support for S+core. | 1 /* 32-bit ELF support for S+core. |
2 Copyright 2009, 2010, 2011 Free Software Foundation, Inc. | 2 Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc. |
3 Contributed by | 3 Contributed by |
4 Brain.lin (brain.lin@sunplusct.com) | 4 Brain.lin (brain.lin@sunplusct.com) |
5 Mei Ligang (ligang@sunnorth.com.cn) | 5 Mei Ligang (ligang@sunnorth.com.cn) |
6 Pei-Lin Tsai (pltsai@sunplus.com) | 6 Pei-Lin Tsai (pltsai@sunplus.com) |
7 | 7 |
8 This file is part of BFD, the Binary File Descriptor library. | 8 This file is part of BFD, the Binary File Descriptor library. |
9 | 9 |
10 This program is free software; you can redistribute it and/or modify | 10 This program is free software; you can redistribute it and/or modify |
11 it under the terms of the GNU General Public License as published by | 11 it under the terms of the GNU General Public License as published by |
12 the Free Software Foundation; either version 3 of the License, or | 12 the Free Software Foundation; either version 3 of the License, or |
13 (at your option) any later version. | 13 (at your option) any later version. |
14 | 14 |
15 This program is distributed in the hope that it will be useful, | 15 This program is distributed in the hope that it will be useful, |
16 but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 GNU General Public License for more details. | 18 GNU General Public License for more details. |
19 | 19 |
20 You should have received a copy of the GNU General Public License | 20 You should have received a copy of the GNU General Public License |
21 along with this program; if not, write to the Free Software | 21 along with this program; if not, write to the Free Software |
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
23 MA 02110-1301, USA. */ | 23 MA 02110-1301, USA. */ |
24 | 24 |
| 25 #include "sysdep.h" |
25 #include "bfd.h" | 26 #include "bfd.h" |
26 #include "sysdep.h" | |
27 #include "libbfd.h" | 27 #include "libbfd.h" |
28 #include "libiberty.h" | 28 #include "libiberty.h" |
29 #include "elf-bfd.h" | 29 #include "elf-bfd.h" |
30 #include "elf/score.h" | 30 #include "elf/score.h" |
31 #include "elf/common.h" | 31 #include "elf/common.h" |
32 #include "elf/internal.h" | 32 #include "elf/internal.h" |
33 #include "hashtab.h" | 33 #include "hashtab.h" |
34 #include "elf32-score.h" | 34 #include "elf32-score.h" |
35 | 35 |
36 | 36 |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 h->root.dynindx = --hsd->min_got_dynindx; | 941 h->root.dynindx = --hsd->min_got_dynindx; |
942 hsd->low = (struct elf_link_hash_entry *) h; | 942 hsd->low = (struct elf_link_hash_entry *) h; |
943 } | 943 } |
944 | 944 |
945 return TRUE; | 945 return TRUE; |
946 } | 946 } |
947 | 947 |
948 static asection * | 948 static asection * |
949 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded) | 949 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded) |
950 { | 950 { |
951 asection *sgot = bfd_get_section_by_name (abfd, ".got"); | 951 asection *sgot = bfd_get_linker_section (abfd, ".got"); |
952 | 952 |
953 if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0)) | 953 if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0)) |
954 return NULL; | 954 return NULL; |
955 return sgot; | 955 return sgot; |
956 } | 956 } |
957 | 957 |
958 /* Returns the GOT information associated with the link indicated by | 958 /* Returns the GOT information associated with the link indicated by |
959 INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */ | 959 INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */ |
960 | 960 |
961 static struct score_got_info * | 961 static struct score_got_info * |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 } | 1096 } |
1097 | 1097 |
1098 /* Returns the dynamic relocation section for DYNOBJ. */ | 1098 /* Returns the dynamic relocation section for DYNOBJ. */ |
1099 | 1099 |
1100 static asection * | 1100 static asection * |
1101 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p) | 1101 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p) |
1102 { | 1102 { |
1103 static const char dname[] = ".rel.dyn"; | 1103 static const char dname[] = ".rel.dyn"; |
1104 asection *sreloc; | 1104 asection *sreloc; |
1105 | 1105 |
1106 sreloc = bfd_get_section_by_name (dynobj, dname); | 1106 sreloc = bfd_get_linker_section (dynobj, dname); |
1107 if (sreloc == NULL && create_p) | 1107 if (sreloc == NULL && create_p) |
1108 { | 1108 { |
1109 sreloc = bfd_make_section_with_flags (dynobj, dname, | 1109 sreloc = bfd_make_section_anyway_with_flags (dynobj, dname, |
1110 (SEC_ALLOC | 1110 » » » » » » (SEC_ALLOC |
1111 | SEC_LOAD | 1111 » » » » » » | SEC_LOAD |
1112 | SEC_HAS_CONTENTS | 1112 » » » » » » | SEC_HAS_CONTENTS |
1113 | SEC_IN_MEMORY | 1113 » » » » » » | SEC_IN_MEMORY |
1114 | SEC_LINKER_CREATED | 1114 » » » » » » | SEC_LINKER_CREATED |
1115 | SEC_READONLY)); | 1115 » » » » » » | SEC_READONLY)); |
1116 if (sreloc == NULL | 1116 if (sreloc == NULL |
1117 || ! bfd_set_section_alignment (dynobj, sreloc, | 1117 || ! bfd_set_section_alignment (dynobj, sreloc, |
1118 SCORE_ELF_LOG_FILE_ALIGN (dynobj))) | 1118 SCORE_ELF_LOG_FILE_ALIGN (dynobj))) |
1119 return NULL; | 1119 return NULL; |
1120 } | 1120 } |
1121 return sreloc; | 1121 return sreloc; |
1122 } | 1122 } |
1123 | 1123 |
1124 static void | 1124 static void |
1125 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n) | 1125 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n) |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 return TRUE; | 1279 return TRUE; |
1280 } | 1280 } |
1281 | 1281 |
1282 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_
CREATED); | 1282 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_
CREATED); |
1283 | 1283 |
1284 if (maybe_exclude) | 1284 if (maybe_exclude) |
1285 flags |= SEC_EXCLUDE; | 1285 flags |= SEC_EXCLUDE; |
1286 | 1286 |
1287 /* We have to use an alignment of 2**4 here because this is hardcoded | 1287 /* We have to use an alignment of 2**4 here because this is hardcoded |
1288 in the function stub generation and in the linker script. */ | 1288 in the function stub generation and in the linker script. */ |
1289 s = bfd_make_section_with_flags (abfd, ".got", flags); | 1289 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); |
1290 if (s == NULL | 1290 if (s == NULL |
1291 || ! bfd_set_section_alignment (abfd, s, 4)) | 1291 || ! bfd_set_section_alignment (abfd, s, 4)) |
1292 return FALSE; | 1292 return FALSE; |
1293 | 1293 |
1294 /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the | 1294 /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the |
1295 linker script because we don't want to define the symbol if we | 1295 linker script because we don't want to define the symbol if we |
1296 are not creating a global offset table. */ | 1296 are not creating a global offset table. */ |
1297 bh = NULL; | 1297 bh = NULL; |
1298 if (! (_bfd_generic_link_add_one_symbol | 1298 if (! (_bfd_generic_link_add_one_symbol |
1299 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, | 1299 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2436 if (! ((*info->callbacks->undefined_symbol) | 2436 if (! ((*info->callbacks->undefined_symbol) |
2437 (info, h->root.root.root.string, input_bfd, | 2437 (info, h->root.root.root.string, input_bfd, |
2438 input_section, rel->r_offset, | 2438 input_section, rel->r_offset, |
2439 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR) | 2439 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR) |
2440 || ELF_ST_VISIBILITY (h->root.other)))) | 2440 || ELF_ST_VISIBILITY (h->root.other)))) |
2441 return bfd_reloc_undefined; | 2441 return bfd_reloc_undefined; |
2442 relocation = 0; | 2442 relocation = 0; |
2443 } | 2443 } |
2444 } | 2444 } |
2445 | 2445 |
2446 if (sec != NULL && elf_discarded_section (sec)) | 2446 if (sec != NULL && discarded_section (sec)) |
2447 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, | 2447 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
2448 » » » » » rel, relend, howto, contents); | 2448 » » » » » rel, 1, relend, howto, 0, contents); |
2449 | 2449 |
2450 if (info->relocatable) | 2450 if (info->relocatable) |
2451 { | 2451 { |
2452 /* This is a relocatable link. We don't have to change | 2452 /* This is a relocatable link. We don't have to change |
2453 anything, unless the reloc is against a section symbol, | 2453 anything, unless the reloc is against a section symbol, |
2454 in which case we have to adjust according to where the | 2454 in which case we have to adjust according to where the |
2455 section symbol winds up in the output section. */ | 2455 section symbol winds up in the output section. */ |
2456 if (r_symndx < symtab_hdr->sh_info) | 2456 if (r_symndx < symtab_hdr->sh_info) |
2457 { | 2457 { |
2458 sym = local_syms + r_symndx; | 2458 sym = local_syms + r_symndx; |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2921 if (!elf_hash_table (info)->dynamic_sections_created) | 2921 if (!elf_hash_table (info)->dynamic_sections_created) |
2922 return TRUE; | 2922 return TRUE; |
2923 | 2923 |
2924 /* If this symbol is not defined in a regular file, then set | 2924 /* If this symbol is not defined in a regular file, then set |
2925 the symbol to the stub location. This is required to make | 2925 the symbol to the stub location. This is required to make |
2926 function pointers compare as equal between the normal | 2926 function pointers compare as equal between the normal |
2927 executable and the shared library. */ | 2927 executable and the shared library. */ |
2928 if (!h->def_regular) | 2928 if (!h->def_regular) |
2929 { | 2929 { |
2930 /* We need .stub section. */ | 2930 /* We need .stub section. */ |
2931 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME); | 2931 s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); |
2932 BFD_ASSERT (s != NULL); | 2932 BFD_ASSERT (s != NULL); |
2933 | 2933 |
2934 h->root.u.def.section = s; | 2934 h->root.u.def.section = s; |
2935 h->root.u.def.value = s->size; | 2935 h->root.u.def.value = s->size; |
2936 | 2936 |
2937 /* XXX Write this stub address somewhere. */ | 2937 /* XXX Write this stub address somewhere. */ |
2938 h->plt.offset = s->size; | 2938 h->plt.offset = s->size; |
2939 | 2939 |
2940 /* Make room for this stub code. */ | 2940 /* Make room for this stub code. */ |
2941 s->size += SCORE_FUNCTION_STUB_SIZE; | 2941 s->size += SCORE_FUNCTION_STUB_SIZE; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3059 bfd_boolean reltext; | 3059 bfd_boolean reltext; |
3060 | 3060 |
3061 dynobj = elf_hash_table (info)->dynobj; | 3061 dynobj = elf_hash_table (info)->dynobj; |
3062 BFD_ASSERT (dynobj != NULL); | 3062 BFD_ASSERT (dynobj != NULL); |
3063 | 3063 |
3064 if (elf_hash_table (info)->dynamic_sections_created) | 3064 if (elf_hash_table (info)->dynamic_sections_created) |
3065 { | 3065 { |
3066 /* Set the contents of the .interp section to the interpreter. */ | 3066 /* Set the contents of the .interp section to the interpreter. */ |
3067 if (!info->shared) | 3067 if (!info->shared) |
3068 { | 3068 { |
3069 s = bfd_get_section_by_name (dynobj, ".interp"); | 3069 s = bfd_get_linker_section (dynobj, ".interp"); |
3070 BFD_ASSERT (s != NULL); | 3070 BFD_ASSERT (s != NULL); |
3071 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; | 3071 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; |
3072 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER; | 3072 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER; |
3073 } | 3073 } |
3074 } | 3074 } |
3075 | 3075 |
3076 /* The check_relocs and adjust_dynamic_symbol entry points have | 3076 /* The check_relocs and adjust_dynamic_symbol entry points have |
3077 determined the sizes of the various dynamic sections. Allocate | 3077 determined the sizes of the various dynamic sections. Allocate |
3078 memory for them. */ | 3078 memory for them. */ |
3079 reltext = FALSE; | 3079 reltext = FALSE; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3217 { | 3217 { |
3218 struct elf_link_hash_entry *h; | 3218 struct elf_link_hash_entry *h; |
3219 struct bfd_link_hash_entry *bh; | 3219 struct bfd_link_hash_entry *bh; |
3220 flagword flags; | 3220 flagword flags; |
3221 asection *s; | 3221 asection *s; |
3222 | 3222 |
3223 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | 3223 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY |
3224 | SEC_LINKER_CREATED | SEC_READONLY); | 3224 | SEC_LINKER_CREATED | SEC_READONLY); |
3225 | 3225 |
3226 /* ABI requests the .dynamic section to be read only. */ | 3226 /* ABI requests the .dynamic section to be read only. */ |
3227 s = bfd_get_section_by_name (abfd, ".dynamic"); | 3227 s = bfd_get_linker_section (abfd, ".dynamic"); |
3228 if (s != NULL) | 3228 if (s != NULL) |
3229 { | 3229 { |
3230 if (!bfd_set_section_flags (abfd, s, flags)) | 3230 if (!bfd_set_section_flags (abfd, s, flags)) |
3231 return FALSE; | 3231 return FALSE; |
3232 } | 3232 } |
3233 | 3233 |
3234 /* We need to create .got section. */ | 3234 /* We need to create .got section. */ |
3235 if (!score_elf_create_got_section (abfd, info, FALSE)) | 3235 if (!score_elf_create_got_section (abfd, info, FALSE)) |
3236 return FALSE; | 3236 return FALSE; |
3237 | 3237 |
3238 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE)) | 3238 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE)) |
3239 return FALSE; | 3239 return FALSE; |
3240 | 3240 |
3241 /* Create .stub section. */ | 3241 /* Create .stub section. */ |
3242 if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL) | 3242 if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL) |
3243 { | 3243 { |
3244 s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME, | 3244 s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME, |
3245 flags | SEC_CODE); | 3245 » » » » » flags | SEC_CODE); |
3246 if (s == NULL | 3246 if (s == NULL |
3247 || !bfd_set_section_alignment (abfd, s, 2)) | 3247 || !bfd_set_section_alignment (abfd, s, 2)) |
3248 | 3248 |
3249 return FALSE; | 3249 return FALSE; |
3250 } | 3250 } |
3251 | 3251 |
3252 if (!info->shared) | 3252 if (!info->shared) |
3253 { | 3253 { |
3254 const char *name; | 3254 const char *name; |
3255 | 3255 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3290 dynobj = elf_hash_table (info)->dynobj; | 3290 dynobj = elf_hash_table (info)->dynobj; |
3291 | 3291 |
3292 if (h->plt.offset != MINUS_ONE) | 3292 if (h->plt.offset != MINUS_ONE) |
3293 { | 3293 { |
3294 asection *s; | 3294 asection *s; |
3295 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE]; | 3295 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE]; |
3296 | 3296 |
3297 /* This symbol has a stub. Set it up. */ | 3297 /* This symbol has a stub. Set it up. */ |
3298 BFD_ASSERT (h->dynindx != -1); | 3298 BFD_ASSERT (h->dynindx != -1); |
3299 | 3299 |
3300 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME); | 3300 s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); |
3301 BFD_ASSERT (s != NULL); | 3301 BFD_ASSERT (s != NULL); |
3302 | 3302 |
3303 /* FIXME: Can h->dynindex be more than 64K? */ | 3303 /* FIXME: Can h->dynindex be more than 64K? */ |
3304 if (h->dynindx & 0xffff0000) | 3304 if (h->dynindx & 0xffff0000) |
3305 return FALSE; | 3305 return FALSE; |
3306 | 3306 |
3307 /* Fill the stub. */ | 3307 /* Fill the stub. */ |
3308 bfd_put_32 (output_bfd, STUB_LW, stub); | 3308 bfd_put_32 (output_bfd, STUB_LW, stub); |
3309 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4); | 3309 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4); |
3310 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8); | 3310 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3370 struct bfd_link_info *info) | 3370 struct bfd_link_info *info) |
3371 { | 3371 { |
3372 bfd *dynobj; | 3372 bfd *dynobj; |
3373 asection *sdyn; | 3373 asection *sdyn; |
3374 asection *sgot; | 3374 asection *sgot; |
3375 asection *s; | 3375 asection *s; |
3376 struct score_got_info *g; | 3376 struct score_got_info *g; |
3377 | 3377 |
3378 dynobj = elf_hash_table (info)->dynobj; | 3378 dynobj = elf_hash_table (info)->dynobj; |
3379 | 3379 |
3380 sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); | 3380 sdyn = bfd_get_linker_section (dynobj, ".dynamic"); |
3381 | 3381 |
3382 sgot = score_elf_got_section (dynobj, FALSE); | 3382 sgot = score_elf_got_section (dynobj, FALSE); |
3383 if (sgot == NULL) | 3383 if (sgot == NULL) |
3384 g = NULL; | 3384 g = NULL; |
3385 else | 3385 else |
3386 { | 3386 { |
3387 BFD_ASSERT (score_elf_section_data (sgot) != NULL); | 3387 BFD_ASSERT (score_elf_section_data (sgot) != NULL); |
3388 g = score_elf_section_data (sgot)->u.got_info; | 3388 g = score_elf_section_data (sgot)->u.got_info; |
3389 BFD_ASSERT (g != NULL); | 3389 BFD_ASSERT (g != NULL); |
3390 } | 3390 } |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3862 sdata = bfd_zalloc (abfd, amt); | 3862 sdata = bfd_zalloc (abfd, amt); |
3863 if (sdata == NULL) | 3863 if (sdata == NULL) |
3864 return FALSE; | 3864 return FALSE; |
3865 sec->used_by_bfd = sdata; | 3865 sec->used_by_bfd = sdata; |
3866 | 3866 |
3867 return _bfd_elf_new_section_hook (abfd, sec); | 3867 return _bfd_elf_new_section_hook (abfd, sec); |
3868 } | 3868 } |
3869 | 3869 |
3870 #define elf_backend_omit_section_dynsym \ | 3870 #define elf_backend_omit_section_dynsym \ |
3871 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) | 3871 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) |
OLD | NEW |