OLD | NEW |
1 /* 32-bit ELF support for ARM | 1 /* 32-bit ELF support for ARM |
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, | 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, |
3 2008, 2009, 2010, 2011 Free Software Foundation, Inc. | 3 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of BFD, the Binary File Descriptor library. | 5 This file is part of BFD, the Binary File Descriptor library. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
11 | 11 |
12 This program is distributed in the hope that it will be useful, | 12 This program is distributed in the hope that it will be useful, |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 GNU General Public License for more details. | 15 GNU General Public License for more details. |
16 | 16 |
17 You should have received a copy of the GNU General Public License | 17 You should have received a copy of the GNU General Public License |
18 along with this program; if not, write to the Free Software | 18 along with this program; if not, write to the Free Software |
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 MA 02110-1301, USA. */ | 20 MA 02110-1301, USA. */ |
21 | 21 |
22 #include "sysdep.h" | 22 #include "sysdep.h" |
23 #include <limits.h> | 23 #include <limits.h> |
24 | 24 |
25 #include "bfd.h" | 25 #include "bfd.h" |
| 26 #include "bfd_stdint.h" |
26 #include "libiberty.h" | 27 #include "libiberty.h" |
27 #include "libbfd.h" | 28 #include "libbfd.h" |
28 #include "elf-bfd.h" | 29 #include "elf-bfd.h" |
| 30 #include "elf-nacl.h" |
29 #include "elf-vxworks.h" | 31 #include "elf-vxworks.h" |
30 #include "elf/arm.h" | 32 #include "elf/arm.h" |
31 | 33 |
32 /* Return the relocation section associated with NAME. HTAB is the | 34 /* Return the relocation section associated with NAME. HTAB is the |
33 bfd's elf32_arm_link_hash_entry. */ | 35 bfd's elf32_arm_link_hash_entry. */ |
34 #define RELOC_SECTION(HTAB, NAME) \ | 36 #define RELOC_SECTION(HTAB, NAME) \ |
35 ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME) | 37 ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME) |
36 | 38 |
37 /* Return size of a relocation entry. HTAB is the bfd's | 39 /* Return size of a relocation entry. HTAB is the bfd's |
38 elf32_arm_link_hash_entry. */ | 40 elf32_arm_link_hash_entry. */ |
(...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 char *command = elf_tdata (abfd)->core_command; | 1983 char *command = elf_tdata (abfd)->core_command; |
1982 int n = strlen (command); | 1984 int n = strlen (command); |
1983 | 1985 |
1984 if (0 < n && command[n - 1] == ' ') | 1986 if (0 < n && command[n - 1] == ' ') |
1985 command[n - 1] = '\0'; | 1987 command[n - 1] = '\0'; |
1986 } | 1988 } |
1987 | 1989 |
1988 return TRUE; | 1990 return TRUE; |
1989 } | 1991 } |
1990 | 1992 |
| 1993 static char * |
| 1994 elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz, |
| 1995 int note_type, ...) |
| 1996 { |
| 1997 switch (note_type) |
| 1998 { |
| 1999 default: |
| 2000 return NULL; |
| 2001 |
| 2002 case NT_PRPSINFO: |
| 2003 { |
| 2004 char data[124]; |
| 2005 va_list ap; |
| 2006 |
| 2007 va_start (ap, note_type); |
| 2008 memset (data, 0, sizeof (data)); |
| 2009 strncpy (data + 28, va_arg (ap, const char *), 16); |
| 2010 strncpy (data + 44, va_arg (ap, const char *), 80); |
| 2011 va_end (ap); |
| 2012 |
| 2013 return elfcore_write_note (abfd, buf, bufsiz, |
| 2014 "CORE", note_type, data, sizeof (data)); |
| 2015 } |
| 2016 |
| 2017 case NT_PRSTATUS: |
| 2018 { |
| 2019 char data[148]; |
| 2020 va_list ap; |
| 2021 long pid; |
| 2022 int cursig; |
| 2023 const void *greg; |
| 2024 |
| 2025 va_start (ap, note_type); |
| 2026 memset (data, 0, sizeof (data)); |
| 2027 pid = va_arg (ap, long); |
| 2028 bfd_put_32 (abfd, pid, data + 24); |
| 2029 cursig = va_arg (ap, int); |
| 2030 bfd_put_16 (abfd, cursig, data + 12); |
| 2031 greg = va_arg (ap, const void *); |
| 2032 memcpy (data + 72, greg, 72); |
| 2033 va_end (ap); |
| 2034 |
| 2035 return elfcore_write_note (abfd, buf, bufsiz, |
| 2036 "CORE", note_type, data, sizeof (data)); |
| 2037 } |
| 2038 } |
| 2039 } |
| 2040 |
1991 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec | 2041 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec |
1992 #define TARGET_LITTLE_NAME "elf32-littlearm" | 2042 #define TARGET_LITTLE_NAME "elf32-littlearm" |
1993 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec | 2043 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec |
1994 #define TARGET_BIG_NAME "elf32-bigarm" | 2044 #define TARGET_BIG_NAME "elf32-bigarm" |
1995 | 2045 |
1996 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus | 2046 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus |
1997 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo | 2047 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo |
| 2048 #define elf_backend_write_core_note elf32_arm_nabi_write_core_note |
1998 | 2049 |
1999 typedef unsigned long int insn32; | 2050 typedef unsigned long int insn32; |
2000 typedef unsigned short int insn16; | 2051 typedef unsigned short int insn16; |
2001 | 2052 |
2002 /* In lieu of proper flags, assume all EABIv4 or later objects are | 2053 /* In lieu of proper flags, assume all EABIv4 or later objects are |
2003 interworkable. */ | 2054 interworkable. */ |
2004 #define INTERWORK_FLAG(abfd) \ | 2055 #define INTERWORK_FLAG(abfd) \ |
2005 (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \ | 2056 (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \ |
2006 || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) \ | 2057 || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) \ |
2007 || ((abfd)->flags & BFD_LINKER_CREATED)) | 2058 || ((abfd)->flags & BFD_LINKER_CREATED)) |
(...skipping 14 matching lines...) Expand all Loading... |
2022 #define ARM_BX_GLUE_SECTION_NAME ".v4_bx" | 2073 #define ARM_BX_GLUE_SECTION_NAME ".v4_bx" |
2023 #define ARM_BX_GLUE_ENTRY_NAME "__bx_r%d" | 2074 #define ARM_BX_GLUE_ENTRY_NAME "__bx_r%d" |
2024 | 2075 |
2025 #define STUB_ENTRY_NAME "__%s_veneer" | 2076 #define STUB_ENTRY_NAME "__%s_veneer" |
2026 | 2077 |
2027 /* The name of the dynamic interpreter. This is put in the .interp | 2078 /* The name of the dynamic interpreter. This is put in the .interp |
2028 section. */ | 2079 section. */ |
2029 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" | 2080 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" |
2030 | 2081 |
2031 static const unsigned long tls_trampoline [] = | 2082 static const unsigned long tls_trampoline [] = |
2032 { | 2083 { |
2033 0xe08e0000,»» /* add r0, lr, r0 */ | 2084 0xe08e0000,» » /* add r0, lr, r0 */ |
2034 0xe5901004,»» /* ldr r1, [r0,#4] */ | 2085 0xe5901004,» » /* ldr r1, [r0,#4] */ |
2035 0xe12fff11,»» /* bx r1 */ | 2086 0xe12fff11,» » /* bx r1 */ |
2036 }; | 2087 }; |
2037 | 2088 |
2038 static const unsigned long dl_tlsdesc_lazy_trampoline [] = | 2089 static const unsigned long dl_tlsdesc_lazy_trampoline [] = |
2039 { | 2090 { |
2040 0xe52d2004, /*» push {r2}» » » */ | 2091 0xe52d2004, /*» push {r2}» » » */ |
2041 0xe59f200c, /* ldr r2, [pc, #3f - . - 8]» */ | 2092 0xe59f200c, /* ldr r2, [pc, #3f - . - 8]» */ |
2042 0xe59f100c, /* ldr r1, [pc, #4f - . - 8]» */ | 2093 0xe59f100c, /* ldr r1, [pc, #4f - . - 8]» */ |
2043 0xe79f2002, /* 1: ldr r2, [pc, r2]» » */ | 2094 0xe79f2002, /* 1: ldr r2, [pc, r2]» » */ |
2044 0xe081100f, /* 2: add r1, pc» » » */ | 2095 0xe081100f, /* 2: add r1, pc» » » */ |
2045 0xe12fff12, /* bx r2» » » */ | 2096 0xe12fff12, /* bx r2» » » */ |
2046 0x00000014, /* 3: .word _GLOBAL_OFFSET_TABLE_ - 1b - 8 | 2097 0x00000014, /* 3: .word _GLOBAL_OFFSET_TABLE_ - 1b - 8 |
2047 + dl_tlsdesc_lazy_resolver(GOT) */ | 2098 + dl_tlsdesc_lazy_resolver(GOT) */ |
2048 0x00000018, /* 4: .word _GLOBAL_OFFSET_TABLE_ - 2b - 8 */ | 2099 0x00000018, /* 4: .word _GLOBAL_OFFSET_TABLE_ - 2b - 8 */ |
2049 }; | 2100 }; |
2050 | 2101 |
2051 #ifdef FOUR_WORD_PLT | 2102 #ifdef FOUR_WORD_PLT |
2052 | 2103 |
2053 /* The first entry in a procedure linkage table looks like | 2104 /* The first entry in a procedure linkage table looks like |
2054 this. It is set up so that any shared library function that is | 2105 this. It is set up so that any shared library function that is |
2055 called before the relocation has been set up calls the dynamic | 2106 called before the relocation has been set up calls the dynamic |
2056 linker first. */ | 2107 linker first. */ |
2057 static const bfd_vma elf32_arm_plt0_entry [] = | 2108 static const bfd_vma elf32_arm_plt0_entry [] = |
2058 { | 2109 { |
2059 0xe52de004,»» /* str lr, [sp, #-4]! */ | 2110 0xe52de004,» » /* str lr, [sp, #-4]! */ |
2060 0xe59fe010,»» /* ldr lr, [pc, #16] */ | 2111 0xe59fe010,» » /* ldr lr, [pc, #16] */ |
2061 0xe08fe00e,»» /* add lr, pc, lr */ | 2112 0xe08fe00e,» » /* add lr, pc, lr */ |
2062 0xe5bef008,»» /* ldr pc, [lr, #8]! */ | 2113 0xe5bef008,» » /* ldr pc, [lr, #8]! */ |
2063 }; | 2114 }; |
2064 | 2115 |
2065 /* Subsequent entries in a procedure linkage table look like | 2116 /* Subsequent entries in a procedure linkage table look like |
2066 this. */ | 2117 this. */ |
2067 static const bfd_vma elf32_arm_plt_entry [] = | 2118 static const bfd_vma elf32_arm_plt_entry [] = |
2068 { | 2119 { |
2069 0xe28fc600,»» /* add ip, pc, #NN» */ | 2120 0xe28fc600,» » /* add ip, pc, #NN» */ |
2070 0xe28cca00,»» /* add» ip, ip, #NN» */ | 2121 0xe28cca00,» » /* add» ip, ip, #NN» */ |
2071 0xe5bcf000,»» /* ldr» pc, [ip, #NN]! */ | 2122 0xe5bcf000,» » /* ldr» pc, [ip, #NN]! */ |
2072 0x00000000,»» /* unused» » */ | 2123 0x00000000,» » /* unused» » */ |
2073 }; | 2124 }; |
2074 | 2125 |
2075 #else | 2126 #else |
2076 | 2127 |
2077 /* The first entry in a procedure linkage table looks like | 2128 /* The first entry in a procedure linkage table looks like |
2078 this. It is set up so that any shared library function that is | 2129 this. It is set up so that any shared library function that is |
2079 called before the relocation has been set up calls the dynamic | 2130 called before the relocation has been set up calls the dynamic |
2080 linker first. */ | 2131 linker first. */ |
2081 static const bfd_vma elf32_arm_plt0_entry [] = | 2132 static const bfd_vma elf32_arm_plt0_entry [] = |
2082 { | 2133 { |
2083 0xe52de004,»» /* str lr, [sp, #-4]! */ | 2134 0xe52de004,» » /* str lr, [sp, #-4]! */ |
2084 0xe59fe004,»» /* ldr lr, [pc, #4] */ | 2135 0xe59fe004,» » /* ldr lr, [pc, #4] */ |
2085 0xe08fe00e,»» /* add lr, pc, lr */ | 2136 0xe08fe00e,» » /* add lr, pc, lr */ |
2086 0xe5bef008,»» /* ldr pc, [lr, #8]! */ | 2137 0xe5bef008,» » /* ldr pc, [lr, #8]! */ |
2087 0x00000000,»» /* &GOT[0] - . */ | 2138 0x00000000,» » /* &GOT[0] - . */ |
2088 }; | 2139 }; |
2089 | 2140 |
2090 /* Subsequent entries in a procedure linkage table look like | 2141 /* Subsequent entries in a procedure linkage table look like |
2091 this. */ | 2142 this. */ |
2092 static const bfd_vma elf32_arm_plt_entry [] = | 2143 static const bfd_vma elf32_arm_plt_entry [] = |
2093 { | 2144 { |
2094 0xe28fc600,»» /* add ip, pc, #0xNN00000 */ | 2145 0xe28fc600,» » /* add ip, pc, #0xNN00000 */ |
2095 0xe28cca00,»» /* add» ip, ip, #0xNN000 */ | 2146 0xe28cca00,» » /* add» ip, ip, #0xNN000 */ |
2096 0xe5bcf000,»» /* ldr» pc, [ip, #0xNNN]! */ | 2147 0xe5bcf000,» » /* ldr» pc, [ip, #0xNNN]! */ |
2097 }; | 2148 }; |
2098 | 2149 |
2099 #endif | 2150 #endif |
2100 | 2151 |
2101 /* The format of the first entry in the procedure linkage table | 2152 /* The format of the first entry in the procedure linkage table |
2102 for a VxWorks executable. */ | 2153 for a VxWorks executable. */ |
2103 static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] = | 2154 static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] = |
2104 { | 2155 { |
2105 0xe52dc008,» /* str ip,[sp,#-8]!» » » */ | 2156 0xe52dc008,» /* str ip,[sp,#-8]!» » » */ |
2106 0xe59fc000, /* ldr ip,[pc]» » » */ | 2157 0xe59fc000, » /* ldr ip,[pc]» » » */ |
2107 0xe59cf008, /* ldr pc,[ip,#8]» » » */ | 2158 0xe59cf008, » /* ldr pc,[ip,#8]» » » */ |
2108 0x00000000, /* .long _GLOBAL_OFFSET_TABLE_»» */ | 2159 0x00000000, » /* .long _GLOBAL_OFFSET_TABLE_»» */ |
2109 }; | 2160 }; |
2110 | 2161 |
2111 /* The format of subsequent entries in a VxWorks executable. */ | 2162 /* The format of subsequent entries in a VxWorks executable. */ |
2112 static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] = | 2163 static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] = |
2113 { | 2164 { |
2114 0xe59fc000, /* ldr ip,[pc]» » » */ | 2165 0xe59fc000, /* ldr ip,[pc]»» » */ |
2115 0xe59cf000, /* ldr pc,[ip]» » » */ | 2166 0xe59cf000, /* ldr pc,[ip]»» » */ |
2116 0x00000000, /* .long @got» » » » */ | 2167 0x00000000, /* .long @got» » » » */ |
2117 0xe59fc000, /* ldr ip,[pc]» » » */ | 2168 0xe59fc000, /* ldr ip,[pc]»» » */ |
2118 0xea000000, /* b _PLT» » » » */ | 2169 0xea000000, /* b _PLT» » » » */ |
2119 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela)» */ | 2170 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela)» */ |
2120 }; | 2171 }; |
2121 | 2172 |
2122 /* The format of entries in a VxWorks shared library. */ | 2173 /* The format of entries in a VxWorks shared library. */ |
2123 static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] = | 2174 static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] = |
2124 { | 2175 { |
2125 0xe59fc000, /* ldr ip,[pc]» » » */ | 2176 0xe59fc000, /* ldr ip,[pc]»» » */ |
2126 0xe79cf009, /* ldr pc,[ip,r9]» » » */ | 2177 0xe79cf009, /* ldr pc,[ip,r9]» » » */ |
2127 0x00000000, /* .long @got» » » » */ | 2178 0x00000000, /* .long @got» » » » */ |
2128 0xe59fc000, /* ldr ip,[pc]» » » */ | 2179 0xe59fc000, /* ldr ip,[pc]»» » */ |
2129 0xe599f008, /* ldr pc,[r9,#8]» » » */ | 2180 0xe599f008, /* ldr pc,[r9,#8]» » » */ |
2130 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela)» */ | 2181 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela)» */ |
2131 }; | 2182 }; |
2132 | 2183 |
2133 /* An initial stub used if the PLT entry is referenced from Thumb code. */ | 2184 /* An initial stub used if the PLT entry is referenced from Thumb code. */ |
2134 #define PLT_THUMB_STUB_SIZE 4 | 2185 #define PLT_THUMB_STUB_SIZE 4 |
2135 static const bfd_vma elf32_arm_plt_thumb_stub [] = | 2186 static const bfd_vma elf32_arm_plt_thumb_stub [] = |
2136 { | 2187 { |
2137 0x4778,» » /* bx pc */ | 2188 0x4778,» » /* bx pc */ |
2138 0x46c0» » /* nop */ | 2189 0x46c0» » /* nop */ |
2139 }; | 2190 }; |
2140 | 2191 |
2141 /* The entries in a PLT when using a DLL-based target with multiple | 2192 /* The entries in a PLT when using a DLL-based target with multiple |
2142 address spaces. */ | 2193 address spaces. */ |
2143 static const bfd_vma elf32_arm_symbian_plt_entry [] = | 2194 static const bfd_vma elf32_arm_symbian_plt_entry [] = |
2144 { | 2195 { |
2145 0xe51ff004, /* ldr pc, [pc, #-4] */ | 2196 0xe51ff004, /* ldr pc, [pc, #-4] */ |
2146 0x00000000, /* dcd R_ARM_GLOB_DAT(X) */ | 2197 0x00000000, /* dcd R_ARM_GLOB_DAT(X) */ |
2147 }; | 2198 }; |
| 2199 |
| 2200 /* The first entry in a procedure linkage table looks like |
| 2201 this. It is set up so that any shared library function that is |
| 2202 called before the relocation has been set up calls the dynamic |
| 2203 linker first. */ |
| 2204 static const bfd_vma elf32_arm_nacl_plt0_entry [] = |
| 2205 { |
| 2206 /* First bundle: */ |
| 2207 0xe300c000,» » /* movw»ip, #:lower16:&GOT[2]-.+8» */ |
| 2208 0xe340c000,» » /* movt»ip, #:upper16:&GOT[2]-.+8» */ |
| 2209 0xe08cc00f,» » /* add» ip, ip, pc» » » */ |
| 2210 0xe52dc008,» » /* str» ip, [sp, #-8]!» » » */ |
| 2211 /* Second bundle: */ |
| 2212 0xe7dfcf1f, » /* bfc» ip, #30, #2» » » */ |
| 2213 0xe59cc000, » /* ldr» ip, [ip]» » » */ |
| 2214 0xe3ccc13f,» » /* bic» ip, ip, #0xc000000f» » */ |
| 2215 0xe12fff1c, » /* bx» ip» » » » */ |
| 2216 /* Third bundle: */ |
| 2217 0xe320f000, » /* nop» » » » » */ |
| 2218 0xe320f000, » /* nop» » » » » */ |
| 2219 0xe320f000, » /* nop» » » » » */ |
| 2220 /* .Lplt_tail: */ |
| 2221 0xe50dc004,» » /* str» ip, [sp, #-4]» » » */ |
| 2222 /* Fourth bundle: */ |
| 2223 0xe7dfcf1f,» » /* bfc» ip, #30, #2» » » */ |
| 2224 0xe59cc000, » /* ldr» ip, [ip]» » » */ |
| 2225 0xe3ccc13f,» » /* bic» ip, ip, #0xc000000f» » */ |
| 2226 0xe12fff1c, » /* bx» ip» » » » */ |
| 2227 }; |
| 2228 #define ARM_NACL_PLT_TAIL_OFFSET» (11 * 4) |
| 2229 |
| 2230 /* Subsequent entries in a procedure linkage table look like this. */ |
| 2231 static const bfd_vma elf32_arm_nacl_plt_entry [] = |
| 2232 { |
| 2233 0xe300c000,» » /* movw»ip, #:lower16:&GOT[n]-.+8» */ |
| 2234 0xe340c000,» » /* movt»ip, #:upper16:&GOT[n]-.+8» */ |
| 2235 0xe08cc00f,» » /* add» ip, ip, pc» » » */ |
| 2236 0xea000000,» » /* b» .Lplt_tail» » » */ |
| 2237 }; |
2148 | 2238 |
2149 #define ARM_MAX_FWD_BRANCH_OFFSET ((((1 << 23) - 1) << 2) + 8) | 2239 #define ARM_MAX_FWD_BRANCH_OFFSET ((((1 << 23) - 1) << 2) + 8) |
2150 #define ARM_MAX_BWD_BRANCH_OFFSET ((-((1 << 23) << 2)) + 8) | 2240 #define ARM_MAX_BWD_BRANCH_OFFSET ((-((1 << 23) << 2)) + 8) |
2151 #define THM_MAX_FWD_BRANCH_OFFSET ((1 << 22) -2 + 4) | 2241 #define THM_MAX_FWD_BRANCH_OFFSET ((1 << 22) -2 + 4) |
2152 #define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4) | 2242 #define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4) |
2153 #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4) | 2243 #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4) |
2154 #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4) | 2244 #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4) |
2155 | 2245 |
2156 enum stub_insn_type | 2246 enum stub_insn_type |
2157 { | 2247 { |
2158 THUMB16_TYPE = 1, | 2248 THUMB16_TYPE = 1, |
2159 THUMB32_TYPE, | 2249 THUMB32_TYPE, |
2160 ARM_TYPE, | 2250 ARM_TYPE, |
2161 DATA_TYPE | 2251 DATA_TYPE |
2162 }; | 2252 }; |
2163 | 2253 |
2164 #define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0} | 2254 #define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0} |
2165 /* A bit of a hack. A Thumb conditional branch, in which the proper condition | 2255 /* A bit of a hack. A Thumb conditional branch, in which the proper condition |
2166 is inserted in arm_build_one_stub(). */ | 2256 is inserted in arm_build_one_stub(). */ |
2167 #define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1} | 2257 #define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1} |
2168 #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} | 2258 #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} |
2169 #define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)} | 2259 #define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)} |
2170 #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} | 2260 #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} |
2171 #define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)} | 2261 #define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)} |
2172 #define DATA_WORD(X,Y,Z) {(X), DATA_TYPE, (Y), (Z)} | 2262 #define DATA_WORD(X,Y,Z) {(X), DATA_TYPE, (Y), (Z)} |
2173 | 2263 |
2174 typedef struct | 2264 typedef struct |
2175 { | 2265 { |
2176 bfd_vma data; | 2266 bfd_vma data; |
2177 enum stub_insn_type type; | 2267 enum stub_insn_type type; |
2178 unsigned int r_type; | 2268 unsigned int r_type; |
2179 int reloc_addend; | 2269 int reloc_addend; |
2180 } insn_sequence; | 2270 } insn_sequence; |
2181 | 2271 |
2182 /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx | 2272 /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx |
2183 to reach the stub if necessary. */ | 2273 to reach the stub if necessary. */ |
2184 static const insn_sequence elf32_arm_stub_long_branch_any_any[] = | 2274 static const insn_sequence elf32_arm_stub_long_branch_any_any[] = |
2185 { | 2275 { |
2186 ARM_INSN(0xe51ff004), /* ldr pc, [pc, #-4] */ | 2276 ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */ |
2187 DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ | 2277 DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
2188 }; | 2278 }; |
2189 | 2279 |
2190 /* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not | 2280 /* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not |
2191 available. */ | 2281 available. */ |
2192 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] = | 2282 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] = |
2193 { | 2283 { |
2194 ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ | 2284 ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
2195 ARM_INSN(0xe12fff1c), /* bx ip */ | 2285 ARM_INSN (0xe12fff1c), /* bx ip */ |
2196 DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ | 2286 DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
2197 }; | 2287 }; |
2198 | 2288 |
2199 /* Thumb -> Thumb long branch stub. Used on M-profile architectures. */ | 2289 /* Thumb -> Thumb long branch stub. Used on M-profile architectures. */ |
2200 static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] = | 2290 static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] = |
2201 { | 2291 { |
2202 THUMB16_INSN(0xb401), /* push {r0} */ | 2292 THUMB16_INSN (0xb401), /* push {r0} */ |
2203 THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ | 2293 THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */ |
2204 THUMB16_INSN(0x4684), /* mov ip, r0 */ | 2294 THUMB16_INSN (0x4684), /* mov ip, r0 */ |
2205 THUMB16_INSN(0xbc01), /* pop {r0} */ | 2295 THUMB16_INSN (0xbc01), /* pop {r0} */ |
2206 THUMB16_INSN(0x4760), /* bx ip */ | 2296 THUMB16_INSN (0x4760), /* bx ip */ |
2207 THUMB16_INSN(0xbf00), /* nop */ | 2297 THUMB16_INSN (0xbf00), /* nop */ |
2208 DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ | 2298 DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
2209 }; | 2299 }; |
2210 | 2300 |
2211 /* V4T Thumb -> Thumb long branch stub. Using the stack is not | 2301 /* V4T Thumb -> Thumb long branch stub. Using the stack is not |
2212 allowed. */ | 2302 allowed. */ |
2213 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] = | 2303 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] = |
2214 { | 2304 { |
2215 THUMB16_INSN(0x4778), /* bx pc */ | 2305 THUMB16_INSN (0x4778), /* bx pc */ |
2216 THUMB16_INSN(0x46c0), /* nop */ | 2306 THUMB16_INSN (0x46c0), /* nop */ |
2217 ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ | 2307 ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
2218 ARM_INSN(0xe12fff1c), /* bx ip */ | 2308 ARM_INSN (0xe12fff1c), /* bx ip */ |
2219 DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ | 2309 DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
2220 }; | 2310 }; |
2221 | 2311 |
2222 /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not | 2312 /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not |
2223 available. */ | 2313 available. */ |
2224 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] = | 2314 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] = |
2225 { | 2315 { |
2226 THUMB16_INSN(0x4778), /* bx pc */ | 2316 THUMB16_INSN (0x4778), /* bx pc */ |
2227 THUMB16_INSN(0x46c0), /* nop */ | 2317 THUMB16_INSN (0x46c0), /* nop */ |
2228 ARM_INSN(0xe51ff004), /* ldr pc, [pc, #-4] */ | 2318 ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */ |
2229 DATA_WORD(0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ | 2319 DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
2230 }; | 2320 }; |
2231 | 2321 |
2232 /* V4T Thumb -> ARM short branch stub. Shorter variant of the above | 2322 /* V4T Thumb -> ARM short branch stub. Shorter variant of the above |
2233 one, when the destination is close enough. */ | 2323 one, when the destination is close enough. */ |
2234 static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] = | 2324 static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] = |
2235 { | 2325 { |
2236 THUMB16_INSN(0x4778), /* bx pc */ | 2326 THUMB16_INSN (0x4778), /* bx pc */ |
2237 THUMB16_INSN(0x46c0), /* nop */ | 2327 THUMB16_INSN (0x46c0), /* nop */ |
2238 ARM_REL_INSN(0xea000000, -8), /* b (X-8) */ | 2328 ARM_REL_INSN (0xea000000, -8), /* b (X-8) */ |
2239 }; | 2329 }; |
2240 | 2330 |
2241 /* ARM/Thumb -> ARM long branch stub, PIC. On V5T and above, use | 2331 /* ARM/Thumb -> ARM long branch stub, PIC. On V5T and above, use |
2242 blx to reach the stub if necessary. */ | 2332 blx to reach the stub if necessary. */ |
2243 static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] = | 2333 static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] = |
2244 { | 2334 { |
2245 ARM_INSN(0xe59fc000), /* ldr ip, [pc] */ | 2335 ARM_INSN (0xe59fc000), /* ldr ip, [pc] */ |
2246 ARM_INSN(0xe08ff00c), /* add pc, pc, ip */ | 2336 ARM_INSN (0xe08ff00c), /* add pc, pc, ip */ |
2247 DATA_WORD(0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ | 2337 DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ |
2248 }; | 2338 }; |
2249 | 2339 |
2250 /* ARM/Thumb -> Thumb long branch stub, PIC. On V5T and above, use | 2340 /* ARM/Thumb -> Thumb long branch stub, PIC. On V5T and above, use |
2251 blx to reach the stub if necessary. We can not add into pc; | 2341 blx to reach the stub if necessary. We can not add into pc; |
2252 it is not guaranteed to mode switch (different in ARMv6 and | 2342 it is not guaranteed to mode switch (different in ARMv6 and |
2253 ARMv7). */ | 2343 ARMv7). */ |
2254 static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] = | 2344 static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] = |
2255 { | 2345 { |
2256 ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ | 2346 ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
2257 ARM_INSN(0xe08fc00c), /* add ip, pc, ip */ | 2347 ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
2258 ARM_INSN(0xe12fff1c), /* bx ip */ | 2348 ARM_INSN (0xe12fff1c), /* bx ip */ |
2259 DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ | 2349 DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
2260 }; | 2350 }; |
2261 | 2351 |
2262 /* V4T ARM -> ARM long branch stub, PIC. */ | 2352 /* V4T ARM -> ARM long branch stub, PIC. */ |
2263 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = | 2353 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = |
2264 { | 2354 { |
2265 ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ | 2355 ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
2266 ARM_INSN(0xe08fc00c), /* add ip, pc, ip */ | 2356 ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
2267 ARM_INSN(0xe12fff1c), /* bx ip */ | 2357 ARM_INSN (0xe12fff1c), /* bx ip */ |
2268 DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ | 2358 DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
2269 }; | 2359 }; |
2270 | 2360 |
2271 /* V4T Thumb -> ARM long branch stub, PIC. */ | 2361 /* V4T Thumb -> ARM long branch stub, PIC. */ |
2272 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = | 2362 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = |
2273 { | 2363 { |
2274 THUMB16_INSN(0x4778), /* bx pc */ | 2364 THUMB16_INSN (0x4778), /* bx pc */ |
2275 THUMB16_INSN(0x46c0), /* nop */ | 2365 THUMB16_INSN (0x46c0), /* nop */ |
2276 ARM_INSN(0xe59fc000), /* ldr ip, [pc, #0] */ | 2366 ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
2277 ARM_INSN(0xe08cf00f), /* add pc, ip, pc */ | 2367 ARM_INSN (0xe08cf00f), /* add pc, ip, pc */ |
2278 DATA_WORD(0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ | 2368 DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ |
2279 }; | 2369 }; |
2280 | 2370 |
2281 /* Thumb -> Thumb long branch stub, PIC. Used on M-profile | 2371 /* Thumb -> Thumb long branch stub, PIC. Used on M-profile |
2282 architectures. */ | 2372 architectures. */ |
2283 static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = | 2373 static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = |
2284 { | 2374 { |
2285 THUMB16_INSN(0xb401), /* push {r0} */ | 2375 THUMB16_INSN (0xb401), /* push {r0} */ |
2286 THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ | 2376 THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */ |
2287 THUMB16_INSN(0x46fc), /* mov ip, pc */ | 2377 THUMB16_INSN (0x46fc), /* mov ip, pc */ |
2288 THUMB16_INSN(0x4484), /* add ip, r0 */ | 2378 THUMB16_INSN (0x4484), /* add ip, r0 */ |
2289 THUMB16_INSN(0xbc01), /* pop {r0} */ | 2379 THUMB16_INSN (0xbc01), /* pop {r0} */ |
2290 THUMB16_INSN(0x4760), /* bx ip */ | 2380 THUMB16_INSN (0x4760), /* bx ip */ |
2291 DATA_WORD(0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ | 2381 DATA_WORD (0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ |
2292 }; | 2382 }; |
2293 | 2383 |
2294 /* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not | 2384 /* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not |
2295 allowed. */ | 2385 allowed. */ |
2296 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] = | 2386 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] = |
2297 { | 2387 { |
2298 THUMB16_INSN(0x4778), /* bx pc */ | 2388 THUMB16_INSN (0x4778), /* bx pc */ |
2299 THUMB16_INSN(0x46c0), /* nop */ | 2389 THUMB16_INSN (0x46c0), /* nop */ |
2300 ARM_INSN(0xe59fc004), /* ldr ip, [pc, #4] */ | 2390 ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
2301 ARM_INSN(0xe08fc00c), /* add ip, pc, ip */ | 2391 ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
2302 ARM_INSN(0xe12fff1c), /* bx ip */ | 2392 ARM_INSN (0xe12fff1c), /* bx ip */ |
2303 DATA_WORD(0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ | 2393 DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
2304 }; | 2394 }; |
2305 | 2395 |
2306 /* Thumb2/ARM -> TLS trampoline. Lowest common denominator, which is a | 2396 /* Thumb2/ARM -> TLS trampoline. Lowest common denominator, which is a |
2307 long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ | 2397 long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ |
2308 static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] = | 2398 static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] = |
2309 { | 2399 { |
2310 ARM_INSN(0xe59f1000), /* ldr r1, [pc] */ | 2400 ARM_INSN (0xe59f1000), /* ldr r1, [pc] */ |
2311 ARM_INSN(0xe08ff001), /* add pc, pc, r1 */ | 2401 ARM_INSN (0xe08ff001), /* add pc, pc, r1 */ |
2312 DATA_WORD(0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ | 2402 DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ |
2313 }; | 2403 }; |
2314 | 2404 |
2315 /* V4T Thumb -> TLS trampoline. lowest common denominator, which is a | 2405 /* V4T Thumb -> TLS trampoline. lowest common denominator, which is a |
2316 long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ | 2406 long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ |
2317 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] = | 2407 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] = |
2318 { | 2408 { |
2319 THUMB16_INSN(0x4778), /* bx pc */ | 2409 THUMB16_INSN (0x4778), /* bx pc */ |
2320 THUMB16_INSN(0x46c0), /* nop */ | 2410 THUMB16_INSN (0x46c0), /* nop */ |
2321 ARM_INSN(0xe59f1000), /* ldr r1, [pc, #0] */ | 2411 ARM_INSN (0xe59f1000), /* ldr r1, [pc, #0] */ |
2322 ARM_INSN(0xe081f00f), /* add pc, r1, pc */ | 2412 ARM_INSN (0xe081f00f), /* add pc, r1, pc */ |
2323 DATA_WORD(0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ | 2413 DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ |
2324 }; | 2414 }; |
2325 | 2415 |
2326 /* Cortex-A8 erratum-workaround stubs. */ | 2416 /* Cortex-A8 erratum-workaround stubs. */ |
2327 | 2417 |
2328 /* Stub used for conditional branches (which may be beyond +/-1MB away, so we | 2418 /* Stub used for conditional branches (which may be beyond +/-1MB away, so we |
2329 can't use a conditional branch to reach this stub). */ | 2419 can't use a conditional branch to reach this stub). */ |
2330 | 2420 |
2331 static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] = | 2421 static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] = |
2332 { | 2422 { |
2333 THUMB16_BCOND_INSN(0xd001), /* b<cond>.n true. */ | 2423 THUMB16_BCOND_INSN (0xd001), /* b<cond>.n true. */ |
2334 THUMB32_B_INSN(0xf000b800, -4), /* b.w insn_after_original_branch. */ | 2424 THUMB32_B_INSN (0xf000b800, -4), /* b.w insn_after_original_branch. */ |
2335 THUMB32_B_INSN(0xf000b800, -4) /* true: b.w original_branch_dest. */ | 2425 THUMB32_B_INSN (0xf000b800, -4) /* true: b.w original_branch_dest. */ |
2336 }; | 2426 }; |
2337 | 2427 |
2338 /* Stub used for b.w and bl.w instructions. */ | 2428 /* Stub used for b.w and bl.w instructions. */ |
2339 | 2429 |
2340 static const insn_sequence elf32_arm_stub_a8_veneer_b[] = | 2430 static const insn_sequence elf32_arm_stub_a8_veneer_b[] = |
2341 { | 2431 { |
2342 THUMB32_B_INSN(0xf000b800, -4)» /* b.w original_branch_dest. */ | 2432 THUMB32_B_INSN (0xf000b800, -4)» /* b.w original_branch_dest. */ |
2343 }; | 2433 }; |
2344 | 2434 |
2345 static const insn_sequence elf32_arm_stub_a8_veneer_bl[] = | 2435 static const insn_sequence elf32_arm_stub_a8_veneer_bl[] = |
2346 { | 2436 { |
2347 THUMB32_B_INSN(0xf000b800, -4)» /* b.w original_branch_dest. */ | 2437 THUMB32_B_INSN (0xf000b800, -4)» /* b.w original_branch_dest. */ |
2348 }; | 2438 }; |
2349 | 2439 |
2350 /* Stub used for Thumb-2 blx.w instructions. We modified the original blx.w | 2440 /* Stub used for Thumb-2 blx.w instructions. We modified the original blx.w |
2351 instruction (which switches to ARM mode) to point to this stub. Jump to the | 2441 instruction (which switches to ARM mode) to point to this stub. Jump to the |
2352 real destination using an ARM-mode branch. */ | 2442 real destination using an ARM-mode branch. */ |
2353 | 2443 |
2354 static const insn_sequence elf32_arm_stub_a8_veneer_blx[] = | 2444 static const insn_sequence elf32_arm_stub_a8_veneer_blx[] = |
2355 { | 2445 { |
2356 ARM_REL_INSN(0xea000000, -8)» /* b original_branch_dest. */ | 2446 ARM_REL_INSN (0xea000000, -8)»/* b original_branch_dest. */ |
2357 }; | 2447 }; |
2358 | 2448 |
2359 /* For each section group there can be a specially created linker section | 2449 /* For each section group there can be a specially created linker section |
2360 to hold the stubs for that group. The name of the stub section is based | 2450 to hold the stubs for that group. The name of the stub section is based |
2361 upon the name of another section within that group with the suffix below | 2451 upon the name of another section within that group with the suffix below |
2362 applied. | 2452 applied. |
2363 | 2453 |
2364 PR 13049: STUB_SUFFIX used to be ".stub", but this allowed the user to | 2454 PR 13049: STUB_SUFFIX used to be ".stub", but this allowed the user to |
2365 create what appeared to be a linker stub section when it actually | 2455 create what appeared to be a linker stub section when it actually |
2366 contained user code/data. For example, consider this fragment: | 2456 contained user code/data. For example, consider this fragment: |
2367 | 2457 |
2368 const char * stubborn_problems[] = { "np" }; | 2458 const char * stubborn_problems[] = { "np" }; |
2369 | 2459 |
2370 If this is compiled with "-fPIC -fdata-sections" then gcc produces a | 2460 If this is compiled with "-fPIC -fdata-sections" then gcc produces a |
2371 section called: | 2461 section called: |
2372 | 2462 |
2373 .data.rel.local.stubborn_problems | 2463 .data.rel.local.stubborn_problems |
2374 | 2464 |
2375 This then causes problems in arm32_arm_build_stubs() as it triggers: | 2465 This then causes problems in arm32_arm_build_stubs() as it triggers: |
2376 | 2466 |
2377 // Ignore non-stub sections. | 2467 // Ignore non-stub sections. |
(...skipping 20 matching lines...) Expand all Loading... |
2398 DEF_STUB(long_branch_v4t_thumb_arm_pic) \ | 2488 DEF_STUB(long_branch_v4t_thumb_arm_pic) \ |
2399 DEF_STUB(long_branch_thumb_only_pic) \ | 2489 DEF_STUB(long_branch_thumb_only_pic) \ |
2400 DEF_STUB(long_branch_any_tls_pic) \ | 2490 DEF_STUB(long_branch_any_tls_pic) \ |
2401 DEF_STUB(long_branch_v4t_thumb_tls_pic) \ | 2491 DEF_STUB(long_branch_v4t_thumb_tls_pic) \ |
2402 DEF_STUB(a8_veneer_b_cond) \ | 2492 DEF_STUB(a8_veneer_b_cond) \ |
2403 DEF_STUB(a8_veneer_b) \ | 2493 DEF_STUB(a8_veneer_b) \ |
2404 DEF_STUB(a8_veneer_bl) \ | 2494 DEF_STUB(a8_veneer_bl) \ |
2405 DEF_STUB(a8_veneer_blx) | 2495 DEF_STUB(a8_veneer_blx) |
2406 | 2496 |
2407 #define DEF_STUB(x) arm_stub_##x, | 2497 #define DEF_STUB(x) arm_stub_##x, |
2408 enum elf32_arm_stub_type { | 2498 enum elf32_arm_stub_type |
| 2499 { |
2409 arm_stub_none, | 2500 arm_stub_none, |
2410 DEF_STUBS | 2501 DEF_STUBS |
2411 /* Note the first a8_veneer type */ | 2502 /* Note the first a8_veneer type */ |
2412 arm_stub_a8_veneer_lwm = arm_stub_a8_veneer_b_cond | 2503 arm_stub_a8_veneer_lwm = arm_stub_a8_veneer_b_cond |
2413 }; | 2504 }; |
2414 #undef DEF_STUB | 2505 #undef DEF_STUB |
2415 | 2506 |
2416 typedef struct | 2507 typedef struct |
2417 { | 2508 { |
2418 const insn_sequence* template_sequence; | 2509 const insn_sequence* template_sequence; |
2419 int template_size; | 2510 int template_size; |
2420 } stub_def; | 2511 } stub_def; |
2421 | 2512 |
2422 #define DEF_STUB(x) {elf32_arm_stub_##x, ARRAY_SIZE(elf32_arm_stub_##x)}, | 2513 #define DEF_STUB(x) {elf32_arm_stub_##x, ARRAY_SIZE(elf32_arm_stub_##x)}, |
2423 static const stub_def stub_definitions[] = { | 2514 static const stub_def stub_definitions[] = |
| 2515 { |
2424 {NULL, 0}, | 2516 {NULL, 0}, |
2425 DEF_STUBS | 2517 DEF_STUBS |
2426 }; | 2518 }; |
2427 | 2519 |
2428 struct elf32_arm_stub_hash_entry | 2520 struct elf32_arm_stub_hash_entry |
2429 { | 2521 { |
2430 /* Base hash table entry structure. */ | 2522 /* Base hash table entry structure. */ |
2431 struct bfd_hash_entry root; | 2523 struct bfd_hash_entry root; |
2432 | 2524 |
2433 /* The stub section. */ | 2525 /* The stub section. */ |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2566 | 2658 |
2567 #define elf32_arm_section_data(sec) \ | 2659 #define elf32_arm_section_data(sec) \ |
2568 ((_arm_elf_section_data *) elf_section_data (sec)) | 2660 ((_arm_elf_section_data *) elf_section_data (sec)) |
2569 | 2661 |
2570 /* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum. | 2662 /* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum. |
2571 These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs), | 2663 These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs), |
2572 so may be created multiple times: we use an array of these entries whilst | 2664 so may be created multiple times: we use an array of these entries whilst |
2573 relaxing which we can refresh easily, then create stubs for each potentially | 2665 relaxing which we can refresh easily, then create stubs for each potentially |
2574 erratum-triggering instruction once we've settled on a solution. */ | 2666 erratum-triggering instruction once we've settled on a solution. */ |
2575 | 2667 |
2576 struct a8_erratum_fix { | 2668 struct a8_erratum_fix |
| 2669 { |
2577 bfd *input_bfd; | 2670 bfd *input_bfd; |
2578 asection *section; | 2671 asection *section; |
2579 bfd_vma offset; | 2672 bfd_vma offset; |
2580 bfd_vma addend; | 2673 bfd_vma addend; |
2581 unsigned long orig_insn; | 2674 unsigned long orig_insn; |
2582 char *stub_name; | 2675 char *stub_name; |
2583 enum elf32_arm_stub_type stub_type; | 2676 enum elf32_arm_stub_type stub_type; |
2584 enum arm_st_branch_type branch_type; | 2677 enum arm_st_branch_type branch_type; |
2585 }; | 2678 }; |
2586 | 2679 |
2587 /* A table of relocs applied to branches which might trigger Cortex-A8 | 2680 /* A table of relocs applied to branches which might trigger Cortex-A8 |
2588 erratum. */ | 2681 erratum. */ |
2589 | 2682 |
2590 struct a8_erratum_reloc { | 2683 struct a8_erratum_reloc |
| 2684 { |
2591 bfd_vma from; | 2685 bfd_vma from; |
2592 bfd_vma destination; | 2686 bfd_vma destination; |
2593 struct elf32_arm_link_hash_entry *hash; | 2687 struct elf32_arm_link_hash_entry *hash; |
2594 const char *sym_name; | 2688 const char *sym_name; |
2595 unsigned int r_type; | 2689 unsigned int r_type; |
2596 enum arm_st_branch_type branch_type; | 2690 enum arm_st_branch_type branch_type; |
2597 bfd_boolean non_a8_stub; | 2691 bfd_boolean non_a8_stub; |
2598 }; | 2692 }; |
2599 | 2693 |
2600 /* The size of the thread control block. */ | 2694 /* The size of the thread control block. */ |
2601 #define TCB_SIZE 8 | 2695 #define TCB_SIZE 8 |
2602 | 2696 |
2603 /* ARM-specific information about a PLT entry, over and above the usual | 2697 /* ARM-specific information about a PLT entry, over and above the usual |
2604 gotplt_union. */ | 2698 gotplt_union. */ |
2605 struct arm_plt_info { | 2699 struct arm_plt_info |
| 2700 { |
2606 /* We reference count Thumb references to a PLT entry separately, | 2701 /* We reference count Thumb references to a PLT entry separately, |
2607 so that we can emit the Thumb trampoline only if needed. */ | 2702 so that we can emit the Thumb trampoline only if needed. */ |
2608 bfd_signed_vma thumb_refcount; | 2703 bfd_signed_vma thumb_refcount; |
2609 | 2704 |
2610 /* Some references from Thumb code may be eliminated by BL->BLX | 2705 /* Some references from Thumb code may be eliminated by BL->BLX |
2611 conversion, so record them separately. */ | 2706 conversion, so record them separately. */ |
2612 bfd_signed_vma maybe_thumb_refcount; | 2707 bfd_signed_vma maybe_thumb_refcount; |
2613 | 2708 |
2614 /* How many of the recorded PLT accesses were from non-call relocations. | 2709 /* How many of the recorded PLT accesses were from non-call relocations. |
2615 This information is useful when deciding whether anything takes the | 2710 This information is useful when deciding whether anything takes the |
2616 address of an STT_GNU_IFUNC PLT. A value of 0 means that all | 2711 address of an STT_GNU_IFUNC PLT. A value of 0 means that all |
2617 non-call references to the function should resolve directly to the | 2712 non-call references to the function should resolve directly to the |
2618 real runtime target. */ | 2713 real runtime target. */ |
2619 unsigned int noncall_refcount; | 2714 unsigned int noncall_refcount; |
2620 | 2715 |
2621 /* Since PLT entries have variable size if the Thumb prologue is | 2716 /* Since PLT entries have variable size if the Thumb prologue is |
2622 used, we need to record the index into .got.plt instead of | 2717 used, we need to record the index into .got.plt instead of |
2623 recomputing it from the PLT offset. */ | 2718 recomputing it from the PLT offset. */ |
2624 bfd_signed_vma got_offset; | 2719 bfd_signed_vma got_offset; |
2625 }; | 2720 }; |
2626 | 2721 |
2627 /* Information about an .iplt entry for a local STT_GNU_IFUNC symbol. */ | 2722 /* Information about an .iplt entry for a local STT_GNU_IFUNC symbol. */ |
2628 struct arm_local_iplt_info { | 2723 struct arm_local_iplt_info |
| 2724 { |
2629 /* The information that is usually found in the generic ELF part of | 2725 /* The information that is usually found in the generic ELF part of |
2630 the hash table entry. */ | 2726 the hash table entry. */ |
2631 union gotplt_union root; | 2727 union gotplt_union root; |
2632 | 2728 |
2633 /* The information that is usually found in the ARM-specific part of | 2729 /* The information that is usually found in the ARM-specific part of |
2634 the hash table entry. */ | 2730 the hash table entry. */ |
2635 struct arm_plt_info arm; | 2731 struct arm_plt_info arm; |
2636 | 2732 |
2637 /* A list of all potential dynamic relocations against this symbol. */ | 2733 /* A list of all potential dynamic relocations against this symbol. */ |
2638 struct elf_dyn_relocs *dyn_relocs; | 2734 struct elf_dyn_relocs *dyn_relocs; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2679 elf32_arm_mkobject (bfd *abfd) | 2775 elf32_arm_mkobject (bfd *abfd) |
2680 { | 2776 { |
2681 return bfd_elf_allocate_object (abfd, sizeof (struct elf_arm_obj_tdata), | 2777 return bfd_elf_allocate_object (abfd, sizeof (struct elf_arm_obj_tdata), |
2682 ARM_ELF_DATA); | 2778 ARM_ELF_DATA); |
2683 } | 2779 } |
2684 | 2780 |
2685 #define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent)) | 2781 #define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent)) |
2686 | 2782 |
2687 /* Arm ELF linker hash entry. */ | 2783 /* Arm ELF linker hash entry. */ |
2688 struct elf32_arm_link_hash_entry | 2784 struct elf32_arm_link_hash_entry |
2689 { | 2785 { |
2690 struct elf_link_hash_entry root; | 2786 struct elf_link_hash_entry root; |
2691 | 2787 |
2692 /* Track dynamic relocs copied for this symbol. */ | 2788 /* Track dynamic relocs copied for this symbol. */ |
2693 struct elf_dyn_relocs *dyn_relocs; | 2789 struct elf_dyn_relocs *dyn_relocs; |
2694 | 2790 |
2695 /* ARM-specific PLT information. */ | 2791 /* ARM-specific PLT information. */ |
2696 struct arm_plt_info plt; | 2792 struct arm_plt_info plt; |
2697 | 2793 |
2698 #define GOT_UNKNOWN 0 | 2794 #define GOT_UNKNOWN 0 |
2699 #define GOT_NORMAL 1 | 2795 #define GOT_NORMAL 1 |
2700 #define GOT_TLS_GD 2 | 2796 #define GOT_TLS_GD 2 |
2701 #define GOT_TLS_IE 4 | 2797 #define GOT_TLS_IE 4 |
2702 #define GOT_TLS_GDESC 8 | 2798 #define GOT_TLS_GDESC 8 |
2703 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC)) | 2799 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC)) |
2704 unsigned int tls_type : 8; | 2800 unsigned int tls_type : 8; |
2705 | 2801 |
2706 /* True if the symbol's PLT entry is in .iplt rather than .plt. */ | 2802 /* True if the symbol's PLT entry is in .iplt rather than .plt. */ |
2707 unsigned int is_iplt : 1; | 2803 unsigned int is_iplt : 1; |
2708 | 2804 |
2709 unsigned int unused : 23; | 2805 unsigned int unused : 23; |
2710 | 2806 |
2711 /* Offset of the GOTPLT entry reserved for the TLS descriptor, | 2807 /* Offset of the GOTPLT entry reserved for the TLS descriptor, |
2712 starting at the end of the jump table. */ | 2808 starting at the end of the jump table. */ |
2713 bfd_vma tlsdesc_got; | 2809 bfd_vma tlsdesc_got; |
2714 | 2810 |
2715 /* The symbol marking the real symbol location for exported thumb | 2811 /* The symbol marking the real symbol location for exported thumb |
2716 symbols with Arm stubs. */ | 2812 symbols with Arm stubs. */ |
2717 struct elf_link_hash_entry *export_glue; | 2813 struct elf_link_hash_entry *export_glue; |
2718 | 2814 |
2719 /* A pointer to the most recently used stub hash entry against this | 2815 /* A pointer to the most recently used stub hash entry against this |
2720 symbol. */ | 2816 symbol. */ |
2721 struct elf32_arm_stub_hash_entry *stub_cache; | 2817 struct elf32_arm_stub_hash_entry *stub_cache; |
2722 }; | 2818 }; |
2723 | 2819 |
2724 /* Traverse an arm ELF linker hash table. */ | 2820 /* Traverse an arm ELF linker hash table. */ |
2725 #define elf32_arm_link_hash_traverse(table, func, info) \ | 2821 #define elf32_arm_link_hash_traverse(table, func, info) \ |
2726 (elf_link_hash_traverse \ | 2822 (elf_link_hash_traverse \ |
2727 (&(table)->root, \ | 2823 (&(table)->root, \ |
2728 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ | 2824 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ |
2729 (info))) | 2825 (info))) |
2730 | 2826 |
2731 /* Get the ARM elf linker hash table from a link_info structure. */ | 2827 /* Get the ARM elf linker hash table from a link_info structure. */ |
2732 #define elf32_arm_hash_table(info) \ | 2828 #define elf32_arm_hash_table(info) \ |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2822 | 2918 |
2823 /* The number of bytes in the subsequent PLT etries. */ | 2919 /* The number of bytes in the subsequent PLT etries. */ |
2824 bfd_size_type plt_entry_size; | 2920 bfd_size_type plt_entry_size; |
2825 | 2921 |
2826 /* True if the target system is VxWorks. */ | 2922 /* True if the target system is VxWorks. */ |
2827 int vxworks_p; | 2923 int vxworks_p; |
2828 | 2924 |
2829 /* True if the target system is Symbian OS. */ | 2925 /* True if the target system is Symbian OS. */ |
2830 int symbian_p; | 2926 int symbian_p; |
2831 | 2927 |
| 2928 /* True if the target system is Native Client. */ |
| 2929 int nacl_p; |
| 2930 |
2832 /* True if the target uses REL relocations. */ | 2931 /* True if the target uses REL relocations. */ |
2833 int use_rel; | 2932 int use_rel; |
2834 | 2933 |
2835 /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */ | 2934 /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */ |
2836 bfd_vma next_tls_desc_index; | 2935 bfd_vma next_tls_desc_index; |
2837 | 2936 |
2838 /* How many R_ARM_TLS_DESC relocations were generated so far. */ | 2937 /* How many R_ARM_TLS_DESC relocations were generated so far. */ |
2839 bfd_vma num_tls_desc; | 2938 bfd_vma num_tls_desc; |
2840 | 2939 |
2841 /* Short-cuts to get to dynamic linker sections. */ | 2940 /* Short-cuts to get to dynamic linker sections. */ |
2842 asection *sdynbss; | 2941 asection *sdynbss; |
2843 asection *srelbss; | 2942 asection *srelbss; |
2844 | 2943 |
2845 /* The (unloaded but important) VxWorks .rela.plt.unloaded section. */ | 2944 /* The (unloaded but important) VxWorks .rela.plt.unloaded section. */ |
2846 asection *srelplt2; | 2945 asection *srelplt2; |
2847 | 2946 |
2848 /* The offset into splt of the PLT entry for the TLS descriptor | 2947 /* The offset into splt of the PLT entry for the TLS descriptor |
2849 resolver. Special values are 0, if not necessary (or not found | 2948 resolver. Special values are 0, if not necessary (or not found |
2850 to be necessary yet), and -1 if needed but not determined | 2949 to be necessary yet), and -1 if needed but not determined |
2851 yet. */ | 2950 yet. */ |
2852 bfd_vma dt_tlsdesc_plt; | 2951 bfd_vma dt_tlsdesc_plt; |
2853 | 2952 |
2854 /* The offset into sgot of the GOT entry used by the PLT entry | 2953 /* The offset into sgot of the GOT entry used by the PLT entry |
2855 above. */ | 2954 above. */ |
2856 bfd_vma dt_tlsdesc_got; | 2955 bfd_vma dt_tlsdesc_got; |
2857 | 2956 |
2858 /* Offset in .plt section of tls_arm_trampoline. */ | 2957 /* Offset in .plt section of tls_arm_trampoline. */ |
2859 bfd_vma tls_trampoline; | 2958 bfd_vma tls_trampoline; |
2860 | 2959 |
2861 /* Data for R_ARM_TLS_LDM32 relocations. */ | 2960 /* Data for R_ARM_TLS_LDM32 relocations. */ |
2862 union | 2961 union |
2863 { | 2962 { |
2864 bfd_signed_vma refcount; | 2963 bfd_signed_vma refcount; |
2865 bfd_vma offset; | 2964 bfd_vma offset; |
2866 } tls_ldm_got; | 2965 } tls_ldm_got; |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3142 /* Create the .iplt, .rel(a).iplt and .igot.plt sections. */ | 3241 /* Create the .iplt, .rel(a).iplt and .igot.plt sections. */ |
3143 | 3242 |
3144 static bfd_boolean | 3243 static bfd_boolean |
3145 create_ifunc_sections (struct bfd_link_info *info) | 3244 create_ifunc_sections (struct bfd_link_info *info) |
3146 { | 3245 { |
3147 struct elf32_arm_link_hash_table *htab; | 3246 struct elf32_arm_link_hash_table *htab; |
3148 const struct elf_backend_data *bed; | 3247 const struct elf_backend_data *bed; |
3149 bfd *dynobj; | 3248 bfd *dynobj; |
3150 asection *s; | 3249 asection *s; |
3151 flagword flags; | 3250 flagword flags; |
3152 | 3251 |
3153 htab = elf32_arm_hash_table (info); | 3252 htab = elf32_arm_hash_table (info); |
3154 dynobj = htab->root.dynobj; | 3253 dynobj = htab->root.dynobj; |
3155 bed = get_elf_backend_data (dynobj); | 3254 bed = get_elf_backend_data (dynobj); |
3156 flags = bed->dynamic_sec_flags; | 3255 flags = bed->dynamic_sec_flags; |
3157 | 3256 |
3158 if (htab->root.iplt == NULL) | 3257 if (htab->root.iplt == NULL) |
3159 { | 3258 { |
3160 s = bfd_make_section_with_flags (dynobj, ".iplt", | 3259 s = bfd_make_section_anyway_with_flags (dynobj, ".iplt", |
3161 » » » » flags | SEC_READONLY | SEC_CODE); | 3260 » » » » » flags | SEC_READONLY | SEC_CODE); |
3162 if (s == NULL | 3261 if (s == NULL |
3163 » || !bfd_set_section_alignment (abfd, s, bed->plt_alignment)) | 3262 » || !bfd_set_section_alignment (dynobj, s, bed->plt_alignment)) |
3164 return FALSE; | 3263 return FALSE; |
3165 htab->root.iplt = s; | 3264 htab->root.iplt = s; |
3166 } | 3265 } |
3167 | 3266 |
3168 if (htab->root.irelplt == NULL) | 3267 if (htab->root.irelplt == NULL) |
3169 { | 3268 { |
3170 s = bfd_make_section_with_flags (dynobj, RELOC_SECTION (htab, ".iplt"), | 3269 s = bfd_make_section_anyway_with_flags (dynobj, |
3171 » » » » flags | SEC_READONLY); | 3270 » » » » » RELOC_SECTION (htab, ".iplt"), |
| 3271 » » » » » flags | SEC_READONLY); |
3172 if (s == NULL | 3272 if (s == NULL |
3173 » || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) | 3273 » || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align)) |
3174 return FALSE; | 3274 return FALSE; |
3175 htab->root.irelplt = s; | 3275 htab->root.irelplt = s; |
3176 } | 3276 } |
3177 | 3277 |
3178 if (htab->root.igotplt == NULL) | 3278 if (htab->root.igotplt == NULL) |
3179 { | 3279 { |
3180 s = bfd_make_section_with_flags (dynobj, ".igot.plt", flags); | 3280 s = bfd_make_section_anyway_with_flags (dynobj, ".igot.plt", flags); |
3181 if (s == NULL | 3281 if (s == NULL |
3182 || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align)) | 3282 || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align)) |
3183 return FALSE; | 3283 return FALSE; |
3184 htab->root.igotplt = s; | 3284 htab->root.igotplt = s; |
3185 } | 3285 } |
3186 return TRUE; | 3286 return TRUE; |
3187 } | 3287 } |
3188 | 3288 |
3189 /* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and | 3289 /* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and |
3190 .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our | 3290 .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our |
3191 hash table. */ | 3291 hash table. */ |
3192 | 3292 |
3193 static bfd_boolean | 3293 static bfd_boolean |
3194 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) | 3294 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) |
3195 { | 3295 { |
3196 struct elf32_arm_link_hash_table *htab; | 3296 struct elf32_arm_link_hash_table *htab; |
3197 | 3297 |
3198 htab = elf32_arm_hash_table (info); | 3298 htab = elf32_arm_hash_table (info); |
3199 if (htab == NULL) | 3299 if (htab == NULL) |
3200 return FALSE; | 3300 return FALSE; |
3201 | 3301 |
3202 if (!htab->root.sgot && !create_got_section (dynobj, info)) | 3302 if (!htab->root.sgot && !create_got_section (dynobj, info)) |
3203 return FALSE; | 3303 return FALSE; |
3204 | 3304 |
3205 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) | 3305 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) |
3206 return FALSE; | 3306 return FALSE; |
3207 | 3307 |
3208 htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); | 3308 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); |
3209 if (!info->shared) | 3309 if (!info->shared) |
3210 htab->srelbss = bfd_get_section_by_name (dynobj, | 3310 htab->srelbss = bfd_get_linker_section (dynobj, |
3211 » » » » » RELOC_SECTION (htab, ".bss")); | 3311 » » » » » RELOC_SECTION (htab, ".bss")); |
3212 | 3312 |
3213 if (htab->vxworks_p) | 3313 if (htab->vxworks_p) |
3214 { | 3314 { |
3215 if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2)) | 3315 if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2)) |
3216 return FALSE; | 3316 return FALSE; |
3217 | 3317 |
3218 if (info->shared) | 3318 if (info->shared) |
3219 { | 3319 { |
3220 htab->plt_header_size = 0; | 3320 htab->plt_header_size = 0; |
3221 htab->plt_entry_size | 3321 htab->plt_entry_size |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3352 ret->plt_header_size = 16; | 3452 ret->plt_header_size = 16; |
3353 ret->plt_entry_size = 16; | 3453 ret->plt_entry_size = 16; |
3354 #else | 3454 #else |
3355 ret->plt_header_size = 20; | 3455 ret->plt_header_size = 20; |
3356 ret->plt_entry_size = 12; | 3456 ret->plt_entry_size = 12; |
3357 #endif | 3457 #endif |
3358 ret->fix_v4bx = 0; | 3458 ret->fix_v4bx = 0; |
3359 ret->use_blx = 0; | 3459 ret->use_blx = 0; |
3360 ret->vxworks_p = 0; | 3460 ret->vxworks_p = 0; |
3361 ret->symbian_p = 0; | 3461 ret->symbian_p = 0; |
| 3462 ret->nacl_p = 0; |
3362 ret->use_rel = 1; | 3463 ret->use_rel = 1; |
3363 ret->sym_cache.abfd = NULL; | 3464 ret->sym_cache.abfd = NULL; |
3364 ret->obfd = abfd; | 3465 ret->obfd = abfd; |
3365 ret->tls_ldm_got.refcount = 0; | 3466 ret->tls_ldm_got.refcount = 0; |
3366 ret->stub_bfd = NULL; | 3467 ret->stub_bfd = NULL; |
3367 ret->add_stub_section = NULL; | 3468 ret->add_stub_section = NULL; |
3368 ret->layout_sections_again = NULL; | 3469 ret->layout_sections_again = NULL; |
3369 ret->stub_group = NULL; | 3470 ret->stub_group = NULL; |
3370 ret->top_id = 0; | 3471 ret->top_id = 0; |
3371 ret->bfd_count = 0; | 3472 ret->bfd_count = 0; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3520 &root_plt, &arm_plt) | 3621 &root_plt, &arm_plt) |
3521 && root_plt->offset != (bfd_vma) -1) | 3622 && root_plt->offset != (bfd_vma) -1) |
3522 { | 3623 { |
3523 asection *splt; | 3624 asection *splt; |
3524 | 3625 |
3525 if (hash == NULL || hash->is_iplt) | 3626 if (hash == NULL || hash->is_iplt) |
3526 splt = globals->root.iplt; | 3627 splt = globals->root.iplt; |
3527 else | 3628 else |
3528 splt = globals->root.splt; | 3629 splt = globals->root.splt; |
3529 if (splt != NULL) | 3630 if (splt != NULL) |
3530 » {» | 3631 » { |
3531 use_plt = 1; | 3632 use_plt = 1; |
3532 | 3633 |
3533 /* Note when dealing with PLT entries: the main PLT stub is in | 3634 /* Note when dealing with PLT entries: the main PLT stub is in |
3534 ARM mode, so if the branch is in Thumb mode, another | 3635 ARM mode, so if the branch is in Thumb mode, another |
3535 Thumb->ARM stub will be inserted later just before the ARM | 3636 Thumb->ARM stub will be inserted later just before the ARM |
3536 PLT stub. We don't take this extra distance into account | 3637 PLT stub. We don't take this extra distance into account |
3537 here, because if a long branch stub is needed, we'll add a | 3638 here, because if a long branch stub is needed, we'll add a |
3538 Thumb->Arm one and branch directly to the ARM PLT entry | 3639 Thumb->Arm one and branch directly to the ARM PLT entry |
3539 because it avoids spreading offset corrections in several | 3640 because it avoids spreading offset corrections in several |
3540 places. */ | 3641 places. */ |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3804 if (h != NULL) | 3905 if (h != NULL) |
3805 h->stub_cache = stub_entry; | 3906 h->stub_cache = stub_entry; |
3806 | 3907 |
3807 free (stub_name); | 3908 free (stub_name); |
3808 } | 3909 } |
3809 | 3910 |
3810 return stub_entry; | 3911 return stub_entry; |
3811 } | 3912 } |
3812 | 3913 |
3813 /* Find or create a stub section. Returns a pointer to the stub section, and | 3914 /* Find or create a stub section. Returns a pointer to the stub section, and |
3814 the section to which the stub section will be attached (in *LINK_SEC_P). | 3915 the section to which the stub section will be attached (in *LINK_SEC_P). |
3815 LINK_SEC_P may be NULL. */ | 3916 LINK_SEC_P may be NULL. */ |
3816 | 3917 |
3817 static asection * | 3918 static asection * |
3818 elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, | 3919 elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, |
3819 struct elf32_arm_link_hash_table *htab) | 3920 struct elf32_arm_link_hash_table *htab) |
3820 { | 3921 { |
3821 asection *link_sec; | 3922 asection *link_sec; |
3822 asection *stub_sec; | 3923 asection *stub_sec; |
3823 | 3924 |
3824 link_sec = htab->stub_group[section->id].link_sec; | 3925 link_sec = htab->stub_group[section->id].link_sec; |
(...skipping 17 matching lines...) Expand all Loading... |
3842 | 3943 |
3843 memcpy (s_name, link_sec->name, namelen); | 3944 memcpy (s_name, link_sec->name, namelen); |
3844 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX)); | 3945 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX)); |
3845 stub_sec = (*htab->add_stub_section) (s_name, link_sec); | 3946 stub_sec = (*htab->add_stub_section) (s_name, link_sec); |
3846 if (stub_sec == NULL) | 3947 if (stub_sec == NULL) |
3847 return NULL; | 3948 return NULL; |
3848 htab->stub_group[link_sec->id].stub_sec = stub_sec; | 3949 htab->stub_group[link_sec->id].stub_sec = stub_sec; |
3849 } | 3950 } |
3850 htab->stub_group[section->id].stub_sec = stub_sec; | 3951 htab->stub_group[section->id].stub_sec = stub_sec; |
3851 } | 3952 } |
3852 | 3953 |
3853 if (link_sec_p) | 3954 if (link_sec_p) |
3854 *link_sec_p = link_sec; | 3955 *link_sec_p = link_sec; |
3855 | 3956 |
3856 return stub_sec; | 3957 return stub_sec; |
3857 } | 3958 } |
3858 | 3959 |
3859 /* Add a new stub entry to the stub hash. Not all fields of the new | 3960 /* Add a new stub entry to the stub hash. Not all fields of the new |
3860 stub entry are initialised. */ | 3961 stub entry are initialised. */ |
3861 | 3962 |
3862 static struct elf32_arm_stub_hash_entry * | 3963 static struct elf32_arm_stub_hash_entry * |
3863 elf32_arm_add_stub (const char *stub_name, | 3964 elf32_arm_add_stub (const char *stub_name, |
3864 asection *section, | 3965 asection *section, |
3865 struct elf32_arm_link_hash_table *htab) | 3966 struct elf32_arm_link_hash_table *htab) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3913 if (htab->byteswap_code != bfd_little_endian (output_bfd)) | 4014 if (htab->byteswap_code != bfd_little_endian (output_bfd)) |
3914 bfd_putl16 (val, ptr); | 4015 bfd_putl16 (val, ptr); |
3915 else | 4016 else |
3916 bfd_putb16 (val, ptr); | 4017 bfd_putb16 (val, ptr); |
3917 } | 4018 } |
3918 | 4019 |
3919 /* If it's possible to change R_TYPE to a more efficient access | 4020 /* If it's possible to change R_TYPE to a more efficient access |
3920 model, return the new reloc type. */ | 4021 model, return the new reloc type. */ |
3921 | 4022 |
3922 static unsigned | 4023 static unsigned |
3923 elf32_arm_tls_transition (struct bfd_link_info *info, int r_type, | 4024 elf32_arm_tls_transition (struct bfd_link_info *info, int r_type, |
3924 struct elf_link_hash_entry *h) | 4025 struct elf_link_hash_entry *h) |
3925 { | 4026 { |
3926 int is_local = (h == NULL); | 4027 int is_local = (h == NULL); |
3927 | 4028 |
3928 if (info->shared || (h && h->root.type == bfd_link_hash_undefweak)) | 4029 if (info->shared || (h && h->root.type == bfd_link_hash_undefweak)) |
3929 return r_type; | 4030 return r_type; |
3930 | 4031 |
3931 /* We do not support relaxations for Old TLS models. */ | 4032 /* We do not support relaxations for Old TLS models. */ |
3932 switch (r_type) | 4033 switch (r_type) |
3933 { | 4034 { |
3934 case R_ARM_TLS_GOTDESC: | 4035 case R_ARM_TLS_GOTDESC: |
3935 case R_ARM_TLS_CALL: | 4036 case R_ARM_TLS_CALL: |
3936 case R_ARM_THM_TLS_CALL: | 4037 case R_ARM_THM_TLS_CALL: |
3937 case R_ARM_TLS_DESCSEQ: | 4038 case R_ARM_TLS_DESCSEQ: |
3938 case R_ARM_THM_TLS_DESCSEQ: | 4039 case R_ARM_THM_TLS_DESCSEQ: |
3939 return is_local ? R_ARM_TLS_LE32 : R_ARM_TLS_IE32; | 4040 return is_local ? R_ARM_TLS_LE32 : R_ARM_TLS_IE32; |
3940 } | 4041 } |
3941 | 4042 |
(...skipping 25 matching lines...) Expand all Loading... |
3967 case arm_stub_long_branch_any_arm_pic: | 4068 case arm_stub_long_branch_any_arm_pic: |
3968 case arm_stub_long_branch_any_thumb_pic: | 4069 case arm_stub_long_branch_any_thumb_pic: |
3969 case arm_stub_long_branch_v4t_thumb_thumb_pic: | 4070 case arm_stub_long_branch_v4t_thumb_thumb_pic: |
3970 case arm_stub_long_branch_v4t_arm_thumb_pic: | 4071 case arm_stub_long_branch_v4t_arm_thumb_pic: |
3971 case arm_stub_long_branch_v4t_thumb_arm_pic: | 4072 case arm_stub_long_branch_v4t_thumb_arm_pic: |
3972 case arm_stub_long_branch_thumb_only_pic: | 4073 case arm_stub_long_branch_thumb_only_pic: |
3973 case arm_stub_long_branch_any_tls_pic: | 4074 case arm_stub_long_branch_any_tls_pic: |
3974 case arm_stub_long_branch_v4t_thumb_tls_pic: | 4075 case arm_stub_long_branch_v4t_thumb_tls_pic: |
3975 case arm_stub_a8_veneer_blx: | 4076 case arm_stub_a8_veneer_blx: |
3976 return 4; | 4077 return 4; |
3977 | 4078 |
3978 default: | 4079 default: |
3979 abort (); /* Should be unreachable. */ | 4080 abort (); /* Should be unreachable. */ |
3980 } | 4081 } |
3981 } | 4082 } |
3982 | 4083 |
3983 static bfd_boolean | 4084 static bfd_boolean |
3984 arm_build_one_stub (struct bfd_hash_entry *gen_entry, | 4085 arm_build_one_stub (struct bfd_hash_entry *gen_entry, |
3985 void * in_arg) | 4086 void * in_arg) |
3986 { | 4087 { |
3987 #define MAXRELOCS 2 | 4088 #define MAXRELOCS 2 |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4505 section = section->next) | 4606 section = section->next) |
4506 { | 4607 { |
4507 bfd_byte *contents = NULL; | 4608 bfd_byte *contents = NULL; |
4508 struct _arm_elf_section_data *sec_data; | 4609 struct _arm_elf_section_data *sec_data; |
4509 unsigned int span; | 4610 unsigned int span; |
4510 bfd_vma base_vma; | 4611 bfd_vma base_vma; |
4511 | 4612 |
4512 if (elf_section_type (section) != SHT_PROGBITS | 4613 if (elf_section_type (section) != SHT_PROGBITS |
4513 || (elf_section_flags (section) & SHF_EXECINSTR) == 0 | 4614 || (elf_section_flags (section) & SHF_EXECINSTR) == 0 |
4514 || (section->flags & SEC_EXCLUDE) != 0 | 4615 || (section->flags & SEC_EXCLUDE) != 0 |
4515 || (section->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) | 4616 || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) |
4516 || (section->output_section == bfd_abs_section_ptr)) | 4617 || (section->output_section == bfd_abs_section_ptr)) |
4517 continue; | 4618 continue; |
4518 | 4619 |
4519 base_vma = section->output_section->vma + section->output_offset; | 4620 base_vma = section->output_section->vma + section->output_offset; |
4520 | 4621 |
4521 if (elf_section_data (section)->this_hdr.contents != NULL) | 4622 if (elf_section_data (section)->this_hdr.contents != NULL) |
4522 contents = elf_section_data (section)->this_hdr.contents; | 4623 contents = elf_section_data (section)->this_hdr.contents; |
4523 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents)) | 4624 else if (! bfd_malloc_and_get_section (input_bfd, section, &contents)) |
4524 return TRUE; | 4625 return TRUE; |
4525 | 4626 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4940 r_indx = ELF32_R_SYM (irela->r_info); | 5041 r_indx = ELF32_R_SYM (irela->r_info); |
4941 | 5042 |
4942 if (r_type >= (unsigned int) R_ARM_max) | 5043 if (r_type >= (unsigned int) R_ARM_max) |
4943 { | 5044 { |
4944 bfd_set_error (bfd_error_bad_value); | 5045 bfd_set_error (bfd_error_bad_value); |
4945 error_ret_free_internal: | 5046 error_ret_free_internal: |
4946 if (elf_section_data (section)->relocs == NULL) | 5047 if (elf_section_data (section)->relocs == NULL) |
4947 free (internal_relocs); | 5048 free (internal_relocs); |
4948 goto error_ret_free_local; | 5049 goto error_ret_free_local; |
4949 } | 5050 } |
4950 » » | 5051 |
4951 hash = NULL; | 5052 hash = NULL; |
4952 if (r_indx >= symtab_hdr->sh_info) | 5053 if (r_indx >= symtab_hdr->sh_info) |
4953 hash = elf32_arm_hash_entry | 5054 hash = elf32_arm_hash_entry |
4954 (elf_sym_hashes (input_bfd) | 5055 (elf_sym_hashes (input_bfd) |
4955 [r_indx - symtab_hdr->sh_info]); | 5056 [r_indx - symtab_hdr->sh_info]); |
4956 » » | 5057 |
4957 /* Only look for stubs on branch instructions, or | 5058 /* Only look for stubs on branch instructions, or |
4958 non-relaxed TLSCALL */ | 5059 non-relaxed TLSCALL */ |
4959 if ((r_type != (unsigned int) R_ARM_CALL) | 5060 if ((r_type != (unsigned int) R_ARM_CALL) |
4960 && (r_type != (unsigned int) R_ARM_THM_CALL) | 5061 && (r_type != (unsigned int) R_ARM_THM_CALL) |
4961 && (r_type != (unsigned int) R_ARM_JUMP24) | 5062 && (r_type != (unsigned int) R_ARM_JUMP24) |
4962 && (r_type != (unsigned int) R_ARM_THM_JUMP19) | 5063 && (r_type != (unsigned int) R_ARM_THM_JUMP19) |
4963 && (r_type != (unsigned int) R_ARM_THM_XPC22) | 5064 && (r_type != (unsigned int) R_ARM_THM_XPC22) |
4964 && (r_type != (unsigned int) R_ARM_THM_JUMP24) | 5065 && (r_type != (unsigned int) R_ARM_THM_JUMP24) |
4965 && (r_type != (unsigned int) R_ARM_PLT32) | 5066 && (r_type != (unsigned int) R_ARM_PLT32) |
4966 && !((r_type == (unsigned int) R_ARM_TLS_CALL | 5067 && !((r_type == (unsigned int) R_ARM_TLS_CALL |
4967 || r_type == (unsigned int) R_ARM_THM_TLS_CALL) | 5068 || r_type == (unsigned int) R_ARM_THM_TLS_CALL) |
4968 && r_type == elf32_arm_tls_transition | 5069 && r_type == elf32_arm_tls_transition |
4969 (info, r_type, &hash->root) | 5070 (info, r_type, &hash->root) |
4970 && ((hash ? hash->tls_type | 5071 && ((hash ? hash->tls_type |
4971 : (elf32_arm_local_got_tls_type | 5072 : (elf32_arm_local_got_tls_type |
4972 (input_bfd)[r_indx])) | 5073 (input_bfd)[r_indx])) |
4973 & GOT_TLS_GDESC) != 0)) | 5074 & GOT_TLS_GDESC) != 0)) |
4974 continue; | 5075 continue; |
4975 | 5076 |
4976 /* Now determine the call target, its name, value, | 5077 /* Now determine the call target, its name, value, |
4977 section. */ | 5078 section. */ |
4978 sym_sec = NULL; | 5079 sym_sec = NULL; |
4979 sym_value = 0; | 5080 sym_value = 0; |
4980 destination = 0; | 5081 destination = 0; |
4981 sym_name = NULL; | 5082 sym_name = NULL; |
4982 » » | 5083 |
4983 if (r_type == (unsigned int) R_ARM_TLS_CALL | 5084 if (r_type == (unsigned int) R_ARM_TLS_CALL |
4984 || r_type == (unsigned int) R_ARM_THM_TLS_CALL) | 5085 || r_type == (unsigned int) R_ARM_THM_TLS_CALL) |
4985 { | 5086 { |
4986 /* A non-relaxed TLS call. The target is the | 5087 /* A non-relaxed TLS call. The target is the |
4987 plt-resident trampoline and nothing to do | 5088 plt-resident trampoline and nothing to do |
4988 with the symbol. */ | 5089 with the symbol. */ |
4989 BFD_ASSERT (htab->tls_trampoline > 0); | 5090 BFD_ASSERT (htab->tls_trampoline > 0); |
4990 sym_sec = htab->root.splt; | 5091 sym_sec = htab->root.splt; |
4991 sym_value = htab->tls_trampoline; | 5092 sym_value = htab->tls_trampoline; |
4992 hash = 0; | 5093 hash = 0; |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5517 /* Thumb->ARM: Thumb->(non-interworking aware) ARM | 5618 /* Thumb->ARM: Thumb->(non-interworking aware) ARM |
5518 | 5619 |
5519 .thumb .thumb | 5620 .thumb .thumb |
5520 .align 2 .align 2 | 5621 .align 2 .align 2 |
5521 __func_from_thumb: __func_from_thumb: | 5622 __func_from_thumb: __func_from_thumb: |
5522 bx pc push {r6, lr} | 5623 bx pc push {r6, lr} |
5523 nop ldr r6, __func_addr | 5624 nop ldr r6, __func_addr |
5524 .arm mov lr, pc | 5625 .arm mov lr, pc |
5525 b func bx r6 | 5626 b func bx r6 |
5526 .arm | 5627 .arm |
5527 » » » » ;; back_to_thumb | 5628 » » » » ;; back_to_thumb |
5528 ldmia r13! {r6, lr} | 5629 ldmia r13! {r6, lr} |
5529 » » » » bx lr | 5630 » » » » bx lr |
5530 __func_addr: | 5631 __func_addr: |
5531 .word func */ | 5632 .word func */ |
5532 | 5633 |
5533 #define THUMB2ARM_GLUE_SIZE 8 | 5634 #define THUMB2ARM_GLUE_SIZE 8 |
5534 static const insn16 t2a1_bx_pc_insn = 0x4778; | 5635 static const insn16 t2a1_bx_pc_insn = 0x4778; |
5535 static const insn16 t2a2_noop_insn = 0x46c0; | 5636 static const insn16 t2a2_noop_insn = 0x46c0; |
5536 static const insn32 t2a3_b_insn = 0xea000000; | 5637 static const insn32 t2a3_b_insn = 0xea000000; |
5537 | 5638 |
5538 #define VFP11_ERRATUM_VENEER_SIZE 8 | 5639 #define VFP11_ERRATUM_VENEER_SIZE 8 |
5539 | 5640 |
5540 #define ARM_BX_VENEER_SIZE 12 | 5641 #define ARM_BX_VENEER_SIZE 12 |
5541 static const insn32 armbx1_tst_insn = 0xe3100001; | 5642 static const insn32 armbx1_tst_insn = 0xe3100001; |
5542 static const insn32 armbx2_moveq_insn = 0x01a0f000; | 5643 static const insn32 armbx2_moveq_insn = 0x01a0f000; |
5543 static const insn32 armbx3_bx_insn = 0xe12fff10; | 5644 static const insn32 armbx3_bx_insn = 0xe12fff10; |
5544 | 5645 |
5545 #ifndef ELFARM_NABI_C_INCLUDED | 5646 #ifndef ELFARM_NABI_C_INCLUDED |
5546 static void | 5647 static void |
5547 arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * na
me) | 5648 arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * na
me) |
5548 { | 5649 { |
5549 asection * s; | 5650 asection * s; |
5550 bfd_byte * contents; | 5651 bfd_byte * contents; |
5551 | 5652 |
5552 if (size == 0) | 5653 if (size == 0) |
5553 { | 5654 { |
5554 /* Do not include empty glue sections in the output. */ | 5655 /* Do not include empty glue sections in the output. */ |
5555 if (abfd != NULL) | 5656 if (abfd != NULL) |
5556 { | 5657 { |
5557 » s = bfd_get_section_by_name (abfd, name); | 5658 » s = bfd_get_linker_section (abfd, name); |
5558 if (s != NULL) | 5659 if (s != NULL) |
5559 s->flags |= SEC_EXCLUDE; | 5660 s->flags |= SEC_EXCLUDE; |
5560 } | 5661 } |
5561 return; | 5662 return; |
5562 } | 5663 } |
5563 | 5664 |
5564 BFD_ASSERT (abfd != NULL); | 5665 BFD_ASSERT (abfd != NULL); |
5565 | 5666 |
5566 s = bfd_get_section_by_name (abfd, name); | 5667 s = bfd_get_linker_section (abfd, name); |
5567 BFD_ASSERT (s != NULL); | 5668 BFD_ASSERT (s != NULL); |
5568 | 5669 |
5569 contents = (bfd_byte *) bfd_alloc (abfd, size); | 5670 contents = (bfd_byte *) bfd_alloc (abfd, size); |
5570 | 5671 |
5571 BFD_ASSERT (s->size == size); | 5672 BFD_ASSERT (s->size == size); |
5572 s->contents = contents; | 5673 s->contents = contents; |
5573 } | 5674 } |
5574 | 5675 |
5575 bfd_boolean | 5676 bfd_boolean |
5576 bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info) | 5677 bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5612 struct elf_link_hash_entry * myh; | 5713 struct elf_link_hash_entry * myh; |
5613 struct bfd_link_hash_entry * bh; | 5714 struct bfd_link_hash_entry * bh; |
5614 struct elf32_arm_link_hash_table * globals; | 5715 struct elf32_arm_link_hash_table * globals; |
5615 bfd_vma val; | 5716 bfd_vma val; |
5616 bfd_size_type size; | 5717 bfd_size_type size; |
5617 | 5718 |
5618 globals = elf32_arm_hash_table (link_info); | 5719 globals = elf32_arm_hash_table (link_info); |
5619 BFD_ASSERT (globals != NULL); | 5720 BFD_ASSERT (globals != NULL); |
5620 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 5721 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
5621 | 5722 |
5622 s = bfd_get_section_by_name | 5723 s = bfd_get_linker_section |
5623 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME); | 5724 (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME); |
5624 | 5725 |
5625 BFD_ASSERT (s != NULL); | 5726 BFD_ASSERT (s != NULL); |
5626 | 5727 |
5627 tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen (name) | 5728 tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen (name) |
5628 + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1); | 5729 + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1); |
5629 | 5730 |
5630 BFD_ASSERT (tmp_name); | 5731 BFD_ASSERT (tmp_name); |
5631 | 5732 |
5632 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); | 5733 sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5688 return; | 5789 return; |
5689 | 5790 |
5690 globals = elf32_arm_hash_table (link_info); | 5791 globals = elf32_arm_hash_table (link_info); |
5691 BFD_ASSERT (globals != NULL); | 5792 BFD_ASSERT (globals != NULL); |
5692 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 5793 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
5693 | 5794 |
5694 /* Check if this veneer has already been allocated. */ | 5795 /* Check if this veneer has already been allocated. */ |
5695 if (globals->bx_glue_offset[reg]) | 5796 if (globals->bx_glue_offset[reg]) |
5696 return; | 5797 return; |
5697 | 5798 |
5698 s = bfd_get_section_by_name | 5799 s = bfd_get_linker_section |
5699 (globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME); | 5800 (globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME); |
5700 | 5801 |
5701 BFD_ASSERT (s != NULL); | 5802 BFD_ASSERT (s != NULL); |
5702 | 5803 |
5703 /* Add symbol for veneer. */ | 5804 /* Add symbol for veneer. */ |
5704 tmp_name = (char *) | 5805 tmp_name = (char *) |
5705 bfd_malloc ((bfd_size_type) strlen (ARM_BX_GLUE_ENTRY_NAME) + 1); | 5806 bfd_malloc ((bfd_size_type) strlen (ARM_BX_GLUE_ENTRY_NAME) + 1); |
5706 | 5807 |
5707 BFD_ASSERT (tmp_name); | 5808 BFD_ASSERT (tmp_name); |
5708 | 5809 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5779 struct elf_link_hash_entry *myh; | 5880 struct elf_link_hash_entry *myh; |
5780 struct bfd_link_hash_entry *bh; | 5881 struct bfd_link_hash_entry *bh; |
5781 bfd_vma val; | 5882 bfd_vma val; |
5782 struct _arm_elf_section_data *sec_data; | 5883 struct _arm_elf_section_data *sec_data; |
5783 elf32_vfp11_erratum_list *newerr; | 5884 elf32_vfp11_erratum_list *newerr; |
5784 | 5885 |
5785 hash_table = elf32_arm_hash_table (link_info); | 5886 hash_table = elf32_arm_hash_table (link_info); |
5786 BFD_ASSERT (hash_table != NULL); | 5887 BFD_ASSERT (hash_table != NULL); |
5787 BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL); | 5888 BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL); |
5788 | 5889 |
5789 s = bfd_get_section_by_name | 5890 s = bfd_get_linker_section |
5790 (hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME); | 5891 (hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME); |
5791 | 5892 |
5792 sec_data = elf32_arm_section_data (s); | 5893 sec_data = elf32_arm_section_data (s); |
5793 | 5894 |
5794 BFD_ASSERT (s != NULL); | 5895 BFD_ASSERT (s != NULL); |
5795 | 5896 |
5796 tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen | 5897 tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen |
5797 (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10); | 5898 (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10); |
5798 | 5899 |
5799 BFD_ASSERT (tmp_name); | 5900 BFD_ASSERT (tmp_name); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5886 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE \ | 5987 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE \ |
5887 | SEC_READONLY | SEC_LINKER_CREATED) | 5988 | SEC_READONLY | SEC_LINKER_CREATED) |
5888 | 5989 |
5889 /* Create a fake section for use by the ARM backend of the linker. */ | 5990 /* Create a fake section for use by the ARM backend of the linker. */ |
5890 | 5991 |
5891 static bfd_boolean | 5992 static bfd_boolean |
5892 arm_make_glue_section (bfd * abfd, const char * name) | 5993 arm_make_glue_section (bfd * abfd, const char * name) |
5893 { | 5994 { |
5894 asection * sec; | 5995 asection * sec; |
5895 | 5996 |
5896 sec = bfd_get_section_by_name (abfd, name); | 5997 sec = bfd_get_linker_section (abfd, name); |
5897 if (sec != NULL) | 5998 if (sec != NULL) |
5898 /* Already made. */ | 5999 /* Already made. */ |
5899 return TRUE; | 6000 return TRUE; |
5900 | 6001 |
5901 sec = bfd_make_section_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS); | 6002 sec = bfd_make_section_anyway_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS); |
5902 | 6003 |
5903 if (sec == NULL | 6004 if (sec == NULL |
5904 || !bfd_set_section_alignment (abfd, sec, 2)) | 6005 || !bfd_set_section_alignment (abfd, sec, 2)) |
5905 return FALSE; | 6006 return FALSE; |
5906 | 6007 |
5907 /* Set the gc mark to prevent the section from being removed by garbage | 6008 /* Set the gc mark to prevent the section from being removed by garbage |
5908 collection, despite the fact that no relocs refer to this section. */ | 6009 collection, despite the fact that no relocs refer to this section. */ |
5909 sec->gc_mark = 1; | 6010 sec->gc_mark = 1; |
5910 | 6011 |
5911 return TRUE; | 6012 return TRUE; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5956 globals->bfd_of_glue_owner = abfd; | 6057 globals->bfd_of_glue_owner = abfd; |
5957 | 6058 |
5958 return TRUE; | 6059 return TRUE; |
5959 } | 6060 } |
5960 | 6061 |
5961 static void | 6062 static void |
5962 check_use_blx (struct elf32_arm_link_hash_table *globals) | 6063 check_use_blx (struct elf32_arm_link_hash_table *globals) |
5963 { | 6064 { |
5964 int cpu_arch; | 6065 int cpu_arch; |
5965 | 6066 |
5966 cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, | 6067 cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, |
5967 Tag_CPU_arch); | 6068 Tag_CPU_arch); |
5968 | 6069 |
5969 if (globals->fix_arm1176) | 6070 if (globals->fix_arm1176) |
5970 { | 6071 { |
5971 if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K) | 6072 if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K) |
5972 globals->use_blx = 1; | 6073 globals->use_blx = 1; |
5973 } | 6074 } |
5974 else | 6075 else |
5975 { | 6076 { |
5976 if (cpu_arch > TAG_CPU_ARCH_V4T) | 6077 if (cpu_arch > TAG_CPU_ARCH_V4T) |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6576 for (sec = abfd->sections; sec != NULL; sec = sec->next) | 6677 for (sec = abfd->sections; sec != NULL; sec = sec->next) |
6577 { | 6678 { |
6578 unsigned int i, span, first_fmac = 0, veneer_of_insn = 0; | 6679 unsigned int i, span, first_fmac = 0, veneer_of_insn = 0; |
6579 struct _arm_elf_section_data *sec_data; | 6680 struct _arm_elf_section_data *sec_data; |
6580 | 6681 |
6581 /* If we don't have executable progbits, we're not interested in this | 6682 /* If we don't have executable progbits, we're not interested in this |
6582 section. Also skip if section is to be excluded. */ | 6683 section. Also skip if section is to be excluded. */ |
6583 if (elf_section_type (sec) != SHT_PROGBITS | 6684 if (elf_section_type (sec) != SHT_PROGBITS |
6584 || (elf_section_flags (sec) & SHF_EXECINSTR) == 0 | 6685 || (elf_section_flags (sec) & SHF_EXECINSTR) == 0 |
6585 || (sec->flags & SEC_EXCLUDE) != 0 | 6686 || (sec->flags & SEC_EXCLUDE) != 0 |
6586 » || sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS | 6687 » || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS |
6587 || sec->output_section == bfd_abs_section_ptr | 6688 || sec->output_section == bfd_abs_section_ptr |
6588 || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0) | 6689 || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0) |
6589 continue; | 6690 continue; |
6590 | 6691 |
6591 sec_data = elf32_arm_section_data (sec); | 6692 sec_data = elf32_arm_section_data (sec); |
6592 | 6693 |
6593 if (sec_data->mapcount == 0) | 6694 if (sec_data->mapcount == 0) |
6594 continue; | 6695 continue; |
6595 | 6696 |
6596 if (elf_section_data (sec)->this_hdr.contents != NULL) | 6697 if (elf_section_data (sec)->this_hdr.contents != NULL) |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6911 myh = find_thumb_glue (info, name, error_message); | 7012 myh = find_thumb_glue (info, name, error_message); |
6912 if (myh == NULL) | 7013 if (myh == NULL) |
6913 return FALSE; | 7014 return FALSE; |
6914 | 7015 |
6915 globals = elf32_arm_hash_table (info); | 7016 globals = elf32_arm_hash_table (info); |
6916 BFD_ASSERT (globals != NULL); | 7017 BFD_ASSERT (globals != NULL); |
6917 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 7018 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
6918 | 7019 |
6919 my_offset = myh->root.u.def.value; | 7020 my_offset = myh->root.u.def.value; |
6920 | 7021 |
6921 s = bfd_get_section_by_name (globals->bfd_of_glue_owner, | 7022 s = bfd_get_linker_section (globals->bfd_of_glue_owner, |
6922 » » » THUMB2ARM_GLUE_SECTION_NAME); | 7023 » » » THUMB2ARM_GLUE_SECTION_NAME); |
6923 | 7024 |
6924 BFD_ASSERT (s != NULL); | 7025 BFD_ASSERT (s != NULL); |
6925 BFD_ASSERT (s->contents != NULL); | 7026 BFD_ASSERT (s->contents != NULL); |
6926 BFD_ASSERT (s->output_section != NULL); | 7027 BFD_ASSERT (s->output_section != NULL); |
6927 | 7028 |
6928 if ((my_offset & 0x01) == 0x01) | 7029 if ((my_offset & 0x01) == 0x01) |
6929 { | 7030 { |
6930 if (sym_sec != NULL | 7031 if (sym_sec != NULL |
6931 && sym_sec->owner != NULL | 7032 && sym_sec->owner != NULL |
6932 && !INTERWORK_FLAG (sym_sec->owner)) | 7033 && !INTERWORK_FLAG (sym_sec->owner)) |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7101 bfd_vma my_offset; | 7202 bfd_vma my_offset; |
7102 asection * s; | 7203 asection * s; |
7103 long int ret_offset; | 7204 long int ret_offset; |
7104 struct elf_link_hash_entry * myh; | 7205 struct elf_link_hash_entry * myh; |
7105 struct elf32_arm_link_hash_table * globals; | 7206 struct elf32_arm_link_hash_table * globals; |
7106 | 7207 |
7107 globals = elf32_arm_hash_table (info); | 7208 globals = elf32_arm_hash_table (info); |
7108 BFD_ASSERT (globals != NULL); | 7209 BFD_ASSERT (globals != NULL); |
7109 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 7210 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
7110 | 7211 |
7111 s = bfd_get_section_by_name (globals->bfd_of_glue_owner, | 7212 s = bfd_get_linker_section (globals->bfd_of_glue_owner, |
7112 » » » ARM2THUMB_GLUE_SECTION_NAME); | 7213 » » » ARM2THUMB_GLUE_SECTION_NAME); |
7113 BFD_ASSERT (s != NULL); | 7214 BFD_ASSERT (s != NULL); |
7114 BFD_ASSERT (s->contents != NULL); | 7215 BFD_ASSERT (s->contents != NULL); |
7115 BFD_ASSERT (s->output_section != NULL); | 7216 BFD_ASSERT (s->output_section != NULL); |
7116 | 7217 |
7117 myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd, | 7218 myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd, |
7118 sym_sec, val, s, error_message); | 7219 sym_sec, val, s, error_message); |
7119 if (!myh) | 7220 if (!myh) |
7120 return FALSE; | 7221 return FALSE; |
7121 | 7222 |
7122 my_offset = myh->root.u.def.value; | 7223 my_offset = myh->root.u.def.value; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7155 | 7256 |
7156 eh = elf32_arm_hash_entry (h); | 7257 eh = elf32_arm_hash_entry (h); |
7157 /* Allocate stubs for exported Thumb functions on v4t. */ | 7258 /* Allocate stubs for exported Thumb functions on v4t. */ |
7158 if (eh->export_glue == NULL) | 7259 if (eh->export_glue == NULL) |
7159 return TRUE; | 7260 return TRUE; |
7160 | 7261 |
7161 globals = elf32_arm_hash_table (info); | 7262 globals = elf32_arm_hash_table (info); |
7162 BFD_ASSERT (globals != NULL); | 7263 BFD_ASSERT (globals != NULL); |
7163 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 7264 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
7164 | 7265 |
7165 s = bfd_get_section_by_name (globals->bfd_of_glue_owner, | 7266 s = bfd_get_linker_section (globals->bfd_of_glue_owner, |
7166 » » » ARM2THUMB_GLUE_SECTION_NAME); | 7267 » » » ARM2THUMB_GLUE_SECTION_NAME); |
7167 BFD_ASSERT (s != NULL); | 7268 BFD_ASSERT (s != NULL); |
7168 BFD_ASSERT (s->contents != NULL); | 7269 BFD_ASSERT (s->contents != NULL); |
7169 BFD_ASSERT (s->output_section != NULL); | 7270 BFD_ASSERT (s->output_section != NULL); |
7170 | 7271 |
7171 sec = eh->export_glue->root.u.def.section; | 7272 sec = eh->export_glue->root.u.def.section; |
7172 | 7273 |
7173 BFD_ASSERT (sec->output_section != NULL); | 7274 BFD_ASSERT (sec->output_section != NULL); |
7174 | 7275 |
7175 val = eh->export_glue->root.u.def.value + sec->output_offset | 7276 val = eh->export_glue->root.u.def.value + sec->output_offset |
7176 + sec->output_section->vma; | 7277 + sec->output_section->vma; |
(...skipping 13 matching lines...) Expand all Loading... |
7190 { | 7291 { |
7191 bfd_byte *p; | 7292 bfd_byte *p; |
7192 bfd_vma glue_addr; | 7293 bfd_vma glue_addr; |
7193 asection *s; | 7294 asection *s; |
7194 struct elf32_arm_link_hash_table *globals; | 7295 struct elf32_arm_link_hash_table *globals; |
7195 | 7296 |
7196 globals = elf32_arm_hash_table (info); | 7297 globals = elf32_arm_hash_table (info); |
7197 BFD_ASSERT (globals != NULL); | 7298 BFD_ASSERT (globals != NULL); |
7198 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); | 7299 BFD_ASSERT (globals->bfd_of_glue_owner != NULL); |
7199 | 7300 |
7200 s = bfd_get_section_by_name (globals->bfd_of_glue_owner, | 7301 s = bfd_get_linker_section (globals->bfd_of_glue_owner, |
7201 » » » ARM_BX_GLUE_SECTION_NAME); | 7302 » » » ARM_BX_GLUE_SECTION_NAME); |
7202 BFD_ASSERT (s != NULL); | 7303 BFD_ASSERT (s != NULL); |
7203 BFD_ASSERT (s->contents != NULL); | 7304 BFD_ASSERT (s->contents != NULL); |
7204 BFD_ASSERT (s->output_section != NULL); | 7305 BFD_ASSERT (s->output_section != NULL); |
7205 | 7306 |
7206 BFD_ASSERT (globals->bx_glue_offset[reg] & 2); | 7307 BFD_ASSERT (globals->bx_glue_offset[reg] & 2); |
7207 | 7308 |
7208 glue_addr = globals->bx_glue_offset[reg] & ~(bfd_vma)3; | 7309 glue_addr = globals->bx_glue_offset[reg] & ~(bfd_vma)3; |
7209 | 7310 |
7210 if ((globals->bx_glue_offset[reg] & 1) == 0) | 7311 if ((globals->bx_glue_offset[reg] & 1) == 0) |
7211 { | 7312 { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7347 | 7448 |
7348 if (!htab->symbian_p) | 7449 if (!htab->symbian_p) |
7349 { | 7450 { |
7350 /* We also need to make an entry in the .got.plt section, which | 7451 /* We also need to make an entry in the .got.plt section, which |
7351 will be placed in the .got section by the linker script. */ | 7452 will be placed in the .got section by the linker script. */ |
7352 arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc; | 7453 arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc; |
7353 sgotplt->size += 4; | 7454 sgotplt->size += 4; |
7354 } | 7455 } |
7355 } | 7456 } |
7356 | 7457 |
| 7458 static bfd_vma |
| 7459 arm_movw_immediate (bfd_vma value) |
| 7460 { |
| 7461 return (value & 0x00000fff) | ((value & 0x0000f000) << 4); |
| 7462 } |
| 7463 |
| 7464 static bfd_vma |
| 7465 arm_movt_immediate (bfd_vma value) |
| 7466 { |
| 7467 return ((value & 0x0fff0000) >> 16) | ((value & 0xf0000000) >> 12); |
| 7468 } |
| 7469 |
7357 /* Fill in a PLT entry and its associated GOT slot. If DYNINDX == -1, | 7470 /* Fill in a PLT entry and its associated GOT slot. If DYNINDX == -1, |
7358 the entry lives in .iplt and resolves to (*SYM_VALUE)(). | 7471 the entry lives in .iplt and resolves to (*SYM_VALUE)(). |
7359 Otherwise, DYNINDX is the index of the symbol in the dynamic | 7472 Otherwise, DYNINDX is the index of the symbol in the dynamic |
7360 symbol table and SYM_VALUE is undefined. | 7473 symbol table and SYM_VALUE is undefined. |
7361 | 7474 |
7362 ROOT_PLT points to the offset of the PLT entry from the start of its | 7475 ROOT_PLT points to the offset of the PLT entry from the start of its |
7363 section (.iplt or .plt). ARM_PLT points to the symbol's ARM-specific | 7476 section (.iplt or .plt). ARM_PLT points to the symbol's ARM-specific |
7364 bookkeeping information. */ | 7477 bookkeeping information. */ |
7365 | 7478 |
7366 static void | 7479 static void |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7507 SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); | 7620 SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); |
7508 loc += RELOC_SIZE (htab); | 7621 loc += RELOC_SIZE (htab); |
7509 | 7622 |
7510 /* Create the R_ARM_ABS32 relocation referencing the | 7623 /* Create the R_ARM_ABS32 relocation referencing the |
7511 beginning of the PLT for this GOT entry. */ | 7624 beginning of the PLT for this GOT entry. */ |
7512 rel.r_offset = got_address; | 7625 rel.r_offset = got_address; |
7513 rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32); | 7626 rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32); |
7514 rel.r_addend = 0; | 7627 rel.r_addend = 0; |
7515 SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); | 7628 SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); |
7516 } | 7629 } |
| 7630 else if (htab->nacl_p) |
| 7631 { |
| 7632 /* Calculate the displacement between the PLT slot and the |
| 7633 common tail that's part of the special initial PLT slot. */ |
| 7634 int32_t tail_displacement |
| 7635 = ((splt->output_section->vma + splt->output_offset |
| 7636 + ARM_NACL_PLT_TAIL_OFFSET) |
| 7637 - (plt_address + htab->plt_entry_size + 4)); |
| 7638 BFD_ASSERT ((tail_displacement & 3) == 0); |
| 7639 tail_displacement >>= 2; |
| 7640 |
| 7641 BFD_ASSERT ((tail_displacement & 0xff000000) == 0 |
| 7642 || (-tail_displacement & 0xff000000) == 0); |
| 7643 |
| 7644 /* Calculate the displacement between the PLT slot and the entry |
| 7645 in the GOT. The offset accounts for the value produced by |
| 7646 adding to pc in the penultimate instruction of the PLT stub. */ |
| 7647 got_displacement = (got_address |
| 7648 - (plt_address + htab->plt_entry_size)); |
| 7649 |
| 7650 /* NaCl does not support interworking at all. */ |
| 7651 BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt)); |
| 7652 |
| 7653 put_arm_insn (htab, output_bfd, |
| 7654 elf32_arm_nacl_plt_entry[0] |
| 7655 | arm_movw_immediate (got_displacement), |
| 7656 ptr + 0); |
| 7657 put_arm_insn (htab, output_bfd, |
| 7658 elf32_arm_nacl_plt_entry[1] |
| 7659 | arm_movt_immediate (got_displacement), |
| 7660 ptr + 4); |
| 7661 put_arm_insn (htab, output_bfd, |
| 7662 elf32_arm_nacl_plt_entry[2], |
| 7663 ptr + 8); |
| 7664 put_arm_insn (htab, output_bfd, |
| 7665 elf32_arm_nacl_plt_entry[3] |
| 7666 | (tail_displacement & 0x00ffffff), |
| 7667 ptr + 12); |
| 7668 } |
7517 else | 7669 else |
7518 { | 7670 { |
7519 /* Calculate the displacement between the PLT slot and the | 7671 /* Calculate the displacement between the PLT slot and the |
7520 entry in the GOT. The eight-byte offset accounts for the | 7672 entry in the GOT. The eight-byte offset accounts for the |
7521 value produced by adding to pc in the first instruction | 7673 value produced by adding to pc in the first instruction |
7522 of the PLT stub. */ | 7674 of the PLT stub. */ |
7523 got_displacement = got_address - (plt_address + 8); | 7675 got_displacement = got_address - (plt_address + 8); |
7524 | 7676 |
7525 BFD_ASSERT ((got_displacement & 0xf0000000) == 0); | 7677 BFD_ASSERT ((got_displacement & 0xf0000000) == 0); |
7526 | 7678 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7647 R_ARM_{,THM_}TLS_DESCSEQ relocations, during a static link. | 7799 R_ARM_{,THM_}TLS_DESCSEQ relocations, during a static link. |
7648 | 7800 |
7649 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller | 7801 Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller |
7650 is to then call final_link_relocate. Return other values in the | 7802 is to then call final_link_relocate. Return other values in the |
7651 case of error. | 7803 case of error. |
7652 | 7804 |
7653 FIXME:When --emit-relocs is in effect, we'll emit relocs describing | 7805 FIXME:When --emit-relocs is in effect, we'll emit relocs describing |
7654 the pre-relaxed code. It would be nice if the relocs were updated | 7806 the pre-relaxed code. It would be nice if the relocs were updated |
7655 to match the optimization. */ | 7807 to match the optimization. */ |
7656 | 7808 |
7657 static bfd_reloc_status_type | 7809 static bfd_reloc_status_type |
7658 elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals, | 7810 elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals, |
7659 » » bfd *input_bfd, asection *input_sec, bfd_byte *contents, | 7811 » » bfd *input_bfd, asection *input_sec, bfd_byte *contents, |
7660 Elf_Internal_Rela *rel, unsigned long is_local) | 7812 Elf_Internal_Rela *rel, unsigned long is_local) |
7661 { | 7813 { |
7662 unsigned long insn; | 7814 unsigned long insn; |
7663 | 7815 |
7664 switch (ELF32_R_TYPE (rel->r_info)) | 7816 switch (ELF32_R_TYPE (rel->r_info)) |
7665 { | 7817 { |
7666 default: | 7818 default: |
7667 return bfd_reloc_notsupported; | 7819 return bfd_reloc_notsupported; |
7668 | 7820 |
7669 case R_ARM_TLS_GOTDESC: | 7821 case R_ARM_TLS_GOTDESC: |
7670 if (is_local) | 7822 if (is_local) |
7671 insn = 0; | 7823 insn = 0; |
7672 else | 7824 else |
7673 { | 7825 { |
7674 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); | 7826 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
7675 if (insn & 1) | 7827 if (insn & 1) |
7676 insn -= 5; /* THUMB */ | 7828 insn -= 5; /* THUMB */ |
7677 else | 7829 else |
7678 insn -= 8; /* ARM */ | 7830 insn -= 8; /* ARM */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7714 /* It's a 32 bit instruction, fetch the rest of it for | 7866 /* It's a 32 bit instruction, fetch the rest of it for |
7715 error generation. */ | 7867 error generation. */ |
7716 insn = (insn << 16) | 7868 insn = (insn << 16) |
7717 | bfd_get_16 (input_bfd, contents + rel->r_offset + 2); | 7869 | bfd_get_16 (input_bfd, contents + rel->r_offset + 2); |
7718 (*_bfd_error_handler) | 7870 (*_bfd_error_handler) |
7719 (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoli
ne"), | 7871 (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoli
ne"), |
7720 input_bfd, input_sec, (unsigned long)rel->r_offset, insn); | 7872 input_bfd, input_sec, (unsigned long)rel->r_offset, insn); |
7721 return bfd_reloc_notsupported; | 7873 return bfd_reloc_notsupported; |
7722 } | 7874 } |
7723 break; | 7875 break; |
7724 | 7876 |
7725 case R_ARM_TLS_DESCSEQ: | 7877 case R_ARM_TLS_DESCSEQ: |
7726 /* arm insn. */ | 7878 /* arm insn. */ |
7727 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); | 7879 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
7728 if ((insn & 0xffff0ff0) == 0xe08f0000) /* add rx,pc,ry */ | 7880 if ((insn & 0xffff0ff0) == 0xe08f0000) /* add rx,pc,ry */ |
7729 { | 7881 { |
7730 if (is_local) | 7882 if (is_local) |
7731 /* mov rx, ry */ | 7883 /* mov rx, ry */ |
7732 bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xffff), | 7884 bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xffff), |
7733 contents + rel->r_offset); | 7885 contents + rel->r_offset); |
7734 } | 7886 } |
(...skipping 25 matching lines...) Expand all Loading... |
7760 return bfd_reloc_notsupported; | 7912 return bfd_reloc_notsupported; |
7761 } | 7913 } |
7762 break; | 7914 break; |
7763 | 7915 |
7764 case R_ARM_TLS_CALL: | 7916 case R_ARM_TLS_CALL: |
7765 /* GD->IE relaxation, turn the instruction into 'nop' or | 7917 /* GD->IE relaxation, turn the instruction into 'nop' or |
7766 'ldr r0, [pc,r0]' */ | 7918 'ldr r0, [pc,r0]' */ |
7767 insn = is_local ? 0xe1a00000 : 0xe79f0000; | 7919 insn = is_local ? 0xe1a00000 : 0xe79f0000; |
7768 bfd_put_32 (input_bfd, insn, contents + rel->r_offset); | 7920 bfd_put_32 (input_bfd, insn, contents + rel->r_offset); |
7769 break; | 7921 break; |
7770 | 7922 |
7771 case R_ARM_THM_TLS_CALL: | 7923 case R_ARM_THM_TLS_CALL: |
7772 /* GD->IE relaxation */ | 7924 /* GD->IE relaxation */ |
7773 if (!is_local) | 7925 if (!is_local) |
7774 /* add r0,pc; ldr r0, [r0] */ | 7926 /* add r0,pc; ldr r0, [r0] */ |
7775 insn = 0x44786800; | 7927 insn = 0x44786800; |
7776 else if (arch_has_thumb2_nop (globals)) | 7928 else if (arch_has_thumb2_nop (globals)) |
7777 /* nop.w */ | 7929 /* nop.w */ |
7778 insn = 0xf3af8000; | 7930 insn = 0xf3af8000; |
7779 else | 7931 else |
7780 /* nop; nop */ | 7932 /* nop; nop */ |
7781 insn = 0xbf00bf00; | 7933 insn = 0xbf00bf00; |
7782 » | 7934 |
7783 bfd_put_16 (input_bfd, insn >> 16, contents + rel->r_offset); | 7935 bfd_put_16 (input_bfd, insn >> 16, contents + rel->r_offset); |
7784 bfd_put_16 (input_bfd, insn & 0xffff, contents + rel->r_offset + 2); | 7936 bfd_put_16 (input_bfd, insn & 0xffff, contents + rel->r_offset + 2); |
7785 break; | 7937 break; |
7786 } | 7938 } |
7787 return bfd_reloc_ok; | 7939 return bfd_reloc_ok; |
7788 } | 7940 } |
7789 | 7941 |
7790 /* For a given value of n, calculate the value of G_n as required to | 7942 /* For a given value of n, calculate the value of G_n as required to |
7791 deal with group relocations. We return it in the form of an | 7943 deal with group relocations. We return it in the form of an |
7792 encoded constant-and-rotation, together with the final residual. If n is | 7944 encoded constant-and-rotation, together with the final residual. If n is |
(...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9193 } | 9345 } |
9194 else | 9346 else |
9195 { | 9347 { |
9196 BFD_ASSERT (local_got_offsets != NULL); | 9348 BFD_ASSERT (local_got_offsets != NULL); |
9197 off = local_got_offsets[r_symndx]; | 9349 off = local_got_offsets[r_symndx]; |
9198 offplt = local_tlsdesc_gotents[r_symndx]; | 9350 offplt = local_tlsdesc_gotents[r_symndx]; |
9199 tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx]; | 9351 tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx]; |
9200 } | 9352 } |
9201 | 9353 |
9202 /* Linker relaxations happens from one of the | 9354 /* Linker relaxations happens from one of the |
9203 » R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE. */ | 9355 » R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE. */ |
9204 if (ELF32_R_TYPE(rel->r_info) != r_type) | 9356 if (ELF32_R_TYPE(rel->r_info) != r_type) |
9205 » tls_type = GOT_TLS_IE; | 9357 » tls_type = GOT_TLS_IE; |
9206 | 9358 |
9207 BFD_ASSERT (tls_type != GOT_UNKNOWN); | 9359 BFD_ASSERT (tls_type != GOT_UNKNOWN); |
9208 | 9360 |
9209 if ((off & 1) != 0) | 9361 if ((off & 1) != 0) |
9210 off &= ~1; | 9362 off &= ~1; |
9211 else | 9363 else |
9212 { | 9364 { |
9213 bfd_boolean need_relocs = FALSE; | 9365 bfd_boolean need_relocs = FALSE; |
9214 Elf_Internal_Rela outrel; | 9366 Elf_Internal_Rela outrel; |
9215 int cur_off = off; | 9367 int cur_off = off; |
(...skipping 20 matching lines...) Expand all Loading... |
9236 BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak)) | 9388 BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak)) |
9237 || info->shared); | 9389 || info->shared); |
9238 BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8 | 9390 BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8 |
9239 <= globals->root.sgotplt->size); | 9391 <= globals->root.sgotplt->size); |
9240 | 9392 |
9241 outrel.r_addend = 0; | 9393 outrel.r_addend = 0; |
9242 outrel.r_offset = (globals->root.sgotplt->output_section->vma | 9394 outrel.r_offset = (globals->root.sgotplt->output_section->vma |
9243 + globals->root.sgotplt->output_offset | 9395 + globals->root.sgotplt->output_offset |
9244 + offplt | 9396 + offplt |
9245 + globals->sgotplt_jump_table_size); | 9397 + globals->sgotplt_jump_table_size); |
9246 » » | 9398 |
9247 outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DESC); | 9399 outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DESC); |
9248 sreloc = globals->root.srelplt; | 9400 sreloc = globals->root.srelplt; |
9249 loc = sreloc->contents; | 9401 loc = sreloc->contents; |
9250 loc += globals->next_tls_desc_index++ * RELOC_SIZE (globals); | 9402 loc += globals->next_tls_desc_index++ * RELOC_SIZE (globals); |
9251 BFD_ASSERT (loc + RELOC_SIZE (globals) | 9403 BFD_ASSERT (loc + RELOC_SIZE (globals) |
9252 <= sreloc->contents + sreloc->size); | 9404 <= sreloc->contents + sreloc->size); |
9253 | 9405 |
9254 SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc); | 9406 SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc); |
9255 | 9407 |
9256 /* For globals, the first word in the relocation gets | 9408 /* For globals, the first word in the relocation gets |
9257 the relocation index and the top bit set, or zero, | 9409 the relocation index and the top bit set, or zero, |
9258 if we're binding now. For locals, it gets the | 9410 if we're binding now. For locals, it gets the |
9259 symbol's offset in the tls section. */ | 9411 symbol's offset in the tls section. */ |
9260 bfd_put_32 (output_bfd, | 9412 bfd_put_32 (output_bfd, |
9261 !h ? value - elf_hash_table (info)->tls_sec->vma | 9413 !h ? value - elf_hash_table (info)->tls_sec->vma |
9262 : info->flags & DF_BIND_NOW ? 0 | 9414 : info->flags & DF_BIND_NOW ? 0 |
9263 : 0x80000000 | ELF32_R_SYM (outrel.r_info), | 9415 : 0x80000000 | ELF32_R_SYM (outrel.r_info), |
9264 » » » globals->root.sgotplt->contents + offplt + | 9416 » » » globals->root.sgotplt->contents + offplt |
9265 » » » globals->sgotplt_jump_table_size); | 9417 » » » + globals->sgotplt_jump_table_size); |
9266 » » | 9418 |
9267 /* Second word in the relocation is always zero. */ | 9419 /* Second word in the relocation is always zero. */ |
9268 bfd_put_32 (output_bfd, 0, | 9420 bfd_put_32 (output_bfd, 0, |
9269 » » » globals->root.sgotplt->contents + offplt + | 9421 » » » globals->root.sgotplt->contents + offplt |
9270 » » » globals->sgotplt_jump_table_size + 4); | 9422 » » » + globals->sgotplt_jump_table_size + 4); |
9271 } | 9423 } |
9272 if (tls_type & GOT_TLS_GD) | 9424 if (tls_type & GOT_TLS_GD) |
9273 { | 9425 { |
9274 if (need_relocs) | 9426 if (need_relocs) |
9275 { | 9427 { |
9276 outrel.r_addend = 0; | 9428 outrel.r_addend = 0; |
9277 outrel.r_offset = (sgot->output_section->vma | 9429 outrel.r_offset = (sgot->output_section->vma |
9278 + sgot->output_offset | 9430 + sgot->output_offset |
9279 + cur_off); | 9431 + cur_off); |
9280 outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32); | 9432 outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9380 + stub_entry->stub_sec->output_section->vma); | 9532 + stub_entry->stub_sec->output_section->vma); |
9381 } | 9533 } |
9382 else | 9534 else |
9383 offset = (globals->root.splt->output_section->vma | 9535 offset = (globals->root.splt->output_section->vma |
9384 + globals->root.splt->output_offset | 9536 + globals->root.splt->output_offset |
9385 + globals->tls_trampoline); | 9537 + globals->tls_trampoline); |
9386 | 9538 |
9387 if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL) | 9539 if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL) |
9388 { | 9540 { |
9389 unsigned long inst; | 9541 unsigned long inst; |
9390 » » | 9542 |
9391 » » offset -= (input_section->output_section->vma + | 9543 » » offset -= (input_section->output_section->vma |
9392 » » » input_section->output_offset + rel->r_offset + 8); | 9544 » » » + input_section->output_offset |
| 9545 » » » + rel->r_offset + 8); |
9393 | 9546 |
9394 inst = offset >> 2; | 9547 inst = offset >> 2; |
9395 inst &= 0x00ffffff; | 9548 inst &= 0x00ffffff; |
9396 value = inst | (globals->use_blx ? 0xfa000000 : 0xeb000000); | 9549 value = inst | (globals->use_blx ? 0xfa000000 : 0xeb000000); |
9397 } | 9550 } |
9398 else | 9551 else |
9399 { | 9552 { |
9400 /* Thumb blx encodes the offset in a complicated | 9553 /* Thumb blx encodes the offset in a complicated |
9401 fashion. */ | 9554 fashion. */ |
9402 unsigned upper_insn, lower_insn; | 9555 unsigned upper_insn, lower_insn; |
9403 unsigned neg; | 9556 unsigned neg; |
9404 | 9557 |
9405 » » offset -= (input_section->output_section->vma + | 9558 » » offset -= (input_section->output_section->vma |
9406 » » » input_section->output_offset | 9559 » » » + input_section->output_offset |
9407 + rel->r_offset + 4); | 9560 + rel->r_offset + 4); |
9408 » | 9561 |
9409 if (stub_type != arm_stub_none | 9562 if (stub_type != arm_stub_none |
9410 && arm_stub_is_thumb (stub_type)) | 9563 && arm_stub_is_thumb (stub_type)) |
9411 { | 9564 { |
9412 lower_insn = 0xd000; | 9565 lower_insn = 0xd000; |
9413 } | 9566 } |
9414 else | 9567 else |
9415 { | 9568 { |
9416 lower_insn = 0xc000; | 9569 lower_insn = 0xc000; |
9417 /* Round up the offset to a word boundary */ | 9570 /* Round up the offset to a word boundary */ |
9418 offset = (offset + 2) & ~2; | 9571 offset = (offset + 2) & ~2; |
(...skipping 12 matching lines...) Expand all Loading... |
9431 } | 9584 } |
9432 } | 9585 } |
9433 /* These relocations needs special care, as besides the fact | 9586 /* These relocations needs special care, as besides the fact |
9434 they point somewhere in .gotplt, the addend must be | 9587 they point somewhere in .gotplt, the addend must be |
9435 adjusted accordingly depending on the type of instruction | 9588 adjusted accordingly depending on the type of instruction |
9436 we refer to */ | 9589 we refer to */ |
9437 else if ((r_type == R_ARM_TLS_GOTDESC) && (tls_type & GOT_TLS_GDESC)) | 9590 else if ((r_type == R_ARM_TLS_GOTDESC) && (tls_type & GOT_TLS_GDESC)) |
9438 { | 9591 { |
9439 unsigned long data, insn; | 9592 unsigned long data, insn; |
9440 unsigned thumb; | 9593 unsigned thumb; |
9441 » | 9594 |
9442 data = bfd_get_32 (input_bfd, hit_data); | 9595 data = bfd_get_32 (input_bfd, hit_data); |
9443 thumb = data & 1; | 9596 thumb = data & 1; |
9444 data &= ~1u; | 9597 data &= ~1u; |
9445 » | 9598 |
9446 if (thumb) | 9599 if (thumb) |
9447 { | 9600 { |
9448 insn = bfd_get_16 (input_bfd, contents + rel->r_offset - data); | 9601 insn = bfd_get_16 (input_bfd, contents + rel->r_offset - data); |
9449 if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800) | 9602 if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800) |
9450 insn = (insn << 16) | 9603 insn = (insn << 16) |
9451 | bfd_get_16 (input_bfd, | 9604 | bfd_get_16 (input_bfd, |
9452 contents + rel->r_offset - data + 2); | 9605 contents + rel->r_offset - data + 2); |
9453 if ((insn & 0xf800c000) == 0xf000c000) | 9606 if ((insn & 0xf800c000) == 0xf000c000) |
9454 /* bl/blx */ | 9607 /* bl/blx */ |
9455 value = -6; | 9608 value = -6; |
(...skipping 16 matching lines...) Expand all Loading... |
9472 switch (insn >> 24) | 9625 switch (insn >> 24) |
9473 { | 9626 { |
9474 case 0xeb: /* bl */ | 9627 case 0xeb: /* bl */ |
9475 case 0xfa: /* blx */ | 9628 case 0xfa: /* blx */ |
9476 value = -4; | 9629 value = -4; |
9477 break; | 9630 break; |
9478 | 9631 |
9479 case 0xe0: /* add */ | 9632 case 0xe0: /* add */ |
9480 value = -8; | 9633 value = -8; |
9481 break; | 9634 break; |
9482 » » | 9635 |
9483 default: | 9636 default: |
9484 (*_bfd_error_handler) | 9637 (*_bfd_error_handler) |
9485 (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' referen
ced by TLS_GOTDESC"), | 9638 (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' referen
ced by TLS_GOTDESC"), |
9486 input_bfd, input_section, | 9639 input_bfd, input_section, |
9487 (unsigned long)rel->r_offset, insn); | 9640 (unsigned long)rel->r_offset, insn); |
9488 return bfd_reloc_notsupported; | 9641 return bfd_reloc_notsupported; |
9489 } | 9642 } |
9490 } | 9643 } |
9491 | 9644 |
9492 value += ((globals->root.sgotplt->output_section->vma | 9645 value += ((globals->root.sgotplt->output_section->vma |
9493 + globals->root.sgotplt->output_offset + off) | 9646 + globals->root.sgotplt->output_offset + off) |
9494 - (input_section->output_section->vma | 9647 - (input_section->output_section->vma |
9495 + input_section->output_offset | 9648 + input_section->output_offset |
9496 + rel->r_offset) | 9649 + rel->r_offset) |
9497 + globals->sgotplt_jump_table_size); | 9650 + globals->sgotplt_jump_table_size); |
9498 } | 9651 } |
9499 else | 9652 else |
9500 value = ((globals->root.sgot->output_section->vma | 9653 value = ((globals->root.sgot->output_section->vma |
9501 + globals->root.sgot->output_offset + off) | 9654 + globals->root.sgot->output_offset + off) |
9502 - (input_section->output_section->vma | 9655 - (input_section->output_section->vma |
9503 + input_section->output_offset + rel->r_offset)); | 9656 + input_section->output_offset + rel->r_offset)); |
9504 | 9657 |
9505 return _bfd_final_link_relocate (howto, input_bfd, input_section, | 9658 return _bfd_final_link_relocate (howto, input_bfd, input_section, |
9506 contents, rel->r_offset, value, | 9659 contents, rel->r_offset, value, |
9507 rel->r_addend); | 9660 rel->r_addend); |
9508 } | 9661 } |
9509 | 9662 |
9510 case R_ARM_TLS_LE32: | 9663 case R_ARM_TLS_LE32: |
9511 if (info->shared && !info->pie) | 9664 if (info->shared && !info->pie) |
9512 { | 9665 { |
9513 (*_bfd_error_handler) | 9666 (*_bfd_error_handler) |
9514 (_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared
object"), | 9667 (_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared
object"), |
9515 input_bfd, input_section, | 9668 input_bfd, input_section, |
9516 (long) rel->r_offset, howto->name); | 9669 (long) rel->r_offset, howto->name); |
9517 » return (bfd_reloc_status_type) FALSE; | 9670 » return bfd_reloc_notsupported; |
9518 } | 9671 } |
9519 else | 9672 else |
9520 value = tpoff (info, value); | 9673 value = tpoff (info, value); |
9521 | 9674 |
9522 return _bfd_final_link_relocate (howto, input_bfd, input_section, | 9675 return _bfd_final_link_relocate (howto, input_bfd, input_section, |
9523 contents, rel->r_offset, value, | 9676 contents, rel->r_offset, value, |
9524 rel->r_addend); | 9677 rel->r_addend); |
9525 | 9678 |
9526 case R_ARM_V4BX: | 9679 case R_ARM_V4BX: |
9527 if (globals->fix_v4bx) | 9680 if (globals->fix_v4bx) |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10215 && bfd_is_und_section (sec) | 10368 && bfd_is_und_section (sec) |
10216 && ELF_ST_BIND (sym->st_info) != STB_WEAK) | 10369 && ELF_ST_BIND (sym->st_info) != STB_WEAK) |
10217 { | 10370 { |
10218 if (!info->callbacks->undefined_symbol | 10371 if (!info->callbacks->undefined_symbol |
10219 (info, bfd_elf_string_from_elf_section | 10372 (info, bfd_elf_string_from_elf_section |
10220 (input_bfd, symtab_hdr->sh_link, sym->st_name), | 10373 (input_bfd, symtab_hdr->sh_link, sym->st_name), |
10221 input_bfd, input_section, | 10374 input_bfd, input_section, |
10222 rel->r_offset, TRUE)) | 10375 rel->r_offset, TRUE)) |
10223 return FALSE; | 10376 return FALSE; |
10224 } | 10377 } |
10225 » | 10378 |
10226 if (globals->use_rel) | 10379 if (globals->use_rel) |
10227 { | 10380 { |
10228 relocation = (sec->output_section->vma | 10381 relocation = (sec->output_section->vma |
10229 + sec->output_offset | 10382 + sec->output_offset |
10230 + sym->st_value); | 10383 + sym->st_value); |
10231 if (!info->relocatable | 10384 if (!info->relocatable |
10232 && (sec->flags & SEC_MERGE) | 10385 && (sec->flags & SEC_MERGE) |
10233 && ELF_ST_TYPE (sym->st_info) == STT_SECTION) | 10386 && ELF_ST_TYPE (sym->st_info) == STT_SECTION) |
10234 { | 10387 { |
10235 asection *msec; | 10388 asection *msec; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10324 bfd_boolean warned; | 10477 bfd_boolean warned; |
10325 | 10478 |
10326 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, | 10479 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
10327 r_symndx, symtab_hdr, sym_hashes, | 10480 r_symndx, symtab_hdr, sym_hashes, |
10328 h, sec, relocation, | 10481 h, sec, relocation, |
10329 unresolved_reloc, warned); | 10482 unresolved_reloc, warned); |
10330 | 10483 |
10331 sym_type = h->type; | 10484 sym_type = h->type; |
10332 } | 10485 } |
10333 | 10486 |
10334 if (sec != NULL && elf_discarded_section (sec)) | 10487 if (sec != NULL && discarded_section (sec)) |
10335 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, | 10488 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
10336 » » » » » rel, relend, howto, contents); | 10489 » » » » » rel, 1, relend, howto, 0, contents); |
10337 | 10490 |
10338 if (info->relocatable) | 10491 if (info->relocatable) |
10339 { | 10492 { |
10340 /* This is a relocatable link. We don't have to change | 10493 /* This is a relocatable link. We don't have to change |
10341 anything, unless the reloc is against a section symbol, | 10494 anything, unless the reloc is against a section symbol, |
10342 in which case we have to adjust according to where the | 10495 in which case we have to adjust according to where the |
10343 section symbol winds up in the output section. */ | 10496 section symbol winds up in the output section. */ |
10344 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) | 10497 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) |
10345 { | 10498 { |
10346 if (globals->use_rel) | 10499 if (globals->use_rel) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10380 name); | 10533 name); |
10381 } | 10534 } |
10382 | 10535 |
10383 /* We call elf32_arm_final_link_relocate unless we're completely | 10536 /* We call elf32_arm_final_link_relocate unless we're completely |
10384 done, i.e., the relaxation produced the final output we want, | 10537 done, i.e., the relaxation produced the final output we want, |
10385 and we won't let anybody mess with it. Also, we have to do | 10538 and we won't let anybody mess with it. Also, we have to do |
10386 addend adjustments in case of a R_ARM_TLS_GOTDESC relocation | 10539 addend adjustments in case of a R_ARM_TLS_GOTDESC relocation |
10387 both in relaxed and non-relaxed cases */ | 10540 both in relaxed and non-relaxed cases */ |
10388 if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type) | 10541 if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type) |
10389 || (IS_ARM_TLS_GNU_RELOC (r_type) | 10542 || (IS_ARM_TLS_GNU_RELOC (r_type) |
10390 » && !((h ? elf32_arm_hash_entry (h)->tls_type : | 10543 » && !((h ? elf32_arm_hash_entry (h)->tls_type : |
10391 elf32_arm_local_got_tls_type (input_bfd)[r_symndx]) | 10544 elf32_arm_local_got_tls_type (input_bfd)[r_symndx]) |
10392 & GOT_TLS_GDESC))) | 10545 & GOT_TLS_GDESC))) |
10393 { | 10546 { |
10394 r = elf32_arm_tls_relax (globals, input_bfd, input_section, | 10547 r = elf32_arm_tls_relax (globals, input_bfd, input_section, |
10395 contents, rel, h == NULL); | 10548 contents, rel, h == NULL); |
10396 /* This may have been marked unresolved because it came from | 10549 /* This may have been marked unresolved because it came from |
10397 a shared library. But we've just dealt with that. */ | 10550 a shared library. But we've just dealt with that. */ |
10398 unresolved_reloc = 0; | 10551 unresolved_reloc = 0; |
10399 } | 10552 } |
10400 else | 10553 else |
10401 r = bfd_reloc_continue; | 10554 r = bfd_reloc_continue; |
10402 | 10555 |
10403 if (r == bfd_reloc_continue) | 10556 if (r == bfd_reloc_continue) |
10404 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, | 10557 r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, |
10405 input_section, contents, rel, | 10558 input_section, contents, rel, |
10406 relocation, info, sec, name, sym_type, | 10559 relocation, info, sec, name, sym_type, |
10407 (h ? h->target_internal | 10560 (h ? h->target_internal |
10408 : ARM_SYM_BRANCH_TYPE (sym)), h, | 10561 : ARM_SYM_BRANCH_TYPE (sym)), h, |
10409 &unresolved_reloc, &error_message); | 10562 &unresolved_reloc, &error_message); |
10410 | 10563 |
10411 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections | 10564 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections |
10412 because such sections are not SEC_ALLOC and thus ld.so will | 10565 because such sections are not SEC_ALLOC and thus ld.so will |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10488 | 10641 |
10489 static void | 10642 static void |
10490 add_unwind_table_edit (arm_unwind_table_edit **head, | 10643 add_unwind_table_edit (arm_unwind_table_edit **head, |
10491 arm_unwind_table_edit **tail, | 10644 arm_unwind_table_edit **tail, |
10492 arm_unwind_edit_type type, | 10645 arm_unwind_edit_type type, |
10493 asection *linked_section, | 10646 asection *linked_section, |
10494 unsigned int tindex) | 10647 unsigned int tindex) |
10495 { | 10648 { |
10496 arm_unwind_table_edit *new_edit = (arm_unwind_table_edit *) | 10649 arm_unwind_table_edit *new_edit = (arm_unwind_table_edit *) |
10497 xmalloc (sizeof (arm_unwind_table_edit)); | 10650 xmalloc (sizeof (arm_unwind_table_edit)); |
10498 | 10651 |
10499 new_edit->type = type; | 10652 new_edit->type = type; |
10500 new_edit->linked_section = linked_section; | 10653 new_edit->linked_section = linked_section; |
10501 new_edit->index = tindex; | 10654 new_edit->index = tindex; |
10502 | 10655 |
10503 if (tindex > 0) | 10656 if (tindex > 0) |
10504 { | 10657 { |
10505 new_edit->next = NULL; | 10658 new_edit->next = NULL; |
10506 | 10659 |
10507 if (*tail) | 10660 if (*tail) |
10508 (*tail)->next = new_edit; | 10661 (*tail)->next = new_edit; |
10509 | 10662 |
10510 (*tail) = new_edit; | 10663 (*tail) = new_edit; |
10511 | 10664 |
10512 if (!*head) | 10665 if (!*head) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10550 add_unwind_table_edit ( | 10703 add_unwind_table_edit ( |
10551 &exidx_arm_data->u.exidx.unwind_edit_list, | 10704 &exidx_arm_data->u.exidx.unwind_edit_list, |
10552 &exidx_arm_data->u.exidx.unwind_edit_tail, | 10705 &exidx_arm_data->u.exidx.unwind_edit_tail, |
10553 INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX); | 10706 INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX); |
10554 | 10707 |
10555 adjust_exidx_size(exidx_sec, 8); | 10708 adjust_exidx_size(exidx_sec, 8); |
10556 } | 10709 } |
10557 | 10710 |
10558 /* Scan .ARM.exidx tables, and create a list describing edits which should be | 10711 /* Scan .ARM.exidx tables, and create a list describing edits which should be |
10559 made to those tables, such that: | 10712 made to those tables, such that: |
10560 | 10713 |
10561 1. Regions without unwind data are marked with EXIDX_CANTUNWIND entries. | 10714 1. Regions without unwind data are marked with EXIDX_CANTUNWIND entries. |
10562 2. Duplicate entries are merged together (EXIDX_CANTUNWIND, or unwind | 10715 2. Duplicate entries are merged together (EXIDX_CANTUNWIND, or unwind |
10563 codes which have been inlined into the index). | 10716 codes which have been inlined into the index). |
10564 | 10717 |
10565 If MERGE_EXIDX_ENTRIES is false, duplicate entries are not merged. | 10718 If MERGE_EXIDX_ENTRIES is false, duplicate entries are not merged. |
10566 | 10719 |
10567 The edits are applied when the tables are written | 10720 The edits are applied when the tables are written |
10568 (in elf32_arm_write_section). | 10721 (in elf32_arm_write_section). */ |
10569 */ | |
10570 | 10722 |
10571 bfd_boolean | 10723 bfd_boolean |
10572 elf32_arm_fix_exidx_coverage (asection **text_section_order, | 10724 elf32_arm_fix_exidx_coverage (asection **text_section_order, |
10573 unsigned int num_text_sections, | 10725 unsigned int num_text_sections, |
10574 struct bfd_link_info *info, | 10726 struct bfd_link_info *info, |
10575 bfd_boolean merge_exidx_entries) | 10727 bfd_boolean merge_exidx_entries) |
10576 { | 10728 { |
10577 bfd *inp; | 10729 bfd *inp; |
10578 unsigned int last_second_word = 0, i; | 10730 unsigned int last_second_word = 0, i; |
10579 asection *last_exidx_sec = NULL; | 10731 asection *last_exidx_sec = NULL; |
10580 asection *last_text_sec = NULL; | 10732 asection *last_text_sec = NULL; |
10581 int last_unwind_type = -1; | 10733 int last_unwind_type = -1; |
10582 | 10734 |
10583 /* Walk over all EXIDX sections, and create backlinks from the corrsponding | 10735 /* Walk over all EXIDX sections, and create backlinks from the corrsponding |
10584 text sections. */ | 10736 text sections. */ |
10585 for (inp = info->input_bfds; inp != NULL; inp = inp->link_next) | 10737 for (inp = info->input_bfds; inp != NULL; inp = inp->link_next) |
10586 { | 10738 { |
10587 asection *sec; | 10739 asection *sec; |
10588 | 10740 |
10589 for (sec = inp->sections; sec != NULL; sec = sec->next) | 10741 for (sec = inp->sections; sec != NULL; sec = sec->next) |
10590 { | 10742 { |
10591 struct bfd_elf_section_data *elf_sec = elf_section_data (sec); | 10743 struct bfd_elf_section_data *elf_sec = elf_section_data (sec); |
10592 Elf_Internal_Shdr *hdr = &elf_sec->this_hdr; | 10744 Elf_Internal_Shdr *hdr = &elf_sec->this_hdr; |
10593 » | 10745 |
10594 if (!hdr || hdr->sh_type != SHT_ARM_EXIDX) | 10746 if (!hdr || hdr->sh_type != SHT_ARM_EXIDX) |
10595 continue; | 10747 continue; |
10596 » | 10748 |
10597 if (elf_sec->linked_to) | 10749 if (elf_sec->linked_to) |
10598 { | 10750 { |
10599 Elf_Internal_Shdr *linked_hdr | 10751 Elf_Internal_Shdr *linked_hdr |
10600 = &elf_section_data (elf_sec->linked_to)->this_hdr; | 10752 = &elf_section_data (elf_sec->linked_to)->this_hdr; |
10601 struct _arm_elf_section_data *linked_sec_arm_data | 10753 struct _arm_elf_section_data *linked_sec_arm_data |
10602 = get_arm_elf_section_data (linked_hdr->bfd_section); | 10754 = get_arm_elf_section_data (linked_hdr->bfd_section); |
10603 | 10755 |
10604 if (linked_sec_arm_data == NULL) | 10756 if (linked_sec_arm_data == NULL) |
10605 continue; | 10757 continue; |
10606 | 10758 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10648 continue; | 10800 continue; |
10649 } | 10801 } |
10650 | 10802 |
10651 /* Skip /DISCARD/ sections. */ | 10803 /* Skip /DISCARD/ sections. */ |
10652 if (bfd_is_abs_section (exidx_sec->output_section)) | 10804 if (bfd_is_abs_section (exidx_sec->output_section)) |
10653 continue; | 10805 continue; |
10654 | 10806 |
10655 hdr = &elf_section_data (exidx_sec)->this_hdr; | 10807 hdr = &elf_section_data (exidx_sec)->this_hdr; |
10656 if (hdr->sh_type != SHT_ARM_EXIDX) | 10808 if (hdr->sh_type != SHT_ARM_EXIDX) |
10657 continue; | 10809 continue; |
10658 | 10810 |
10659 exidx_arm_data = get_arm_elf_section_data (exidx_sec); | 10811 exidx_arm_data = get_arm_elf_section_data (exidx_sec); |
10660 if (exidx_arm_data == NULL) | 10812 if (exidx_arm_data == NULL) |
10661 continue; | 10813 continue; |
10662 | 10814 |
10663 ibfd = exidx_sec->owner; | 10815 ibfd = exidx_sec->owner; |
10664 » | 10816 |
10665 if (hdr->contents != NULL) | 10817 if (hdr->contents != NULL) |
10666 contents = hdr->contents; | 10818 contents = hdr->contents; |
10667 else if (! bfd_malloc_and_get_section (ibfd, exidx_sec, &contents)) | 10819 else if (! bfd_malloc_and_get_section (ibfd, exidx_sec, &contents)) |
10668 /* An error? */ | 10820 /* An error? */ |
10669 continue; | 10821 continue; |
10670 | 10822 |
10671 for (j = 0; j < hdr->sh_size; j += 8) | 10823 for (j = 0; j < hdr->sh_size; j += 8) |
10672 { | 10824 { |
10673 unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4); | 10825 unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4); |
10674 int unwind_type; | 10826 int unwind_type; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10706 last_unwind_type = unwind_type; | 10858 last_unwind_type = unwind_type; |
10707 } | 10859 } |
10708 | 10860 |
10709 /* Free contents if we allocated it ourselves. */ | 10861 /* Free contents if we allocated it ourselves. */ |
10710 if (contents != hdr->contents) | 10862 if (contents != hdr->contents) |
10711 free (contents); | 10863 free (contents); |
10712 | 10864 |
10713 /* Record edits to be applied later (in elf32_arm_write_section). */ | 10865 /* Record edits to be applied later (in elf32_arm_write_section). */ |
10714 exidx_arm_data->u.exidx.unwind_edit_list = unwind_edit_head; | 10866 exidx_arm_data->u.exidx.unwind_edit_list = unwind_edit_head; |
10715 exidx_arm_data->u.exidx.unwind_edit_tail = unwind_edit_tail; | 10867 exidx_arm_data->u.exidx.unwind_edit_tail = unwind_edit_tail; |
10716 » | 10868 |
10717 if (deleted_exidx_bytes > 0) | 10869 if (deleted_exidx_bytes > 0) |
10718 adjust_exidx_size(exidx_sec, -deleted_exidx_bytes); | 10870 adjust_exidx_size(exidx_sec, -deleted_exidx_bytes); |
10719 | 10871 |
10720 last_exidx_sec = exidx_sec; | 10872 last_exidx_sec = exidx_sec; |
10721 last_text_sec = sec; | 10873 last_text_sec = sec; |
10722 } | 10874 } |
10723 | 10875 |
10724 /* Add terminating CANTUNWIND entry. */ | 10876 /* Add terminating CANTUNWIND entry. */ |
10725 if (last_exidx_sec && last_unwind_type != 0) | 10877 if (last_exidx_sec && last_unwind_type != 0) |
10726 insert_cantunwind_after(last_text_sec, last_exidx_sec); | 10878 insert_cantunwind_after(last_text_sec, last_exidx_sec); |
10727 | 10879 |
10728 return TRUE; | 10880 return TRUE; |
10729 } | 10881 } |
10730 | 10882 |
10731 static bfd_boolean | 10883 static bfd_boolean |
10732 elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd, | 10884 elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd, |
10733 bfd *ibfd, const char *name) | 10885 bfd *ibfd, const char *name) |
10734 { | 10886 { |
10735 asection *sec, *osec; | 10887 asection *sec, *osec; |
10736 | 10888 |
10737 sec = bfd_get_section_by_name (ibfd, name); | 10889 sec = bfd_get_linker_section (ibfd, name); |
10738 if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0) | 10890 if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0) |
10739 return TRUE; | 10891 return TRUE; |
10740 | 10892 |
10741 osec = sec->output_section; | 10893 osec = sec->output_section; |
10742 if (elf32_arm_write_section (obfd, info, sec, sec->contents)) | 10894 if (elf32_arm_write_section (obfd, info, sec, sec->contents)) |
10743 return TRUE; | 10895 return TRUE; |
10744 | 10896 |
10745 if (! bfd_set_section_contents (obfd, osec, sec->contents, | 10897 if (! bfd_set_section_contents (obfd, osec, sec->contents, |
10746 sec->output_offset, sec->size)) | 10898 sec->output_offset, sec->size)) |
10747 return FALSE; | 10899 return FALSE; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10800 | 10952 |
10801 if (! elf32_arm_output_glue_section (info, abfd, | 10953 if (! elf32_arm_output_glue_section (info, abfd, |
10802 globals->bfd_of_glue_owner, | 10954 globals->bfd_of_glue_owner, |
10803 ARM_BX_GLUE_SECTION_NAME)) | 10955 ARM_BX_GLUE_SECTION_NAME)) |
10804 return FALSE; | 10956 return FALSE; |
10805 } | 10957 } |
10806 | 10958 |
10807 return TRUE; | 10959 return TRUE; |
10808 } | 10960 } |
10809 | 10961 |
| 10962 /* Return a best guess for the machine number based on the attributes. */ |
| 10963 |
| 10964 static unsigned int |
| 10965 bfd_arm_get_mach_from_attributes (bfd * abfd) |
| 10966 { |
| 10967 int arch = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_CPU_arch); |
| 10968 |
| 10969 switch (arch) |
| 10970 { |
| 10971 case TAG_CPU_ARCH_V4: return bfd_mach_arm_4; |
| 10972 case TAG_CPU_ARCH_V4T: return bfd_mach_arm_4T; |
| 10973 case TAG_CPU_ARCH_V5T: return bfd_mach_arm_5T; |
| 10974 |
| 10975 case TAG_CPU_ARCH_V5TE: |
| 10976 { |
| 10977 char * name; |
| 10978 |
| 10979 BFD_ASSERT (Tag_CPU_name < NUM_KNOWN_OBJ_ATTRIBUTES); |
| 10980 name = elf_known_obj_attributes (abfd) [OBJ_ATTR_PROC][Tag_CPU_name].s; |
| 10981 |
| 10982 if (name) |
| 10983 { |
| 10984 if (strcmp (name, "IWMMXT2") == 0) |
| 10985 return bfd_mach_arm_iWMMXt2; |
| 10986 |
| 10987 if (strcmp (name, "IWMMXT") == 0) |
| 10988 return bfd_mach_arm_iWMMXt; |
| 10989 } |
| 10990 |
| 10991 return bfd_mach_arm_5TE; |
| 10992 } |
| 10993 |
| 10994 default: |
| 10995 return bfd_mach_arm_unknown; |
| 10996 } |
| 10997 } |
| 10998 |
10810 /* Set the right machine number. */ | 10999 /* Set the right machine number. */ |
10811 | 11000 |
10812 static bfd_boolean | 11001 static bfd_boolean |
10813 elf32_arm_object_p (bfd *abfd) | 11002 elf32_arm_object_p (bfd *abfd) |
10814 { | 11003 { |
10815 unsigned int mach; | 11004 unsigned int mach; |
10816 | 11005 |
10817 mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION); | 11006 mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION); |
10818 | 11007 |
10819 if (mach != bfd_mach_arm_unknown) | 11008 if (mach == bfd_mach_arm_unknown) |
10820 bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach); | 11009 { |
| 11010 if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT) |
| 11011 » mach = bfd_mach_arm_ep9312; |
| 11012 else |
| 11013 » mach = bfd_arm_get_mach_from_attributes (abfd); |
| 11014 } |
10821 | 11015 |
10822 else if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT) | 11016 bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach); |
10823 bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312); | |
10824 | |
10825 else | |
10826 bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach); | |
10827 | |
10828 return TRUE; | 11017 return TRUE; |
10829 } | 11018 } |
10830 | 11019 |
10831 /* Function to keep ARM specific flags in the ELF header. */ | 11020 /* Function to keep ARM specific flags in the ELF header. */ |
10832 | 11021 |
10833 static bfd_boolean | 11022 static bfd_boolean |
10834 elf32_arm_set_private_flags (bfd *abfd, flagword flags) | 11023 elf32_arm_set_private_flags (bfd *abfd, flagword flags) |
10835 { | 11024 { |
10836 if (elf_flags_init (abfd) | 11025 if (elf_flags_init (abfd) |
10837 && elf_elfheader (abfd)->e_flags != flags) | 11026 && elf_elfheader (abfd)->e_flags != flags) |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11212 { | 11401 { |
11213 _bfd_error_handler (_("error: %B: Conflicting CPU architectures %d/%d"), | 11402 _bfd_error_handler (_("error: %B: Conflicting CPU architectures %d/%d"), |
11214 ibfd, oldtag, newtag); | 11403 ibfd, oldtag, newtag); |
11215 return -1; | 11404 return -1; |
11216 } | 11405 } |
11217 | 11406 |
11218 return result; | 11407 return result; |
11219 #undef T | 11408 #undef T |
11220 } | 11409 } |
11221 | 11410 |
| 11411 /* Query attributes object to see if integer divide instructions may be |
| 11412 present in an object. */ |
| 11413 static bfd_boolean |
| 11414 elf32_arm_attributes_accept_div (const obj_attribute *attr) |
| 11415 { |
| 11416 int arch = attr[Tag_CPU_arch].i; |
| 11417 int profile = attr[Tag_CPU_arch_profile].i; |
| 11418 |
| 11419 switch (attr[Tag_DIV_use].i) |
| 11420 { |
| 11421 case 0: |
| 11422 /* Integer divide allowed if instruction contained in archetecture. */ |
| 11423 if (arch == TAG_CPU_ARCH_V7 && (profile == 'R' || profile == 'M')) |
| 11424 return TRUE; |
| 11425 else if (arch >= TAG_CPU_ARCH_V7E_M) |
| 11426 return TRUE; |
| 11427 else |
| 11428 return FALSE; |
| 11429 |
| 11430 case 1: |
| 11431 /* Integer divide explicitly prohibited. */ |
| 11432 return FALSE; |
| 11433 |
| 11434 default: |
| 11435 /* Unrecognised case - treat as allowing divide everywhere. */ |
| 11436 case 2: |
| 11437 /* Integer divide allowed in ARM state. */ |
| 11438 return TRUE; |
| 11439 } |
| 11440 } |
| 11441 |
| 11442 /* Query attributes object to see if integer divide instructions are |
| 11443 forbidden to be in the object. This is not the inverse of |
| 11444 elf32_arm_attributes_accept_div. */ |
| 11445 static bfd_boolean |
| 11446 elf32_arm_attributes_forbid_div (const obj_attribute *attr) |
| 11447 { |
| 11448 return attr[Tag_DIV_use].i == 1; |
| 11449 } |
| 11450 |
11222 /* Merge EABI object attributes from IBFD into OBFD. Raise an error if there | 11451 /* Merge EABI object attributes from IBFD into OBFD. Raise an error if there |
11223 are conflicting attributes. */ | 11452 are conflicting attributes. */ |
11224 | 11453 |
11225 static bfd_boolean | 11454 static bfd_boolean |
11226 elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) | 11455 elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd) |
11227 { | 11456 { |
11228 obj_attribute *in_attr; | 11457 obj_attribute *in_attr; |
11229 obj_attribute *out_attr; | 11458 obj_attribute *out_attr; |
11230 /* Some tags have 0 = don't care, 1 = strong requirement, | 11459 /* Some tags have 0 = don't care, 1 = strong requirement, |
11231 2 = weak requirement. */ | 11460 2 = weak requirement. */ |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11653 (_("error: fp16 format mismatch between %B and %B"), | 11882 (_("error: fp16 format mismatch between %B and %B"), |
11654 ibfd, obfd); | 11883 ibfd, obfd); |
11655 result = FALSE; | 11884 result = FALSE; |
11656 } | 11885 } |
11657 } | 11886 } |
11658 if (in_attr[i].i != 0) | 11887 if (in_attr[i].i != 0) |
11659 out_attr[i].i = in_attr[i].i; | 11888 out_attr[i].i = in_attr[i].i; |
11660 break; | 11889 break; |
11661 | 11890 |
11662 case Tag_DIV_use: | 11891 case Tag_DIV_use: |
11663 » /* This tag is set to zero if we can use UDIV and SDIV in Thumb | 11892 » /* A value of zero on input means that the divide instruction may |
11664 » mode on a v7-M or v7-R CPU; to one if we can not use UDIV or | 11893 » be used if available in the base architecture as specified via |
11665 » SDIV at all; and to two if we can use UDIV or SDIV on a v7-A | 11894 » Tag_CPU_arch and Tag_CPU_arch_profile. A value of 1 means that |
11666 » CPU. We will merge as follows: If the input attribute's value | 11895 » the user did not want divide instructions. A value of 2 |
11667 » is one then the output attribute's value remains unchanged. If | 11896 » explicitly means that divide instructions were allowed in ARM |
11668 » the input attribute's value is zero or two then if the output | 11897 » and Thumb state. */ |
11669 » attribute's value is one the output value is set to the input | 11898 » if (in_attr[i].i == out_attr[i].i) |
11670 » value, otherwise the output value must be the same as the | 11899 » /* Do nothing. */ ; |
11671 » inputs. */ | 11900 » else if (elf32_arm_attributes_forbid_div (in_attr) |
11672 » if (in_attr[i].i != 1 && out_attr[i].i != 1) | 11901 » » && !elf32_arm_attributes_accept_div (out_attr)) |
11673 » { | 11902 » out_attr[i].i = 1; |
11674 » if (in_attr[i].i != out_attr[i].i) | 11903 » else if (elf32_arm_attributes_forbid_div (out_attr) |
11675 » » { | 11904 » » && elf32_arm_attributes_accept_div (in_attr)) |
11676 » » _bfd_error_handler | 11905 » out_attr[i].i = in_attr[i].i; |
11677 » » (_("DIV usage mismatch between %B and %B"), | 11906 » else if (in_attr[i].i == 2) |
11678 » » ibfd, obfd); | 11907 » out_attr[i].i = in_attr[i].i; |
11679 » » result = FALSE; | |
11680 » » } | |
11681 » } | |
11682 | |
11683 » if (in_attr[i].i != 1) | |
11684 » out_attr[i].i = in_attr[i].i; | |
11685 » | |
11686 break; | 11908 break; |
11687 | 11909 |
11688 case Tag_MPextension_use_legacy: | 11910 case Tag_MPextension_use_legacy: |
11689 /* We don't output objects with Tag_MPextension_use_legacy - we | 11911 /* We don't output objects with Tag_MPextension_use_legacy - we |
11690 move the value to Tag_MPextension_use. */ | 11912 move the value to Tag_MPextension_use. */ |
11691 if (in_attr[i].i != 0 && in_attr[Tag_MPextension_use].i != 0) | 11913 if (in_attr[i].i != 0 && in_attr[Tag_MPextension_use].i != 0) |
11692 { | 11914 { |
11693 if (in_attr[Tag_MPextension_use].i != in_attr[i].i) | 11915 if (in_attr[Tag_MPextension_use].i != in_attr[i].i) |
11694 { | 11916 { |
11695 _bfd_error_handler | 11917 _bfd_error_handler |
11696 (_("%B has has both the current and legacy " | 11918 (_("%B has has both the current and legacy " |
11697 » » "Tag_MPextension_use attributes"), | 11919 » » "Tag_MPextension_use attributes"), |
11698 ibfd); | 11920 ibfd); |
11699 result = FALSE; | 11921 result = FALSE; |
11700 } | 11922 } |
11701 } | 11923 } |
11702 | 11924 |
11703 if (in_attr[i].i > out_attr[Tag_MPextension_use].i) | 11925 if (in_attr[i].i > out_attr[Tag_MPextension_use].i) |
11704 out_attr[Tag_MPextension_use] = in_attr[i]; | 11926 out_attr[Tag_MPextension_use] = in_attr[i]; |
11705 | 11927 |
11706 break; | 11928 break; |
11707 | 11929 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12067 may_need_local_target_p = TRUE; | 12289 may_need_local_target_p = TRUE; |
12068 break; | 12290 break; |
12069 | 12291 |
12070 default: | 12292 default: |
12071 break; | 12293 break; |
12072 } | 12294 } |
12073 | 12295 |
12074 if (may_need_local_target_p | 12296 if (may_need_local_target_p |
12075 && elf32_arm_get_plt_info (abfd, eh, r_symndx, &root_plt, &arm_plt)) | 12297 && elf32_arm_get_plt_info (abfd, eh, r_symndx, &root_plt, &arm_plt)) |
12076 { | 12298 { |
12077 » BFD_ASSERT (root_plt->refcount > 0); | 12299 » /* If PLT refcount book-keeping is wrong and too low, we'll |
12078 » root_plt->refcount -= 1; | 12300 » see a zero value (going to -1) for the root PLT reference |
| 12301 » count. */ |
| 12302 » if (root_plt->refcount >= 0) |
| 12303 » { |
| 12304 » BFD_ASSERT (root_plt->refcount != 0); |
| 12305 » root_plt->refcount -= 1; |
| 12306 » } |
| 12307 » else |
| 12308 » /* A value of -1 means the symbol has become local, forced |
| 12309 » or seeing a hidden definition. Any other negative value |
| 12310 » is an error. */ |
| 12311 » BFD_ASSERT (root_plt->refcount == -1); |
12079 | 12312 |
12080 if (!call_reloc_p) | 12313 if (!call_reloc_p) |
12081 arm_plt->noncall_refcount--; | 12314 arm_plt->noncall_refcount--; |
12082 | 12315 |
12083 if (r_type == R_ARM_THM_CALL) | 12316 if (r_type == R_ARM_THM_CALL) |
12084 arm_plt->maybe_thumb_refcount--; | 12317 arm_plt->maybe_thumb_refcount--; |
12085 | 12318 |
12086 if (r_type == R_ARM_THM_JUMP24 | 12319 if (r_type == R_ARM_THM_JUMP24 |
12087 || r_type == R_ARM_THM_JUMP19) | 12320 || r_type == R_ARM_THM_JUMP19) |
12088 arm_plt->thumb_refcount--; | 12321 arm_plt->thumb_refcount--; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12161 if (htab->root.dynobj == NULL) | 12394 if (htab->root.dynobj == NULL) |
12162 htab->root.dynobj = abfd; | 12395 htab->root.dynobj = abfd; |
12163 if (!create_ifunc_sections (info)) | 12396 if (!create_ifunc_sections (info)) |
12164 return FALSE; | 12397 return FALSE; |
12165 | 12398 |
12166 dynobj = htab->root.dynobj; | 12399 dynobj = htab->root.dynobj; |
12167 | 12400 |
12168 symtab_hdr = & elf_symtab_hdr (abfd); | 12401 symtab_hdr = & elf_symtab_hdr (abfd); |
12169 sym_hashes = elf_sym_hashes (abfd); | 12402 sym_hashes = elf_sym_hashes (abfd); |
12170 nsyms = NUM_SHDR_ENTRIES (symtab_hdr); | 12403 nsyms = NUM_SHDR_ENTRIES (symtab_hdr); |
12171 | 12404 |
12172 rel_end = relocs + sec->reloc_count; | 12405 rel_end = relocs + sec->reloc_count; |
12173 for (rel = relocs; rel < rel_end; rel++) | 12406 for (rel = relocs; rel < rel_end; rel++) |
12174 { | 12407 { |
12175 Elf_Internal_Sym *isym; | 12408 Elf_Internal_Sym *isym; |
12176 struct elf_link_hash_entry *h; | 12409 struct elf_link_hash_entry *h; |
12177 struct elf32_arm_link_hash_entry *eh; | 12410 struct elf32_arm_link_hash_entry *eh; |
12178 unsigned long r_symndx; | 12411 unsigned long r_symndx; |
12179 int r_type; | 12412 int r_type; |
12180 | 12413 |
12181 r_symndx = ELF32_R_SYM (rel->r_info); | 12414 r_symndx = ELF32_R_SYM (rel->r_info); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12233 case R_ARM_THM_TLS_DESCSEQ: | 12466 case R_ARM_THM_TLS_DESCSEQ: |
12234 case R_ARM_TLS_CALL: | 12467 case R_ARM_TLS_CALL: |
12235 case R_ARM_THM_TLS_CALL: | 12468 case R_ARM_THM_TLS_CALL: |
12236 /* This symbol requires a global offset table entry. */ | 12469 /* This symbol requires a global offset table entry. */ |
12237 { | 12470 { |
12238 int tls_type, old_tls_type; | 12471 int tls_type, old_tls_type; |
12239 | 12472 |
12240 switch (r_type) | 12473 switch (r_type) |
12241 { | 12474 { |
12242 case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break; | 12475 case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break; |
12243 » » | 12476 |
12244 case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break; | 12477 case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break; |
12245 » » | 12478 |
12246 case R_ARM_TLS_GOTDESC: | 12479 case R_ARM_TLS_GOTDESC: |
12247 case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL: | 12480 case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL: |
12248 case R_ARM_TLS_DESCSEQ: case R_ARM_THM_TLS_DESCSEQ: | 12481 case R_ARM_TLS_DESCSEQ: case R_ARM_THM_TLS_DESCSEQ: |
12249 tls_type = GOT_TLS_GDESC; break; | 12482 tls_type = GOT_TLS_GDESC; break; |
12250 » » | 12483 |
12251 default: tls_type = GOT_NORMAL; break; | 12484 default: tls_type = GOT_NORMAL; break; |
12252 } | 12485 } |
12253 | 12486 |
12254 if (h != NULL) | 12487 if (h != NULL) |
12255 { | 12488 { |
12256 h->got.refcount++; | 12489 h->got.refcount++; |
12257 old_tls_type = elf32_arm_hash_entry (h)->tls_type; | 12490 old_tls_type = elf32_arm_hash_entry (h)->tls_type; |
12258 } | 12491 } |
12259 else | 12492 else |
12260 { | 12493 { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12429 { | 12662 { |
12430 local_iplt = elf32_arm_create_local_iplt (abfd, r_symndx); | 12663 local_iplt = elf32_arm_create_local_iplt (abfd, r_symndx); |
12431 if (local_iplt == NULL) | 12664 if (local_iplt == NULL) |
12432 return FALSE; | 12665 return FALSE; |
12433 root_plt = &local_iplt->root; | 12666 root_plt = &local_iplt->root; |
12434 arm_plt = &local_iplt->arm; | 12667 arm_plt = &local_iplt->arm; |
12435 } | 12668 } |
12436 | 12669 |
12437 /* If the symbol is a function that doesn't bind locally, | 12670 /* If the symbol is a function that doesn't bind locally, |
12438 this relocation will need a PLT entry. */ | 12671 this relocation will need a PLT entry. */ |
12439 » root_plt->refcount += 1; | 12672 » if (root_plt->refcount != -1) |
| 12673 » root_plt->refcount += 1; |
12440 | 12674 |
12441 if (!call_reloc_p) | 12675 if (!call_reloc_p) |
12442 arm_plt->noncall_refcount++; | 12676 arm_plt->noncall_refcount++; |
12443 | 12677 |
12444 /* It's too early to use htab->use_blx here, so we have to | 12678 /* It's too early to use htab->use_blx here, so we have to |
12445 record possible blx references separately from | 12679 record possible blx references separately from |
12446 relocs that definitely need a thumb stub. */ | 12680 relocs that definitely need a thumb stub. */ |
12447 | 12681 |
12448 if (r_type == R_ARM_THM_CALL) | 12682 if (r_type == R_ARM_THM_CALL) |
12449 arm_plt->maybe_thumb_refcount += 1; | 12683 arm_plt->maybe_thumb_refcount += 1; |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12790 | 13024 |
12791 /* If we are creating a shared library, we must presume that the | 13025 /* If we are creating a shared library, we must presume that the |
12792 only references to the symbol are via the global offset table. | 13026 only references to the symbol are via the global offset table. |
12793 For such cases we need not do anything here; the relocations will | 13027 For such cases we need not do anything here; the relocations will |
12794 be handled correctly by relocate_section. Relocatable executables | 13028 be handled correctly by relocate_section. Relocatable executables |
12795 can reference data in shared objects directly, so we don't need to | 13029 can reference data in shared objects directly, so we don't need to |
12796 do anything here. */ | 13030 do anything here. */ |
12797 if (info->shared || globals->root.is_relocatable_executable) | 13031 if (info->shared || globals->root.is_relocatable_executable) |
12798 return TRUE; | 13032 return TRUE; |
12799 | 13033 |
12800 if (h->size == 0) | |
12801 { | |
12802 (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), | |
12803 h->root.root.string); | |
12804 return TRUE; | |
12805 } | |
12806 | |
12807 /* We must allocate the symbol in our .dynbss section, which will | 13034 /* We must allocate the symbol in our .dynbss section, which will |
12808 become part of the .bss section of the executable. There will be | 13035 become part of the .bss section of the executable. There will be |
12809 an entry for this symbol in the .dynsym section. The dynamic | 13036 an entry for this symbol in the .dynsym section. The dynamic |
12810 object will contain position independent code, so all references | 13037 object will contain position independent code, so all references |
12811 from the dynamic object to this symbol will go through the global | 13038 from the dynamic object to this symbol will go through the global |
12812 offset table. The dynamic linker will use the .dynsym entry to | 13039 offset table. The dynamic linker will use the .dynsym entry to |
12813 determine the address it must put in the global offset table, so | 13040 determine the address it must put in the global offset table, so |
12814 both the dynamic object and the regular object will refer to the | 13041 both the dynamic object and the regular object will refer to the |
12815 same memory location for the variable. */ | 13042 same memory location for the variable. */ |
12816 s = bfd_get_section_by_name (dynobj, ".dynbss"); | 13043 s = bfd_get_linker_section (dynobj, ".dynbss"); |
12817 BFD_ASSERT (s != NULL); | 13044 BFD_ASSERT (s != NULL); |
12818 | 13045 |
12819 /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to | 13046 /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to |
12820 copy the initial value out of the dynamic object and into the | 13047 copy the initial value out of the dynamic object and into the |
12821 runtime process image. We need to remember the offset into the | 13048 runtime process image. We need to remember the offset into the |
12822 .rel(a).bss section we are going to use. */ | 13049 .rel(a).bss section we are going to use. */ |
12823 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) | 13050 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) |
12824 { | 13051 { |
12825 asection *srel; | 13052 asection *srel; |
12826 | 13053 |
12827 srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (globals, ".bss")); | 13054 srel = bfd_get_linker_section (dynobj, RELOC_SECTION (globals, ".bss")); |
12828 elf32_arm_allocate_dynrelocs (info, srel, 1); | 13055 elf32_arm_allocate_dynrelocs (info, srel, 1); |
12829 h->needs_copy = 1; | 13056 h->needs_copy = 1; |
12830 } | 13057 } |
12831 | 13058 |
12832 return _bfd_elf_adjust_dynamic_copy (h, s); | 13059 return _bfd_elf_adjust_dynamic_copy (h, s); |
12833 } | 13060 } |
12834 | 13061 |
12835 /* Allocate space in .plt, .got and associated reloc sections for | 13062 /* Allocate space in .plt, .got and associated reloc sections for |
12836 dynamic relocs. */ | 13063 dynamic relocs. */ |
12837 | 13064 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13007 && (info->shared || indx != 0) | 13234 && (info->shared || indx != 0) |
13008 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT | 13235 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
13009 || h->root.type != bfd_link_hash_undefweak)) | 13236 || h->root.type != bfd_link_hash_undefweak)) |
13010 { | 13237 { |
13011 if (tls_type & GOT_TLS_IE) | 13238 if (tls_type & GOT_TLS_IE) |
13012 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); | 13239 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); |
13013 | 13240 |
13014 if (tls_type & GOT_TLS_GD) | 13241 if (tls_type & GOT_TLS_GD) |
13015 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); | 13242 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); |
13016 | 13243 |
13017 » if (tls_type & GOT_TLS_GDESC) | 13244 » if (tls_type & GOT_TLS_GDESC) |
13018 { | 13245 { |
13019 elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1); | 13246 elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1); |
13020 /* GDESC needs a trampoline to jump to. */ | 13247 /* GDESC needs a trampoline to jump to. */ |
13021 htab->tls_trampoline = -1; | 13248 htab->tls_trampoline = -1; |
13022 } | 13249 } |
13023 | 13250 |
13024 /* Only GD needs it. GDESC just emits one relocation per | 13251 /* Only GD needs it. GDESC just emits one relocation per |
13025 2 entries. */ | 13252 2 entries. */ |
13026 » if ((tls_type & GOT_TLS_GD) && indx != 0) | 13253 » if ((tls_type & GOT_TLS_GD) && indx != 0) |
13027 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); | 13254 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); |
13028 } | 13255 } |
13029 else if (!SYMBOL_REFERENCES_LOCAL (info, h)) | 13256 else if (!SYMBOL_REFERENCES_LOCAL (info, h)) |
13030 { | 13257 { |
13031 if (htab->root.dynamic_sections_created) | 13258 if (htab->root.dynamic_sections_created) |
13032 /* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation.
*/ | 13259 /* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation.
*/ |
13033 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); | 13260 elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); |
13034 } | 13261 } |
13035 else if (h->type == STT_GNU_IFUNC | 13262 else if (h->type == STT_GNU_IFUNC |
13036 && eh->plt.noncall_refcount == 0) | 13263 && eh->plt.noncall_refcount == 0) |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13259 | 13486 |
13260 dynobj = elf_hash_table (info)->dynobj; | 13487 dynobj = elf_hash_table (info)->dynobj; |
13261 BFD_ASSERT (dynobj != NULL); | 13488 BFD_ASSERT (dynobj != NULL); |
13262 check_use_blx (htab); | 13489 check_use_blx (htab); |
13263 | 13490 |
13264 if (elf_hash_table (info)->dynamic_sections_created) | 13491 if (elf_hash_table (info)->dynamic_sections_created) |
13265 { | 13492 { |
13266 /* Set the contents of the .interp section to the interpreter. */ | 13493 /* Set the contents of the .interp section to the interpreter. */ |
13267 if (info->executable) | 13494 if (info->executable) |
13268 { | 13495 { |
13269 » s = bfd_get_section_by_name (dynobj, ".interp"); | 13496 » s = bfd_get_linker_section (dynobj, ".interp"); |
13270 BFD_ASSERT (s != NULL); | 13497 BFD_ASSERT (s != NULL); |
13271 s->size = sizeof ELF_DYNAMIC_INTERPRETER; | 13498 s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
13272 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; | 13499 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
13273 } | 13500 } |
13274 } | 13501 } |
13275 | 13502 |
13276 /* Set up .got offsets for local syms, and space for local dynamic | 13503 /* Set up .got offsets for local syms, and space for local dynamic |
13277 relocs. */ | 13504 relocs. */ |
13278 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) | 13505 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) |
13279 { | 13506 { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13471 it's not incremented, so in order to compute the space reserved | 13698 it's not incremented, so in order to compute the space reserved |
13472 for them, it suffices to multiply the reloc count by the jump | 13699 for them, it suffices to multiply the reloc count by the jump |
13473 slot size. */ | 13700 slot size. */ |
13474 if (htab->root.srelplt) | 13701 if (htab->root.srelplt) |
13475 htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab); | 13702 htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab); |
13476 | 13703 |
13477 if (htab->tls_trampoline) | 13704 if (htab->tls_trampoline) |
13478 { | 13705 { |
13479 if (htab->root.splt->size == 0) | 13706 if (htab->root.splt->size == 0) |
13480 htab->root.splt->size += htab->plt_header_size; | 13707 htab->root.splt->size += htab->plt_header_size; |
13481 | 13708 |
13482 htab->tls_trampoline = htab->root.splt->size; | 13709 htab->tls_trampoline = htab->root.splt->size; |
13483 htab->root.splt->size += htab->plt_entry_size; | 13710 htab->root.splt->size += htab->plt_entry_size; |
13484 | 13711 |
13485 /* If we're not using lazy TLS relocations, don't generate the | 13712 /* If we're not using lazy TLS relocations, don't generate the |
13486 PLT and GOT entries they require. */ | 13713 PLT and GOT entries they require. */ |
13487 if (!(info->flags & DF_BIND_NOW)) | 13714 if (!(info->flags & DF_BIND_NOW)) |
13488 { | 13715 { |
13489 htab->dt_tlsdesc_got = htab->root.sgot->size; | 13716 htab->dt_tlsdesc_got = htab->root.sgot->size; |
13490 htab->root.sgot->size += 4; | 13717 htab->root.sgot->size += 4; |
13491 | 13718 |
13492 htab->dt_tlsdesc_plt = htab->root.splt->size; | 13719 htab->dt_tlsdesc_plt = htab->root.splt->size; |
13493 htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline); | 13720 htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline); |
13494 } | 13721 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13582 if (plt) | 13809 if (plt) |
13583 { | 13810 { |
13584 if ( !add_dynamic_entry (DT_PLTGOT, 0) | 13811 if ( !add_dynamic_entry (DT_PLTGOT, 0) |
13585 || !add_dynamic_entry (DT_PLTRELSZ, 0) | 13812 || !add_dynamic_entry (DT_PLTRELSZ, 0) |
13586 || !add_dynamic_entry (DT_PLTREL, | 13813 || !add_dynamic_entry (DT_PLTREL, |
13587 htab->use_rel ? DT_REL : DT_RELA) | 13814 htab->use_rel ? DT_REL : DT_RELA) |
13588 || !add_dynamic_entry (DT_JMPREL, 0)) | 13815 || !add_dynamic_entry (DT_JMPREL, 0)) |
13589 return FALSE; | 13816 return FALSE; |
13590 | 13817 |
13591 if (htab->dt_tlsdesc_plt && | 13818 if (htab->dt_tlsdesc_plt && |
13592 » » (!add_dynamic_entry (DT_TLSDESC_PLT,0) | 13819 » » (!add_dynamic_entry (DT_TLSDESC_PLT,0) |
13593 || !add_dynamic_entry (DT_TLSDESC_GOT,0))) | 13820 || !add_dynamic_entry (DT_TLSDESC_GOT,0))) |
13594 » return FALSE; | 13821 » return FALSE; |
13595 } | 13822 } |
13596 | 13823 |
13597 if (relocs) | 13824 if (relocs) |
13598 { | 13825 { |
13599 if (htab->use_rel) | 13826 if (htab->use_rel) |
13600 { | 13827 { |
13601 if (!add_dynamic_entry (DT_REL, 0) | 13828 if (!add_dynamic_entry (DT_REL, 0) |
13602 || !add_dynamic_entry (DT_RELSZ, 0) | 13829 || !add_dynamic_entry (DT_RELSZ, 0) |
13603 || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab))) | 13830 || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab))) |
13604 return FALSE; | 13831 return FALSE; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13657 { | 13884 { |
13658 struct bfd_link_hash_entry *bh = NULL; | 13885 struct bfd_link_hash_entry *bh = NULL; |
13659 const struct elf_backend_data *bed | 13886 const struct elf_backend_data *bed |
13660 = get_elf_backend_data (output_bfd); | 13887 = get_elf_backend_data (output_bfd); |
13661 | 13888 |
13662 if (!(_bfd_generic_link_add_one_symbol | 13889 if (!(_bfd_generic_link_add_one_symbol |
13663 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL, | 13890 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL, |
13664 tls_sec, 0, NULL, FALSE, | 13891 tls_sec, 0, NULL, FALSE, |
13665 bed->collect, &bh))) | 13892 bed->collect, &bh))) |
13666 return FALSE; | 13893 return FALSE; |
13667 » | 13894 |
13668 tlsbase->type = STT_TLS; | 13895 tlsbase->type = STT_TLS; |
13669 tlsbase = (struct elf_link_hash_entry *)bh; | 13896 tlsbase = (struct elf_link_hash_entry *)bh; |
13670 tlsbase->def_regular = 1; | 13897 tlsbase->def_regular = 1; |
13671 tlsbase->other = STV_HIDDEN; | 13898 tlsbase->other = STV_HIDDEN; |
13672 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); | 13899 (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); |
13673 } | 13900 } |
13674 } | 13901 } |
13675 return TRUE; | 13902 return TRUE; |
13676 } | 13903 } |
13677 | 13904 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13758 | 13985 |
13759 return TRUE; | 13986 return TRUE; |
13760 } | 13987 } |
13761 | 13988 |
13762 static void | 13989 static void |
13763 arm_put_trampoline (struct elf32_arm_link_hash_table *htab, bfd *output_bfd, | 13990 arm_put_trampoline (struct elf32_arm_link_hash_table *htab, bfd *output_bfd, |
13764 void *contents, | 13991 void *contents, |
13765 const unsigned long *template, unsigned count) | 13992 const unsigned long *template, unsigned count) |
13766 { | 13993 { |
13767 unsigned ix; | 13994 unsigned ix; |
13768 | 13995 |
13769 for (ix = 0; ix != count; ix++) | 13996 for (ix = 0; ix != count; ix++) |
13770 { | 13997 { |
13771 unsigned long insn = template[ix]; | 13998 unsigned long insn = template[ix]; |
13772 | 13999 |
13773 /* Emit mov pc,rx if bx is not permitted. */ | 14000 /* Emit mov pc,rx if bx is not permitted. */ |
13774 if (htab->fix_v4bx == 1 && (insn & 0x0ffffff0) == 0x012fff10) | 14001 if (htab->fix_v4bx == 1 && (insn & 0x0ffffff0) == 0x012fff10) |
13775 insn = (insn & 0xf000000f) | 0x01a0f000; | 14002 insn = (insn & 0xf000000f) | 0x01a0f000; |
13776 put_arm_insn (htab, output_bfd, insn, (char *)contents + ix*4); | 14003 put_arm_insn (htab, output_bfd, insn, (char *)contents + ix*4); |
13777 } | 14004 } |
13778 } | 14005 } |
(...skipping 12 matching lines...) Expand all Loading... |
13791 if (htab == NULL) | 14018 if (htab == NULL) |
13792 return FALSE; | 14019 return FALSE; |
13793 | 14020 |
13794 dynobj = elf_hash_table (info)->dynobj; | 14021 dynobj = elf_hash_table (info)->dynobj; |
13795 | 14022 |
13796 sgot = htab->root.sgotplt; | 14023 sgot = htab->root.sgotplt; |
13797 /* A broken linker script might have discarded the dynamic sections. | 14024 /* A broken linker script might have discarded the dynamic sections. |
13798 Catch this here so that we do not seg-fault later on. */ | 14025 Catch this here so that we do not seg-fault later on. */ |
13799 if (sgot != NULL && bfd_is_abs_section (sgot->output_section)) | 14026 if (sgot != NULL && bfd_is_abs_section (sgot->output_section)) |
13800 return FALSE; | 14027 return FALSE; |
13801 sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); | 14028 sdyn = bfd_get_linker_section (dynobj, ".dynamic"); |
13802 | 14029 |
13803 if (elf_hash_table (info)->dynamic_sections_created) | 14030 if (elf_hash_table (info)->dynamic_sections_created) |
13804 { | 14031 { |
13805 asection *splt; | 14032 asection *splt; |
13806 Elf32_External_Dyn *dyncon, *dynconend; | 14033 Elf32_External_Dyn *dyncon, *dynconend; |
13807 | 14034 |
13808 splt = htab->root.splt; | 14035 splt = htab->root.splt; |
13809 BFD_ASSERT (splt != NULL && sdyn != NULL); | 14036 BFD_ASSERT (splt != NULL && sdyn != NULL); |
13810 BFD_ASSERT (htab->symbian_p || sgot != NULL); | 14037 BFD_ASSERT (htab->symbian_p || sgot != NULL); |
13811 | 14038 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14000 splt->contents + 8); | 14227 splt->contents + 8); |
14001 bfd_put_32 (output_bfd, got_address, splt->contents + 12); | 14228 bfd_put_32 (output_bfd, got_address, splt->contents + 12); |
14002 | 14229 |
14003 /* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */ | 14230 /* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */ |
14004 rel.r_offset = plt_address + 12; | 14231 rel.r_offset = plt_address + 12; |
14005 rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32); | 14232 rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32); |
14006 rel.r_addend = 0; | 14233 rel.r_addend = 0; |
14007 SWAP_RELOC_OUT (htab) (output_bfd, &rel, | 14234 SWAP_RELOC_OUT (htab) (output_bfd, &rel, |
14008 htab->srelplt2->contents); | 14235 htab->srelplt2->contents); |
14009 } | 14236 } |
| 14237 else if (htab->nacl_p) |
| 14238 { |
| 14239 unsigned int i; |
| 14240 |
| 14241 got_displacement = got_address + 8 - (plt_address + 16); |
| 14242 |
| 14243 put_arm_insn (htab, output_bfd, |
| 14244 elf32_arm_nacl_plt0_entry[0] |
| 14245 | arm_movw_immediate (got_displacement), |
| 14246 splt->contents + 0); |
| 14247 put_arm_insn (htab, output_bfd, |
| 14248 elf32_arm_nacl_plt0_entry[1] |
| 14249 | arm_movt_immediate (got_displacement), |
| 14250 splt->contents + 4); |
| 14251 for (i = 2; i < ARRAY_SIZE (elf32_arm_nacl_plt0_entry); ++i) |
| 14252 put_arm_insn (htab, output_bfd, |
| 14253 elf32_arm_nacl_plt0_entry[i], |
| 14254 splt->contents + (i * 4)); |
| 14255 } |
14010 else | 14256 else |
14011 { | 14257 { |
14012 got_displacement = got_address - (plt_address + 16); | 14258 got_displacement = got_address - (plt_address + 16); |
14013 | 14259 |
14014 plt0_entry = elf32_arm_plt0_entry; | 14260 plt0_entry = elf32_arm_plt0_entry; |
14015 put_arm_insn (htab, output_bfd, plt0_entry[0], | 14261 put_arm_insn (htab, output_bfd, plt0_entry[0], |
14016 splt->contents + 0); | 14262 splt->contents + 0); |
14017 put_arm_insn (htab, output_bfd, plt0_entry[1], | 14263 put_arm_insn (htab, output_bfd, plt0_entry[1], |
14018 splt->contents + 4); | 14264 splt->contents + 4); |
14019 put_arm_insn (htab, output_bfd, plt0_entry[2], | 14265 put_arm_insn (htab, output_bfd, plt0_entry[2], |
(...skipping 18 matching lines...) Expand all Loading... |
14038 | 14284 |
14039 if (htab->dt_tlsdesc_plt) | 14285 if (htab->dt_tlsdesc_plt) |
14040 { | 14286 { |
14041 bfd_vma got_address | 14287 bfd_vma got_address |
14042 = sgot->output_section->vma + sgot->output_offset; | 14288 = sgot->output_section->vma + sgot->output_offset; |
14043 bfd_vma gotplt_address = (htab->root.sgot->output_section->vma | 14289 bfd_vma gotplt_address = (htab->root.sgot->output_section->vma |
14044 + htab->root.sgot->output_offset); | 14290 + htab->root.sgot->output_offset); |
14045 bfd_vma plt_address | 14291 bfd_vma plt_address |
14046 = splt->output_section->vma + splt->output_offset; | 14292 = splt->output_section->vma + splt->output_offset; |
14047 | 14293 |
14048 » arm_put_trampoline (htab, output_bfd, | 14294 » arm_put_trampoline (htab, output_bfd, |
14049 splt->contents + htab->dt_tlsdesc_plt, | 14295 splt->contents + htab->dt_tlsdesc_plt, |
14050 dl_tlsdesc_lazy_trampoline, 6); | 14296 dl_tlsdesc_lazy_trampoline, 6); |
14051 | 14297 |
14052 bfd_put_32 (output_bfd, | 14298 bfd_put_32 (output_bfd, |
14053 gotplt_address + htab->dt_tlsdesc_got | 14299 gotplt_address + htab->dt_tlsdesc_got |
14054 - (plt_address + htab->dt_tlsdesc_plt) | 14300 - (plt_address + htab->dt_tlsdesc_plt) |
14055 - dl_tlsdesc_lazy_trampoline[6], | 14301 - dl_tlsdesc_lazy_trampoline[6], |
14056 splt->contents + htab->dt_tlsdesc_plt + 24); | 14302 splt->contents + htab->dt_tlsdesc_plt + 24); |
14057 bfd_put_32 (output_bfd, | 14303 bfd_put_32 (output_bfd, |
14058 got_address - (plt_address + htab->dt_tlsdesc_plt) | 14304 got_address - (plt_address + htab->dt_tlsdesc_plt) |
14059 - dl_tlsdesc_lazy_trampoline[7], | 14305 - dl_tlsdesc_lazy_trampoline[7], |
14060 splt->contents + htab->dt_tlsdesc_plt + 24 + 4); | 14306 splt->contents + htab->dt_tlsdesc_plt + 24 + 4); |
14061 } | 14307 } |
14062 | 14308 |
14063 if (htab->tls_trampoline) | 14309 if (htab->tls_trampoline) |
14064 { | 14310 { |
14065 » arm_put_trampoline (htab, output_bfd, | 14311 » arm_put_trampoline (htab, output_bfd, |
14066 splt->contents + htab->tls_trampoline, | 14312 splt->contents + htab->tls_trampoline, |
14067 tls_trampoline, 3); | 14313 tls_trampoline, 3); |
14068 #ifdef FOUR_WORD_PLT | 14314 #ifdef FOUR_WORD_PLT |
14069 bfd_put_32 (output_bfd, 0x00000000, | 14315 bfd_put_32 (output_bfd, 0x00000000, |
14070 splt->contents + htab->tls_trampoline + 12); | 14316 splt->contents + htab->tls_trampoline + 12); |
14071 #endif | 14317 #endif |
14072 } | 14318 } |
14073 | 14319 |
14074 if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0) | 14320 if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0) |
14075 { | 14321 { |
14076 /* Correct the .rel(a).plt.unloaded relocations. They will have | 14322 /* Correct the .rel(a).plt.unloaded relocations. They will have |
14077 incorrect symbol indexes. */ | 14323 incorrect symbol indexes. */ |
14078 int num_plts; | 14324 int num_plts; |
14079 unsigned char *p; | 14325 unsigned char *p; |
14080 | 14326 |
14081 num_plts = ((htab->root.splt->size - htab->plt_header_size) | 14327 num_plts = ((htab->root.splt->size - htab->plt_header_size) |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14228 get_arm_elf_section_data (asection * sec) | 14474 get_arm_elf_section_data (asection * sec) |
14229 { | 14475 { |
14230 if (sec && sec->owner && is_arm_elf (sec->owner)) | 14476 if (sec && sec->owner && is_arm_elf (sec->owner)) |
14231 return elf32_arm_section_data (sec); | 14477 return elf32_arm_section_data (sec); |
14232 else | 14478 else |
14233 return NULL; | 14479 return NULL; |
14234 } | 14480 } |
14235 | 14481 |
14236 typedef struct | 14482 typedef struct |
14237 { | 14483 { |
14238 void *finfo; | 14484 void *flaginfo; |
14239 struct bfd_link_info *info; | 14485 struct bfd_link_info *info; |
14240 asection *sec; | 14486 asection *sec; |
14241 int sec_shndx; | 14487 int sec_shndx; |
14242 int (*func) (void *, const char *, Elf_Internal_Sym *, | 14488 int (*func) (void *, const char *, Elf_Internal_Sym *, |
14243 asection *, struct elf_link_hash_entry *); | 14489 asection *, struct elf_link_hash_entry *); |
14244 } output_arch_syminfo; | 14490 } output_arch_syminfo; |
14245 | 14491 |
14246 enum map_symbol_type | 14492 enum map_symbol_type |
14247 { | 14493 { |
14248 ARM_MAP_ARM, | 14494 ARM_MAP_ARM, |
(...skipping 14 matching lines...) Expand all Loading... |
14263 | 14509 |
14264 sym.st_value = osi->sec->output_section->vma | 14510 sym.st_value = osi->sec->output_section->vma |
14265 + osi->sec->output_offset | 14511 + osi->sec->output_offset |
14266 + offset; | 14512 + offset; |
14267 sym.st_size = 0; | 14513 sym.st_size = 0; |
14268 sym.st_other = 0; | 14514 sym.st_other = 0; |
14269 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); | 14515 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); |
14270 sym.st_shndx = osi->sec_shndx; | 14516 sym.st_shndx = osi->sec_shndx; |
14271 sym.st_target_internal = 0; | 14517 sym.st_target_internal = 0; |
14272 elf32_arm_section_map_add (osi->sec, names[type][1], offset); | 14518 elf32_arm_section_map_add (osi->sec, names[type][1], offset); |
14273 return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1; | 14519 return osi->func (osi->flaginfo, names[type], &sym, osi->sec, NULL) == 1; |
14274 } | 14520 } |
14275 | 14521 |
14276 /* Output mapping symbols for the PLT entry described by ROOT_PLT and ARM_PLT. | 14522 /* Output mapping symbols for the PLT entry described by ROOT_PLT and ARM_PLT. |
14277 IS_IPLT_ENTRY_P says whether the PLT is in .iplt rather than .plt. */ | 14523 IS_IPLT_ENTRY_P says whether the PLT is in .iplt rather than .plt. */ |
14278 | 14524 |
14279 static bfd_boolean | 14525 static bfd_boolean |
14280 elf32_arm_output_plt_map_1 (output_arch_syminfo *osi, | 14526 elf32_arm_output_plt_map_1 (output_arch_syminfo *osi, |
14281 bfd_boolean is_iplt_entry_p, | 14527 bfd_boolean is_iplt_entry_p, |
14282 union gotplt_union *root_plt, | 14528 union gotplt_union *root_plt, |
14283 struct arm_plt_info *arm_plt) | 14529 struct arm_plt_info *arm_plt) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14317 { | 14563 { |
14318 if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) | 14564 if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) |
14319 return FALSE; | 14565 return FALSE; |
14320 if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8)) | 14566 if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8)) |
14321 return FALSE; | 14567 return FALSE; |
14322 if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 12)) | 14568 if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 12)) |
14323 return FALSE; | 14569 return FALSE; |
14324 if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20)) | 14570 if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20)) |
14325 return FALSE; | 14571 return FALSE; |
14326 } | 14572 } |
| 14573 else if (htab->nacl_p) |
| 14574 { |
| 14575 if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) |
| 14576 return FALSE; |
| 14577 } |
14327 else | 14578 else |
14328 { | 14579 { |
14329 bfd_boolean thumb_stub_p; | 14580 bfd_boolean thumb_stub_p; |
14330 | 14581 |
14331 thumb_stub_p = elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt); | 14582 thumb_stub_p = elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt); |
14332 if (thumb_stub_p) | 14583 if (thumb_stub_p) |
14333 { | 14584 { |
14334 if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4)) | 14585 if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4)) |
14335 return FALSE; | 14586 return FALSE; |
14336 } | 14587 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14385 Elf_Internal_Sym sym; | 14636 Elf_Internal_Sym sym; |
14386 | 14637 |
14387 sym.st_value = osi->sec->output_section->vma | 14638 sym.st_value = osi->sec->output_section->vma |
14388 + osi->sec->output_offset | 14639 + osi->sec->output_offset |
14389 + offset; | 14640 + offset; |
14390 sym.st_size = size; | 14641 sym.st_size = size; |
14391 sym.st_other = 0; | 14642 sym.st_other = 0; |
14392 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC); | 14643 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC); |
14393 sym.st_shndx = osi->sec_shndx; | 14644 sym.st_shndx = osi->sec_shndx; |
14394 sym.st_target_internal = 0; | 14645 sym.st_target_internal = 0; |
14395 return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1; | 14646 return osi->func (osi->flaginfo, name, &sym, osi->sec, NULL) == 1; |
14396 } | 14647 } |
14397 | 14648 |
14398 static bfd_boolean | 14649 static bfd_boolean |
14399 arm_map_one_stub (struct bfd_hash_entry * gen_entry, | 14650 arm_map_one_stub (struct bfd_hash_entry * gen_entry, |
14400 void * in_arg) | 14651 void * in_arg) |
14401 { | 14652 { |
14402 struct elf32_arm_stub_hash_entry *stub_entry; | 14653 struct elf32_arm_stub_hash_entry *stub_entry; |
14403 asection *stub_sec; | 14654 asection *stub_sec; |
14404 bfd_vma addr; | 14655 bfd_vma addr; |
14405 char *stub_name; | 14656 char *stub_name; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14497 return TRUE; | 14748 return TRUE; |
14498 } | 14749 } |
14499 | 14750 |
14500 /* Output mapping symbols for linker generated sections, | 14751 /* Output mapping symbols for linker generated sections, |
14501 and for those data-only sections that do not have a | 14752 and for those data-only sections that do not have a |
14502 $d. */ | 14753 $d. */ |
14503 | 14754 |
14504 static bfd_boolean | 14755 static bfd_boolean |
14505 elf32_arm_output_arch_local_syms (bfd *output_bfd, | 14756 elf32_arm_output_arch_local_syms (bfd *output_bfd, |
14506 struct bfd_link_info *info, | 14757 struct bfd_link_info *info, |
14507 » » » » void *finfo, | 14758 » » » » void *flaginfo, |
14508 int (*func) (void *, const char *, | 14759 int (*func) (void *, const char *, |
14509 Elf_Internal_Sym *, | 14760 Elf_Internal_Sym *, |
14510 asection *, | 14761 asection *, |
14511 struct elf_link_hash_entry *)) | 14762 struct elf_link_hash_entry *)) |
14512 { | 14763 { |
14513 output_arch_syminfo osi; | 14764 output_arch_syminfo osi; |
14514 struct elf32_arm_link_hash_table *htab; | 14765 struct elf32_arm_link_hash_table *htab; |
14515 bfd_vma offset; | 14766 bfd_vma offset; |
14516 bfd_size_type size; | 14767 bfd_size_type size; |
14517 bfd *input_bfd; | 14768 bfd *input_bfd; |
14518 | 14769 |
14519 htab = elf32_arm_hash_table (info); | 14770 htab = elf32_arm_hash_table (info); |
14520 if (htab == NULL) | 14771 if (htab == NULL) |
14521 return FALSE; | 14772 return FALSE; |
14522 | 14773 |
14523 check_use_blx (htab); | 14774 check_use_blx (htab); |
14524 | 14775 |
14525 osi.finfo = finfo; | 14776 osi.flaginfo = flaginfo; |
14526 osi.info = info; | 14777 osi.info = info; |
14527 osi.func = func; | 14778 osi.func = func; |
14528 | 14779 |
14529 /* Add a $d mapping symbol to data-only sections that | 14780 /* Add a $d mapping symbol to data-only sections that |
14530 don't have any mapping symbol. This may result in (harmless) redundant | 14781 don't have any mapping symbol. This may result in (harmless) redundant |
14531 mapping symbols. */ | 14782 mapping symbols. */ |
14532 for (input_bfd = info->input_bfds; | 14783 for (input_bfd = info->input_bfds; |
14533 input_bfd != NULL; | 14784 input_bfd != NULL; |
14534 input_bfd = input_bfd->link_next) | 14785 input_bfd = input_bfd->link_next) |
14535 { | 14786 { |
(...skipping 16 matching lines...) Expand all Loading... |
14552 (output_bfd, osi.sec->output_section); | 14803 (output_bfd, osi.sec->output_section); |
14553 if (osi.sec_shndx != (int)SHN_BAD) | 14804 if (osi.sec_shndx != (int)SHN_BAD) |
14554 elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 0); | 14805 elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 0); |
14555 } | 14806 } |
14556 } | 14807 } |
14557 } | 14808 } |
14558 | 14809 |
14559 /* ARM->Thumb glue. */ | 14810 /* ARM->Thumb glue. */ |
14560 if (htab->arm_glue_size > 0) | 14811 if (htab->arm_glue_size > 0) |
14561 { | 14812 { |
14562 osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner, | 14813 osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner, |
14563 » » » » » ARM2THUMB_GLUE_SECTION_NAME); | 14814 » » » » » ARM2THUMB_GLUE_SECTION_NAME); |
14564 | 14815 |
14565 osi.sec_shndx = _bfd_elf_section_from_bfd_section | 14816 osi.sec_shndx = _bfd_elf_section_from_bfd_section |
14566 (output_bfd, osi.sec->output_section); | 14817 (output_bfd, osi.sec->output_section); |
14567 if (info->shared || htab->root.is_relocatable_executable | 14818 if (info->shared || htab->root.is_relocatable_executable |
14568 || htab->pic_veneer) | 14819 || htab->pic_veneer) |
14569 size = ARM2THUMB_PIC_GLUE_SIZE; | 14820 size = ARM2THUMB_PIC_GLUE_SIZE; |
14570 else if (htab->use_blx) | 14821 else if (htab->use_blx) |
14571 size = ARM2THUMB_V5_STATIC_GLUE_SIZE; | 14822 size = ARM2THUMB_V5_STATIC_GLUE_SIZE; |
14572 else | 14823 else |
14573 size = ARM2THUMB_STATIC_GLUE_SIZE; | 14824 size = ARM2THUMB_STATIC_GLUE_SIZE; |
14574 | 14825 |
14575 for (offset = 0; offset < htab->arm_glue_size; offset += size) | 14826 for (offset = 0; offset < htab->arm_glue_size; offset += size) |
14576 { | 14827 { |
14577 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset); | 14828 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset); |
14578 elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, offset + size - 4); | 14829 elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, offset + size - 4); |
14579 } | 14830 } |
14580 } | 14831 } |
14581 | 14832 |
14582 /* Thumb->ARM glue. */ | 14833 /* Thumb->ARM glue. */ |
14583 if (htab->thumb_glue_size > 0) | 14834 if (htab->thumb_glue_size > 0) |
14584 { | 14835 { |
14585 osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner, | 14836 osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner, |
14586 » » » » » THUMB2ARM_GLUE_SECTION_NAME); | 14837 » » » » » THUMB2ARM_GLUE_SECTION_NAME); |
14587 | 14838 |
14588 osi.sec_shndx = _bfd_elf_section_from_bfd_section | 14839 osi.sec_shndx = _bfd_elf_section_from_bfd_section |
14589 (output_bfd, osi.sec->output_section); | 14840 (output_bfd, osi.sec->output_section); |
14590 size = THUMB2ARM_GLUE_SIZE; | 14841 size = THUMB2ARM_GLUE_SIZE; |
14591 | 14842 |
14592 for (offset = 0; offset < htab->thumb_glue_size; offset += size) | 14843 for (offset = 0; offset < htab->thumb_glue_size; offset += size) |
14593 { | 14844 { |
14594 elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, offset); | 14845 elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, offset); |
14595 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset + 4); | 14846 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset + 4); |
14596 } | 14847 } |
14597 } | 14848 } |
14598 | 14849 |
14599 /* ARMv4 BX veneers. */ | 14850 /* ARMv4 BX veneers. */ |
14600 if (htab->bx_glue_size > 0) | 14851 if (htab->bx_glue_size > 0) |
14601 { | 14852 { |
14602 osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner, | 14853 osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner, |
14603 » » » » » ARM_BX_GLUE_SECTION_NAME); | 14854 » » » » » ARM_BX_GLUE_SECTION_NAME); |
14604 | 14855 |
14605 osi.sec_shndx = _bfd_elf_section_from_bfd_section | 14856 osi.sec_shndx = _bfd_elf_section_from_bfd_section |
14606 (output_bfd, osi.sec->output_section); | 14857 (output_bfd, osi.sec->output_section); |
14607 | 14858 |
14608 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0); | 14859 elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0); |
14609 } | 14860 } |
14610 | 14861 |
14611 /* Long calls stubs. */ | 14862 /* Long calls stubs. */ |
14612 if (htab->stub_bfd && htab->stub_bfd->sections) | 14863 if (htab->stub_bfd && htab->stub_bfd->sections) |
14613 { | 14864 { |
(...skipping 29 matching lines...) Expand all Loading... |
14643 { | 14894 { |
14644 /* VxWorks shared libraries have no PLT header. */ | 14895 /* VxWorks shared libraries have no PLT header. */ |
14645 if (!info->shared) | 14896 if (!info->shared) |
14646 { | 14897 { |
14647 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) | 14898 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) |
14648 return FALSE; | 14899 return FALSE; |
14649 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12)) | 14900 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12)) |
14650 return FALSE; | 14901 return FALSE; |
14651 } | 14902 } |
14652 } | 14903 } |
| 14904 else if (htab->nacl_p) |
| 14905 { |
| 14906 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) |
| 14907 return FALSE; |
| 14908 } |
14653 else if (!htab->symbian_p) | 14909 else if (!htab->symbian_p) |
14654 { | 14910 { |
14655 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) | 14911 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) |
14656 return FALSE; | 14912 return FALSE; |
14657 #ifndef FOUR_WORD_PLT | 14913 #ifndef FOUR_WORD_PLT |
14658 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 16)) | 14914 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 16)) |
14659 return FALSE; | 14915 return FALSE; |
14660 #endif | 14916 #endif |
14661 } | 14917 } |
14662 } | 14918 } |
(...skipping 19 matching lines...) Expand all Loading... |
14682 &local_iplt[i]->arm)) | 14938 &local_iplt[i]->arm)) |
14683 return FALSE; | 14939 return FALSE; |
14684 } | 14940 } |
14685 } | 14941 } |
14686 } | 14942 } |
14687 if (htab->dt_tlsdesc_plt != 0) | 14943 if (htab->dt_tlsdesc_plt != 0) |
14688 { | 14944 { |
14689 /* Mapping symbols for the lazy tls trampoline. */ | 14945 /* Mapping symbols for the lazy tls trampoline. */ |
14690 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->dt_tlsdesc_plt)) | 14946 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->dt_tlsdesc_plt)) |
14691 return FALSE; | 14947 return FALSE; |
14692 | 14948 |
14693 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, | 14949 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, |
14694 htab->dt_tlsdesc_plt + 24)) | 14950 htab->dt_tlsdesc_plt + 24)) |
14695 return FALSE; | 14951 return FALSE; |
14696 } | 14952 } |
14697 if (htab->tls_trampoline != 0) | 14953 if (htab->tls_trampoline != 0) |
14698 { | 14954 { |
14699 /* Mapping symbols for the tls trampoline. */ | 14955 /* Mapping symbols for the tls trampoline. */ |
14700 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->tls_trampoline)) | 14956 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->tls_trampoline)) |
14701 return FALSE; | 14957 return FALSE; |
14702 #ifdef FOUR_WORD_PLT | 14958 #ifdef FOUR_WORD_PLT |
14703 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, | 14959 if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, |
14704 htab->tls_trampoline + 12)) | 14960 htab->tls_trampoline + 12)) |
14705 return FALSE; | 14961 return FALSE; |
14706 #endif | 14962 #endif |
14707 } | 14963 } |
14708 | 14964 |
14709 return TRUE; | 14965 return TRUE; |
14710 } | 14966 } |
14711 | 14967 |
14712 /* Allocate target specific section data. */ | 14968 /* Allocate target specific section data. */ |
14713 | 14969 |
14714 static bfd_boolean | 14970 static bfd_boolean |
14715 elf32_arm_new_section_hook (bfd *abfd, asection *sec) | 14971 elf32_arm_new_section_hook (bfd *abfd, asection *sec) |
14716 { | 14972 { |
14717 if (!sec->used_by_bfd) | 14973 if (!sec->used_by_bfd) |
14718 { | 14974 { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14761 } | 15017 } |
14762 | 15018 |
14763 /* Copy an .ARM.exidx table entry, adding OFFSET to (applied) PREL31 | 15019 /* Copy an .ARM.exidx table entry, adding OFFSET to (applied) PREL31 |
14764 relocations. */ | 15020 relocations. */ |
14765 | 15021 |
14766 static void | 15022 static void |
14767 copy_exidx_entry (bfd *output_bfd, bfd_byte *to, bfd_byte *from, bfd_vma offset) | 15023 copy_exidx_entry (bfd *output_bfd, bfd_byte *to, bfd_byte *from, bfd_vma offset) |
14768 { | 15024 { |
14769 unsigned long first_word = bfd_get_32 (output_bfd, from); | 15025 unsigned long first_word = bfd_get_32 (output_bfd, from); |
14770 unsigned long second_word = bfd_get_32 (output_bfd, from + 4); | 15026 unsigned long second_word = bfd_get_32 (output_bfd, from + 4); |
14771 | 15027 |
14772 /* High bit of first word is supposed to be zero. */ | 15028 /* High bit of first word is supposed to be zero. */ |
14773 if ((first_word & 0x80000000ul) == 0) | 15029 if ((first_word & 0x80000000ul) == 0) |
14774 first_word = offset_prel31 (first_word, offset); | 15030 first_word = offset_prel31 (first_word, offset); |
14775 | 15031 |
14776 /* If the high bit of the first word is clear, and the bit pattern is not 0x1 | 15032 /* If the high bit of the first word is clear, and the bit pattern is not 0x1 |
14777 (EXIDX_CANTUNWIND), this is an offset to an .ARM.extab entry. */ | 15033 (EXIDX_CANTUNWIND), this is an offset to an .ARM.extab entry. */ |
14778 if ((second_word != 0x1) && ((second_word & 0x80000000ul) == 0)) | 15034 if ((second_word != 0x1) && ((second_word & 0x80000000ul) == 0)) |
14779 second_word = offset_prel31 (second_word, offset); | 15035 second_word = offset_prel31 (second_word, offset); |
14780 | 15036 |
14781 bfd_put_32 (output_bfd, first_word, to); | 15037 bfd_put_32 (output_bfd, first_word, to); |
14782 bfd_put_32 (output_bfd, second_word, to + 4); | 15038 bfd_put_32 (output_bfd, second_word, to + 4); |
14783 } | 15039 } |
14784 | 15040 |
14785 /* Data for make_branch_to_a8_stub(). */ | 15041 /* Data for make_branch_to_a8_stub(). */ |
14786 | 15042 |
14787 struct a8_branch_to_stub_data { | 15043 struct a8_branch_to_stub_data |
| 15044 { |
14788 asection *writing_section; | 15045 asection *writing_section; |
14789 bfd_byte *contents; | 15046 bfd_byte *contents; |
14790 }; | 15047 }; |
14791 | 15048 |
14792 | 15049 |
14793 /* Helper to insert branches to Cortex-A8 erratum stubs in the right | 15050 /* Helper to insert branches to Cortex-A8 erratum stubs in the right |
14794 places for a particular section. */ | 15051 places for a particular section. */ |
14795 | 15052 |
14796 static bfd_boolean | 15053 static bfd_boolean |
14797 make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry, | 15054 make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry, |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15015 bfd_byte *edited_contents = (bfd_byte *) bfd_malloc (sec->size); | 15272 bfd_byte *edited_contents = (bfd_byte *) bfd_malloc (sec->size); |
15016 unsigned int input_size = sec->rawsize ? sec->rawsize : sec->size; | 15273 unsigned int input_size = sec->rawsize ? sec->rawsize : sec->size; |
15017 unsigned int in_index, out_index; | 15274 unsigned int in_index, out_index; |
15018 bfd_vma add_to_offsets = 0; | 15275 bfd_vma add_to_offsets = 0; |
15019 | 15276 |
15020 for (in_index = 0, out_index = 0; in_index * 8 < input_size || edit_node;) | 15277 for (in_index = 0, out_index = 0; in_index * 8 < input_size || edit_node;) |
15021 { | 15278 { |
15022 if (edit_node) | 15279 if (edit_node) |
15023 { | 15280 { |
15024 unsigned int edit_index = edit_node->index; | 15281 unsigned int edit_index = edit_node->index; |
15025 » | 15282 |
15026 if (in_index < edit_index && in_index * 8 < input_size) | 15283 if (in_index < edit_index && in_index * 8 < input_size) |
15027 { | 15284 { |
15028 copy_exidx_entry (output_bfd, edited_contents + out_index * 8, | 15285 copy_exidx_entry (output_bfd, edited_contents + out_index * 8, |
15029 contents + in_index * 8, add_to_offsets); | 15286 contents + in_index * 8, add_to_offsets); |
15030 out_index++; | 15287 out_index++; |
15031 in_index++; | 15288 in_index++; |
15032 } | 15289 } |
15033 else if (in_index == edit_index | 15290 else if (in_index == edit_index |
15034 || (in_index * 8 >= input_size | 15291 || (in_index * 8 >= input_size |
15035 && edit_index == UINT_MAX)) | 15292 && edit_index == UINT_MAX)) |
15036 { | 15293 { |
15037 switch (edit_node->type) | 15294 switch (edit_node->type) |
15038 { | 15295 { |
15039 case DELETE_EXIDX_ENTRY: | 15296 case DELETE_EXIDX_ENTRY: |
15040 in_index++; | 15297 in_index++; |
15041 add_to_offsets += 8; | 15298 add_to_offsets += 8; |
15042 break; | 15299 break; |
15043 » » | 15300 |
15044 case INSERT_EXIDX_CANTUNWIND_AT_END: | 15301 case INSERT_EXIDX_CANTUNWIND_AT_END: |
15045 { | 15302 { |
15046 asection *text_sec = edit_node->linked_section; | 15303 asection *text_sec = edit_node->linked_section; |
15047 bfd_vma text_offset = text_sec->output_section->vma | 15304 bfd_vma text_offset = text_sec->output_section->vma |
15048 + text_sec->output_offset | 15305 + text_sec->output_offset |
15049 + text_sec->size; | 15306 + text_sec->size; |
15050 bfd_vma exidx_offset = offset + out_index * 8; | 15307 bfd_vma exidx_offset = offset + out_index * 8; |
15051 unsigned long prel31_offset; | 15308 unsigned long prel31_offset; |
15052 | 15309 |
15053 /* Note: this is meant to be equivalent to an | 15310 /* Note: this is meant to be equivalent to an |
15054 R_ARM_PREL31 relocation. These synthetic | 15311 R_ARM_PREL31 relocation. These synthetic |
15055 EXIDX_CANTUNWIND markers are not relocated by the | 15312 EXIDX_CANTUNWIND markers are not relocated by the |
15056 usual BFD method. */ | 15313 usual BFD method. */ |
15057 prel31_offset = (text_offset - exidx_offset) | 15314 prel31_offset = (text_offset - exidx_offset) |
15058 & 0x7ffffffful; | 15315 & 0x7ffffffful; |
15059 | 15316 |
15060 /* First address we can't unwind. */ | 15317 /* First address we can't unwind. */ |
15061 bfd_put_32 (output_bfd, prel31_offset, | 15318 bfd_put_32 (output_bfd, prel31_offset, |
15062 &edited_contents[out_index * 8]); | 15319 &edited_contents[out_index * 8]); |
15063 | 15320 |
15064 /* Code for EXIDX_CANTUNWIND. */ | 15321 /* Code for EXIDX_CANTUNWIND. */ |
15065 bfd_put_32 (output_bfd, 0x1, | 15322 bfd_put_32 (output_bfd, 0x1, |
15066 &edited_contents[out_index * 8 + 4]); | 15323 &edited_contents[out_index * 8 + 4]); |
15067 | 15324 |
15068 out_index++; | 15325 out_index++; |
15069 add_to_offsets -= 8; | 15326 add_to_offsets -= 8; |
15070 } | 15327 } |
15071 break; | 15328 break; |
15072 } | 15329 } |
15073 » » | 15330 |
15074 edit_node = edit_node->next; | 15331 edit_node = edit_node->next; |
15075 } | 15332 } |
15076 } | 15333 } |
15077 else | 15334 else |
15078 { | 15335 { |
15079 /* No more edits, copy remaining entries verbatim. */ | 15336 /* No more edits, copy remaining entries verbatim. */ |
15080 copy_exidx_entry (output_bfd, edited_contents + out_index * 8, | 15337 copy_exidx_entry (output_bfd, edited_contents + out_index * 8, |
15081 contents + in_index * 8, add_to_offsets); | 15338 contents + in_index * 8, add_to_offsets); |
15082 out_index++; | 15339 out_index++; |
15083 in_index++; | 15340 in_index++; |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15353 | 15610 |
15354 #define bfd_elf32_mkobject elf32_arm_mkobject | 15611 #define bfd_elf32_mkobject elf32_arm_mkobject |
15355 | 15612 |
15356 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data | 15613 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data |
15357 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data | 15614 #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data |
15358 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags | 15615 #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags |
15359 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data | 15616 #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data |
15360 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create | 15617 #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create |
15361 #define bfd_elf32_bfd_link_hash_table_free elf32_arm_hash_table_free | 15618 #define bfd_elf32_bfd_link_hash_table_free elf32_arm_hash_table_free |
15362 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup | 15619 #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup |
15363 #define bfd_elf32_bfd_reloc_name_lookup»elf32_arm_reloc_name_lookup | 15620 #define bfd_elf32_bfd_reloc_name_lookup»» elf32_arm_reloc_name_lookup |
15364 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line | 15621 #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line |
15365 #define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info | 15622 #define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info |
15366 #define bfd_elf32_new_section_hook elf32_arm_new_section_hook | 15623 #define bfd_elf32_new_section_hook elf32_arm_new_section_hook |
15367 #define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symb
ol | 15624 #define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symb
ol |
15368 #define bfd_elf32_bfd_final_link elf32_arm_final_link | 15625 #define bfd_elf32_bfd_final_link elf32_arm_final_link |
15369 | 15626 |
15370 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type | 15627 #define elf_backend_get_symbol_type elf32_arm_get_symbol_type |
15371 #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook | 15628 #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook |
15372 #define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections | 15629 #define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections |
15373 #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook | 15630 #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15407 #define elf_backend_got_header_size 12 | 15664 #define elf_backend_got_header_size 12 |
15408 | 15665 |
15409 #undef elf_backend_obj_attrs_vendor | 15666 #undef elf_backend_obj_attrs_vendor |
15410 #define elf_backend_obj_attrs_vendor "aeabi" | 15667 #define elf_backend_obj_attrs_vendor "aeabi" |
15411 #undef elf_backend_obj_attrs_section | 15668 #undef elf_backend_obj_attrs_section |
15412 #define elf_backend_obj_attrs_section ".ARM.attributes" | 15669 #define elf_backend_obj_attrs_section ".ARM.attributes" |
15413 #undef elf_backend_obj_attrs_arg_type | 15670 #undef elf_backend_obj_attrs_arg_type |
15414 #define elf_backend_obj_attrs_arg_type elf32_arm_obj_attrs_arg_type | 15671 #define elf_backend_obj_attrs_arg_type elf32_arm_obj_attrs_arg_type |
15415 #undef elf_backend_obj_attrs_section_type | 15672 #undef elf_backend_obj_attrs_section_type |
15416 #define elf_backend_obj_attrs_section_type SHT_ARM_ATTRIBUTES | 15673 #define elf_backend_obj_attrs_section_type SHT_ARM_ATTRIBUTES |
15417 #define elf_backend_obj_attrs_order» elf32_arm_obj_attrs_order | 15674 #define elf_backend_obj_attrs_order» » elf32_arm_obj_attrs_order |
15418 #define elf_backend_obj_attrs_handle_unknown elf32_arm_obj_attrs_handle_unknown | 15675 #define elf_backend_obj_attrs_handle_unknown » elf32_arm_obj_attrs_handle_unkno
wn |
15419 | 15676 |
15420 #include "elf32-target.h" | 15677 #include "elf32-target.h" |
15421 | 15678 |
| 15679 /* Native Client targets. */ |
| 15680 |
| 15681 #undef TARGET_LITTLE_SYM |
| 15682 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_nacl_vec |
| 15683 #undef TARGET_LITTLE_NAME |
| 15684 #define TARGET_LITTLE_NAME "elf32-littlearm-nacl" |
| 15685 #undef TARGET_BIG_SYM |
| 15686 #define TARGET_BIG_SYM bfd_elf32_bigarm_nacl_vec |
| 15687 #undef TARGET_BIG_NAME |
| 15688 #define TARGET_BIG_NAME "elf32-bigarm-nacl" |
| 15689 |
| 15690 /* Like elf32_arm_link_hash_table_create -- but overrides |
| 15691 appropriately for NaCl. */ |
| 15692 |
| 15693 static struct bfd_link_hash_table * |
| 15694 elf32_arm_nacl_link_hash_table_create (bfd *abfd) |
| 15695 { |
| 15696 struct bfd_link_hash_table *ret; |
| 15697 |
| 15698 ret = elf32_arm_link_hash_table_create (abfd); |
| 15699 if (ret) |
| 15700 { |
| 15701 struct elf32_arm_link_hash_table *htab |
| 15702 = (struct elf32_arm_link_hash_table *) ret; |
| 15703 |
| 15704 htab->nacl_p = 1; |
| 15705 |
| 15706 htab->plt_header_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt0_entry); |
| 15707 htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt_entry); |
| 15708 } |
| 15709 return ret; |
| 15710 } |
| 15711 |
| 15712 /* Since NaCl doesn't use the ARM-specific unwind format, we don't |
| 15713 really need to use elf32_arm_modify_segment_map. But we do it |
| 15714 anyway just to reduce gratuitous differences with the stock ARM backend. */ |
| 15715 |
| 15716 static bfd_boolean |
| 15717 elf32_arm_nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info) |
| 15718 { |
| 15719 return (elf32_arm_modify_segment_map (abfd, info) |
| 15720 && nacl_modify_segment_map (abfd, info)); |
| 15721 } |
| 15722 |
| 15723 #undef elf32_bed |
| 15724 #define elf32_bed elf32_arm_nacl_bed |
| 15725 #undef bfd_elf32_bfd_link_hash_table_create |
| 15726 #define bfd_elf32_bfd_link_hash_table_create \ |
| 15727 elf32_arm_nacl_link_hash_table_create |
| 15728 #undef elf_backend_plt_alignment |
| 15729 #define elf_backend_plt_alignment 4 |
| 15730 #undef elf_backend_modify_segment_map |
| 15731 #define elf_backend_modify_segment_map elf32_arm_nacl_modify_segment_ma
p |
| 15732 #undef elf_backend_modify_program_headers |
| 15733 #define elf_backend_modify_program_headers nacl_modify_program_headers |
| 15734 |
| 15735 #undef ELF_MAXPAGESIZE |
| 15736 #define ELF_MAXPAGESIZE 0x10000 |
| 15737 |
| 15738 #include "elf32-target.h" |
| 15739 |
| 15740 /* Reset to defaults. */ |
| 15741 #undef elf_backend_plt_alignment |
| 15742 #undef elf_backend_modify_segment_map |
| 15743 #define elf_backend_modify_segment_map elf32_arm_modify_segment_map |
| 15744 #undef elf_backend_modify_program_headers |
| 15745 |
15422 /* VxWorks Targets. */ | 15746 /* VxWorks Targets. */ |
15423 | 15747 |
15424 #undef TARGET_LITTLE_SYM | 15748 #undef TARGET_LITTLE_SYM |
15425 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vxworks_vec | 15749 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vxworks_vec |
15426 #undef TARGET_LITTLE_NAME | 15750 #undef TARGET_LITTLE_NAME |
15427 #define TARGET_LITTLE_NAME "elf32-littlearm-vxworks" | 15751 #define TARGET_LITTLE_NAME "elf32-littlearm-vxworks" |
15428 #undef TARGET_BIG_SYM | 15752 #undef TARGET_BIG_SYM |
15429 #define TARGET_BIG_SYM bfd_elf32_bigarm_vxworks_vec | 15753 #define TARGET_BIG_SYM bfd_elf32_bigarm_vxworks_vec |
15430 #undef TARGET_BIG_NAME | 15754 #undef TARGET_BIG_NAME |
15431 #define TARGET_BIG_NAME "elf32-bigarm-vxworks" | 15755 #define TARGET_BIG_NAME "elf32-bigarm-vxworks" |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15858 #undef elf_backend_may_use_rela_p | 16182 #undef elf_backend_may_use_rela_p |
15859 #define elf_backend_may_use_rela_p 0 | 16183 #define elf_backend_may_use_rela_p 0 |
15860 #undef elf_backend_default_use_rela_p | 16184 #undef elf_backend_default_use_rela_p |
15861 #define elf_backend_default_use_rela_p 0 | 16185 #define elf_backend_default_use_rela_p 0 |
15862 #undef elf_backend_want_plt_sym | 16186 #undef elf_backend_want_plt_sym |
15863 #define elf_backend_want_plt_sym 0 | 16187 #define elf_backend_want_plt_sym 0 |
15864 #undef ELF_MAXPAGESIZE | 16188 #undef ELF_MAXPAGESIZE |
15865 #define ELF_MAXPAGESIZE 0x8000 | 16189 #define ELF_MAXPAGESIZE 0x8000 |
15866 | 16190 |
15867 #include "elf32-target.h" | 16191 #include "elf32-target.h" |
OLD | NEW |