| 1 | /* i370-specific support for 32-bit ELF
|
|---|
| 2 | Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001
|
|---|
| 3 | Free Software Foundation, Inc.
|
|---|
| 4 | Written by Ian Lance Taylor, Cygnus Support.
|
|---|
| 5 | Hacked by Linas Vepstas for i370 [email protected]
|
|---|
| 6 |
|
|---|
| 7 | This file is part of BFD, the Binary File Descriptor library.
|
|---|
| 8 |
|
|---|
| 9 | This program is free software; you can redistribute it and/or modify
|
|---|
| 10 | it under the terms of the GNU General Public License as published by
|
|---|
| 11 | the Free Software Foundation; either version 2 of the License, or
|
|---|
| 12 | (at your option) any later version.
|
|---|
| 13 |
|
|---|
| 14 | This program is distributed in the hope that it will be useful,
|
|---|
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 17 | GNU General Public License for more details.
|
|---|
| 18 |
|
|---|
| 19 | You should have received a copy of the GNU General Public License
|
|---|
| 20 | along with this program; if not, write to the Free Software
|
|---|
| 21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|---|
| 22 |
|
|---|
| 23 | /* This file is based on a preliminary PowerPC ELF ABI.
|
|---|
| 24 | But its been hacked on for the IBM 360/370 architectures.
|
|---|
| 25 | Basically, the 31bit relocation works, and just about everything
|
|---|
| 26 | else is a wild card. In particular, don't expect shared libs or
|
|---|
| 27 | dynamic loading to work ... its never been tested ...
|
|---|
| 28 | */
|
|---|
| 29 |
|
|---|
| 30 | #include "bfd.h"
|
|---|
| 31 | #include "sysdep.h"
|
|---|
| 32 | #include "bfdlink.h"
|
|---|
| 33 | #include "libbfd.h"
|
|---|
| 34 | #include "elf-bfd.h"
|
|---|
| 35 | #include "elf/i370.h"
|
|---|
| 36 |
|
|---|
| 37 | #define USE_RELA /* we want RELA relocations, not REL */
|
|---|
| 38 |
|
|---|
| 39 | /* i370 relocations */
|
|---|
| 40 | /* Note that there is really just one relocation that we currently
|
|---|
| 41 | * support (and only one that we seem to need, at the moment), and
|
|---|
| 42 | * that is the 31-bit address relocation. Note that the 370/390
|
|---|
| 43 | * only supports a 31-bit (2GB) address space.
|
|---|
| 44 | */
|
|---|
| 45 | enum i370_reloc_type
|
|---|
| 46 | {
|
|---|
| 47 | R_I370_NONE = 0,
|
|---|
| 48 | R_I370_ADDR31 = 1,
|
|---|
| 49 | R_I370_ADDR32 = 2,
|
|---|
| 50 | R_I370_ADDR16 = 3,
|
|---|
| 51 | R_I370_REL31 = 4,
|
|---|
| 52 | R_I370_REL32 = 5,
|
|---|
| 53 | R_I370_ADDR12 = 6,
|
|---|
| 54 | R_I370_REL12 = 7,
|
|---|
| 55 | R_I370_ADDR8 = 8,
|
|---|
| 56 | R_I370_REL8 = 9,
|
|---|
| 57 | R_I370_COPY = 10,
|
|---|
| 58 | R_I370_RELATIVE = 11,
|
|---|
| 59 |
|
|---|
| 60 | R_I370_max
|
|---|
| 61 | };
|
|---|
| 62 | |
|---|
| 63 |
|
|---|
| 64 | static reloc_howto_type *i370_elf_howto_table[ (int)R_I370_max ];
|
|---|
| 65 |
|
|---|
| 66 | static reloc_howto_type i370_elf_howto_raw[] =
|
|---|
| 67 | {
|
|---|
| 68 | /* This reloc does nothing. */
|
|---|
| 69 | HOWTO (R_I370_NONE, /* type */
|
|---|
| 70 | 0, /* rightshift */
|
|---|
| 71 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 72 | 32, /* bitsize */
|
|---|
| 73 | false, /* pc_relative */
|
|---|
| 74 | 0, /* bitpos */
|
|---|
| 75 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 76 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 77 | "R_I370_NONE", /* name */
|
|---|
| 78 | false, /* partial_inplace */
|
|---|
| 79 | 0, /* src_mask */
|
|---|
| 80 | 0, /* dst_mask */
|
|---|
| 81 | false), /* pcrel_offset */
|
|---|
| 82 |
|
|---|
| 83 | /* A standard 31 bit relocation. */
|
|---|
| 84 | HOWTO (R_I370_ADDR31, /* type */
|
|---|
| 85 | 0, /* rightshift */
|
|---|
| 86 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 87 | 31, /* bitsize */
|
|---|
| 88 | false, /* pc_relative */
|
|---|
| 89 | 0, /* bitpos */
|
|---|
| 90 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 91 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 92 | "R_I370_ADDR31", /* name */
|
|---|
| 93 | false, /* partial_inplace */
|
|---|
| 94 | 0, /* src_mask */
|
|---|
| 95 | 0x7fffffff, /* dst_mask */
|
|---|
| 96 | false), /* pcrel_offset */
|
|---|
| 97 |
|
|---|
| 98 | /* A standard 32 bit relocation. */
|
|---|
| 99 | HOWTO (R_I370_ADDR32, /* type */
|
|---|
| 100 | 0, /* rightshift */
|
|---|
| 101 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 102 | 32, /* bitsize */
|
|---|
| 103 | false, /* pc_relative */
|
|---|
| 104 | 0, /* bitpos */
|
|---|
| 105 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 106 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 107 | "R_I370_ADDR32", /* name */
|
|---|
| 108 | false, /* partial_inplace */
|
|---|
| 109 | 0, /* src_mask */
|
|---|
| 110 | 0xffffffff, /* dst_mask */
|
|---|
| 111 | false), /* pcrel_offset */
|
|---|
| 112 |
|
|---|
| 113 | /* A standard 16 bit relocation. */
|
|---|
| 114 | HOWTO (R_I370_ADDR16, /* type */
|
|---|
| 115 | 0, /* rightshift */
|
|---|
| 116 | 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 117 | 16, /* bitsize */
|
|---|
| 118 | false, /* pc_relative */
|
|---|
| 119 | 0, /* bitpos */
|
|---|
| 120 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 121 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 122 | "R_I370_ADDR16", /* name */
|
|---|
| 123 | false, /* partial_inplace */
|
|---|
| 124 | 0, /* src_mask */
|
|---|
| 125 | 0xffff, /* dst_mask */
|
|---|
| 126 | false), /* pcrel_offset */
|
|---|
| 127 |
|
|---|
| 128 | /* 31-bit PC relative */
|
|---|
| 129 | HOWTO (R_I370_REL31, /* type */
|
|---|
| 130 | 0, /* rightshift */
|
|---|
| 131 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 132 | 31, /* bitsize */
|
|---|
| 133 | true, /* pc_relative */
|
|---|
| 134 | 0, /* bitpos */
|
|---|
| 135 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 136 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 137 | "R_I370_REL31", /* name */
|
|---|
| 138 | false, /* partial_inplace */
|
|---|
| 139 | 0, /* src_mask */
|
|---|
| 140 | 0x7fffffff, /* dst_mask */
|
|---|
| 141 | true), /* pcrel_offset */
|
|---|
| 142 |
|
|---|
| 143 | /* 32-bit PC relative */
|
|---|
| 144 | HOWTO (R_I370_REL32, /* type */
|
|---|
| 145 | 0, /* rightshift */
|
|---|
| 146 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 147 | 32, /* bitsize */
|
|---|
| 148 | true, /* pc_relative */
|
|---|
| 149 | 0, /* bitpos */
|
|---|
| 150 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 151 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 152 | "R_I370_REL32", /* name */
|
|---|
| 153 | false, /* partial_inplace */
|
|---|
| 154 | 0, /* src_mask */
|
|---|
| 155 | 0xffffffff, /* dst_mask */
|
|---|
| 156 | true), /* pcrel_offset */
|
|---|
| 157 |
|
|---|
| 158 | /* A standard 12 bit relocation. */
|
|---|
| 159 | HOWTO (R_I370_ADDR12, /* type */
|
|---|
| 160 | 0, /* rightshift */
|
|---|
| 161 | 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 162 | 12, /* bitsize */
|
|---|
| 163 | false, /* pc_relative */
|
|---|
| 164 | 0, /* bitpos */
|
|---|
| 165 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 166 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 167 | "R_I370_ADDR12", /* name */
|
|---|
| 168 | false, /* partial_inplace */
|
|---|
| 169 | 0, /* src_mask */
|
|---|
| 170 | 0xfff, /* dst_mask */
|
|---|
| 171 | false), /* pcrel_offset */
|
|---|
| 172 |
|
|---|
| 173 | /* 12-bit PC relative */
|
|---|
| 174 | HOWTO (R_I370_REL12, /* type */
|
|---|
| 175 | 0, /* rightshift */
|
|---|
| 176 | 1, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 177 | 12, /* bitsize */
|
|---|
| 178 | true, /* pc_relative */
|
|---|
| 179 | 0, /* bitpos */
|
|---|
| 180 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 181 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 182 | "R_I370_REL12", /* name */
|
|---|
| 183 | false, /* partial_inplace */
|
|---|
| 184 | 0, /* src_mask */
|
|---|
| 185 | 0xfff, /* dst_mask */
|
|---|
| 186 | true), /* pcrel_offset */
|
|---|
| 187 |
|
|---|
| 188 | /* A standard 8 bit relocation. */
|
|---|
| 189 | HOWTO (R_I370_ADDR8, /* type */
|
|---|
| 190 | 0, /* rightshift */
|
|---|
| 191 | 0, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 192 | 8, /* bitsize */
|
|---|
| 193 | false, /* pc_relative */
|
|---|
| 194 | 0, /* bitpos */
|
|---|
| 195 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 196 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 197 | "R_I370_ADDR8", /* name */
|
|---|
| 198 | false, /* partial_inplace */
|
|---|
| 199 | 0, /* src_mask */
|
|---|
| 200 | 0xff, /* dst_mask */
|
|---|
| 201 | false), /* pcrel_offset */
|
|---|
| 202 |
|
|---|
| 203 | /* 8-bit PC relative */
|
|---|
| 204 | HOWTO (R_I370_REL8, /* type */
|
|---|
| 205 | 0, /* rightshift */
|
|---|
| 206 | 0, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 207 | 8, /* bitsize */
|
|---|
| 208 | true, /* pc_relative */
|
|---|
| 209 | 0, /* bitpos */
|
|---|
| 210 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 211 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 212 | "R_I370_REL8", /* name */
|
|---|
| 213 | false, /* partial_inplace */
|
|---|
| 214 | 0, /* src_mask */
|
|---|
| 215 | 0xff, /* dst_mask */
|
|---|
| 216 | true), /* pcrel_offset */
|
|---|
| 217 |
|
|---|
| 218 | /* This is used only by the dynamic linker. The symbol should exist
|
|---|
| 219 | both in the object being run and in some shared library. The
|
|---|
| 220 | dynamic linker copies the data addressed by the symbol from the
|
|---|
| 221 | shared library into the object, because the object being
|
|---|
| 222 | run has to have the data at some particular address. */
|
|---|
| 223 | HOWTO (R_I370_COPY, /* type */
|
|---|
| 224 | 0, /* rightshift */
|
|---|
| 225 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 226 | 32, /* bitsize */
|
|---|
| 227 | false, /* pc_relative */
|
|---|
| 228 | 0, /* bitpos */
|
|---|
| 229 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 230 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 231 | "R_I370_COPY", /* name */
|
|---|
| 232 | false, /* partial_inplace */
|
|---|
| 233 | 0, /* src_mask */
|
|---|
| 234 | 0, /* dst_mask */
|
|---|
| 235 | false), /* pcrel_offset */
|
|---|
| 236 |
|
|---|
| 237 | /* Used only by the dynamic linker. When the object is run, this
|
|---|
| 238 | longword is set to the load address of the object, plus the
|
|---|
| 239 | addend. */
|
|---|
| 240 | HOWTO (R_I370_RELATIVE, /* type */
|
|---|
| 241 | 0, /* rightshift */
|
|---|
| 242 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 243 | 32, /* bitsize */
|
|---|
| 244 | false, /* pc_relative */
|
|---|
| 245 | 0, /* bitpos */
|
|---|
| 246 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 247 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 248 | "R_I370_RELATIVE", /* name */
|
|---|
| 249 | false, /* partial_inplace */
|
|---|
| 250 | 0, /* src_mask */
|
|---|
| 251 | 0xffffffff, /* dst_mask */
|
|---|
| 252 | false), /* pcrel_offset */
|
|---|
| 253 |
|
|---|
| 254 | };
|
|---|
| 255 | |
|---|
| 256 |
|
|---|
| 257 | static void i370_elf_howto_init PARAMS ((void));
|
|---|
| 258 | static void i370_elf_info_to_howto PARAMS ((bfd *abfd, arelent *cache_ptr,
|
|---|
| 259 | Elf32_Internal_Rela *dst));
|
|---|
| 260 | static boolean i370_elf_set_private_flags PARAMS ((bfd *, flagword));
|
|---|
| 261 | |
|---|
| 262 |
|
|---|
| 263 | /* Initialize the i370_elf_howto_table, so that linear accesses can be done. */
|
|---|
| 264 |
|
|---|
| 265 | static void
|
|---|
| 266 | i370_elf_howto_init ()
|
|---|
| 267 | {
|
|---|
| 268 | unsigned int i, type;
|
|---|
| 269 |
|
|---|
| 270 | for (i = 0; i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]); i++)
|
|---|
| 271 | {
|
|---|
| 272 | type = i370_elf_howto_raw[i].type;
|
|---|
| 273 | BFD_ASSERT (type < sizeof (i370_elf_howto_table) / sizeof (i370_elf_howto_table[0]));
|
|---|
| 274 | i370_elf_howto_table[type] = &i370_elf_howto_raw[i];
|
|---|
| 275 | }
|
|---|
| 276 | }
|
|---|
| 277 | |
|---|
| 278 |
|
|---|
| 279 | static reloc_howto_type *
|
|---|
| 280 | i370_elf_reloc_type_lookup (abfd, code)
|
|---|
| 281 | bfd *abfd ATTRIBUTE_UNUSED;
|
|---|
| 282 | bfd_reloc_code_real_type code;
|
|---|
| 283 | {
|
|---|
| 284 | enum i370_reloc_type i370_reloc = R_I370_NONE;
|
|---|
| 285 |
|
|---|
| 286 | if (!i370_elf_howto_table[ R_I370_ADDR31 ]) /* Initialize howto table if needed */
|
|---|
| 287 | i370_elf_howto_init ();
|
|---|
| 288 |
|
|---|
| 289 | switch ((int)code)
|
|---|
| 290 | {
|
|---|
| 291 | default:
|
|---|
| 292 | return (reloc_howto_type *)NULL;
|
|---|
| 293 |
|
|---|
| 294 | case BFD_RELOC_NONE: i370_reloc = R_I370_NONE; break;
|
|---|
| 295 | case BFD_RELOC_32: i370_reloc = R_I370_ADDR31; break;
|
|---|
| 296 | case BFD_RELOC_16: i370_reloc = R_I370_ADDR16; break;
|
|---|
| 297 | case BFD_RELOC_32_PCREL: i370_reloc = R_I370_REL31; break;
|
|---|
| 298 | case BFD_RELOC_CTOR: i370_reloc = R_I370_ADDR31; break;
|
|---|
| 299 | case BFD_RELOC_I370_D12: i370_reloc = R_I370_ADDR12; break;
|
|---|
| 300 | }
|
|---|
| 301 |
|
|---|
| 302 | return i370_elf_howto_table[ (int)i370_reloc ];
|
|---|
| 303 | };
|
|---|
| 304 |
|
|---|
| 305 | static boolean i370_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
|---|
| 306 | static boolean i370_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
|
|---|
| 307 |
|
|---|
| 308 | static boolean i370_elf_relocate_section PARAMS ((bfd *,
|
|---|
| 309 | struct bfd_link_info *info,
|
|---|
| 310 | bfd *,
|
|---|
| 311 | asection *,
|
|---|
| 312 | bfd_byte *,
|
|---|
| 313 | Elf_Internal_Rela *relocs,
|
|---|
| 314 | Elf_Internal_Sym *local_syms,
|
|---|
| 315 | asection **));
|
|---|
| 316 |
|
|---|
| 317 | static boolean i370_elf_create_dynamic_sections PARAMS ((bfd *,
|
|---|
| 318 | struct bfd_link_info *));
|
|---|
| 319 |
|
|---|
| 320 | static boolean i370_elf_section_from_shdr PARAMS ((bfd *,
|
|---|
| 321 | Elf32_Internal_Shdr *,
|
|---|
| 322 | char *));
|
|---|
| 323 | static boolean i370_elf_fake_sections PARAMS ((bfd *,
|
|---|
| 324 | Elf32_Internal_Shdr *,
|
|---|
| 325 | asection *));
|
|---|
| 326 | #if 0
|
|---|
| 327 | static elf_linker_section_t *i370_elf_create_linker_section
|
|---|
| 328 | PARAMS ((bfd *abfd,
|
|---|
| 329 | struct bfd_link_info *info,
|
|---|
| 330 | enum elf_linker_section_enum));
|
|---|
| 331 | #endif
|
|---|
| 332 | static boolean i370_elf_check_relocs PARAMS ((bfd *,
|
|---|
| 333 | struct bfd_link_info *,
|
|---|
| 334 | asection *,
|
|---|
| 335 | const Elf_Internal_Rela *));
|
|---|
| 336 |
|
|---|
| 337 | static boolean i370_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,
|
|---|
| 338 | struct elf_link_hash_entry *));
|
|---|
| 339 |
|
|---|
| 340 | static boolean i370_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR));
|
|---|
| 341 |
|
|---|
| 342 | static boolean i370_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
|
|---|
| 343 |
|
|---|
| 344 | static boolean i370_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
|
|---|
| 345 |
|
|---|
| 346 | /* The name of the dynamic interpreter. This is put in the .interp
|
|---|
| 347 | section. */
|
|---|
| 348 |
|
|---|
| 349 | #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
|
|---|
| 350 |
|
|---|
| 351 | /* Set the howto pointer for an i370 ELF reloc. */
|
|---|
| 352 |
|
|---|
| 353 | static void
|
|---|
| 354 | i370_elf_info_to_howto (abfd, cache_ptr, dst)
|
|---|
| 355 | bfd *abfd ATTRIBUTE_UNUSED;
|
|---|
| 356 | arelent *cache_ptr;
|
|---|
| 357 | Elf32_Internal_Rela *dst;
|
|---|
| 358 | {
|
|---|
| 359 | if (!i370_elf_howto_table[ R_I370_ADDR31 ]) /* Initialize howto table */
|
|---|
| 360 | i370_elf_howto_init ();
|
|---|
| 361 |
|
|---|
| 362 | BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_I370_max);
|
|---|
| 363 | cache_ptr->howto = i370_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
|
|---|
| 364 | }
|
|---|
| 365 |
|
|---|
| 366 | /* hack alert -- the following several routines look generic to me ...
|
|---|
| 367 | * why are we bothering with them ???
|
|---|
| 368 | */
|
|---|
| 369 | /* Function to set whether a module needs the -mrelocatable bit set. */
|
|---|
| 370 | static boolean
|
|---|
| 371 | i370_elf_set_private_flags (abfd, flags)
|
|---|
| 372 | bfd *abfd;
|
|---|
| 373 | flagword flags;
|
|---|
| 374 | {
|
|---|
| 375 | BFD_ASSERT (!elf_flags_init (abfd)
|
|---|
| 376 | || elf_elfheader (abfd)->e_flags == flags);
|
|---|
| 377 |
|
|---|
| 378 | elf_elfheader (abfd)->e_flags = flags;
|
|---|
| 379 | elf_flags_init (abfd) = true;
|
|---|
| 380 | return true;
|
|---|
| 381 | }
|
|---|
| 382 |
|
|---|
| 383 | /* Copy backend specific data from one object module to another */
|
|---|
| 384 | static boolean
|
|---|
| 385 | i370_elf_copy_private_bfd_data (ibfd, obfd)
|
|---|
| 386 | bfd *ibfd;
|
|---|
| 387 | bfd *obfd;
|
|---|
| 388 | {
|
|---|
| 389 | if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|
|---|
| 390 | || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
|---|
| 391 | return true;
|
|---|
| 392 |
|
|---|
| 393 | BFD_ASSERT (!elf_flags_init (obfd)
|
|---|
| 394 | || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
|
|---|
| 395 |
|
|---|
| 396 | elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
|---|
| 397 | elf_flags_init (obfd) = true;
|
|---|
| 398 | return true;
|
|---|
| 399 | }
|
|---|
| 400 |
|
|---|
| 401 | /* Merge backend specific data from an object file to the output
|
|---|
| 402 | object file when linking */
|
|---|
| 403 | static boolean
|
|---|
| 404 | i370_elf_merge_private_bfd_data (ibfd, obfd)
|
|---|
| 405 | bfd *ibfd;
|
|---|
| 406 | bfd *obfd;
|
|---|
| 407 | {
|
|---|
| 408 | flagword old_flags;
|
|---|
| 409 | flagword new_flags;
|
|---|
| 410 |
|
|---|
| 411 | if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|
|---|
| 412 | || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
|---|
| 413 | return true;
|
|---|
| 414 |
|
|---|
| 415 | new_flags = elf_elfheader (ibfd)->e_flags;
|
|---|
| 416 | old_flags = elf_elfheader (obfd)->e_flags;
|
|---|
| 417 | if (!elf_flags_init (obfd)) /* First call, no flags set */
|
|---|
| 418 | {
|
|---|
| 419 | elf_flags_init (obfd) = true;
|
|---|
| 420 | elf_elfheader (obfd)->e_flags = new_flags;
|
|---|
| 421 | }
|
|---|
| 422 |
|
|---|
| 423 | else if (new_flags == old_flags) /* Compatible flags are ok */
|
|---|
| 424 | ;
|
|---|
| 425 |
|
|---|
| 426 | else /* Incompatible flags */
|
|---|
| 427 | {
|
|---|
| 428 | (*_bfd_error_handler)
|
|---|
| 429 | ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",
|
|---|
| 430 | bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
|
|---|
| 431 |
|
|---|
| 432 | bfd_set_error (bfd_error_bad_value);
|
|---|
| 433 | return false;
|
|---|
| 434 | }
|
|---|
| 435 |
|
|---|
| 436 | return true;
|
|---|
| 437 | }
|
|---|
| 438 | |
|---|
| 439 |
|
|---|
| 440 | /* Handle an i370 specific section when reading an object file. This
|
|---|
| 441 | is called when elfcode.h finds a section with an unknown type. */
|
|---|
| 442 | /* XXX hack alert bogus This routine is mostly all junk and almost
|
|---|
| 443 | * certainly does the wrong thing. Its here simply because it does
|
|---|
| 444 | * just enough to allow glibc-2.1 ld.so to compile & link.
|
|---|
| 445 | */
|
|---|
| 446 |
|
|---|
| 447 | static boolean
|
|---|
| 448 | i370_elf_section_from_shdr (abfd, hdr, name)
|
|---|
| 449 | bfd *abfd;
|
|---|
| 450 | Elf32_Internal_Shdr *hdr;
|
|---|
| 451 | char *name;
|
|---|
| 452 | {
|
|---|
| 453 | asection *newsect;
|
|---|
| 454 | flagword flags;
|
|---|
| 455 |
|
|---|
| 456 | if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
|
|---|
| 457 | return false;
|
|---|
| 458 |
|
|---|
| 459 | newsect = hdr->bfd_section;
|
|---|
| 460 | flags = bfd_get_section_flags (abfd, newsect);
|
|---|
| 461 | if (hdr->sh_flags & SHF_EXCLUDE)
|
|---|
| 462 | flags |= SEC_EXCLUDE;
|
|---|
| 463 |
|
|---|
| 464 | if (hdr->sh_type == SHT_ORDERED)
|
|---|
| 465 | flags |= SEC_SORT_ENTRIES;
|
|---|
| 466 |
|
|---|
| 467 | bfd_set_section_flags (abfd, newsect, flags);
|
|---|
| 468 | return true;
|
|---|
| 469 | }
|
|---|
| 470 | |
|---|
| 471 |
|
|---|
| 472 | /* Set up any other section flags and such that may be necessary. */
|
|---|
| 473 | /* XXX hack alert bogus This routine is mostly all junk and almost
|
|---|
| 474 | * certainly does the wrong thing. Its here simply because it does
|
|---|
| 475 | * just enough to allow glibc-2.1 ld.so to compile & link.
|
|---|
| 476 | */
|
|---|
| 477 |
|
|---|
| 478 | static boolean
|
|---|
| 479 | i370_elf_fake_sections (abfd, shdr, asect)
|
|---|
| 480 | bfd *abfd ATTRIBUTE_UNUSED;
|
|---|
| 481 | Elf32_Internal_Shdr *shdr;
|
|---|
| 482 | asection *asect;
|
|---|
| 483 | {
|
|---|
| 484 | if ((asect->flags & SEC_EXCLUDE) != 0)
|
|---|
| 485 | shdr->sh_flags |= SHF_EXCLUDE;
|
|---|
| 486 |
|
|---|
| 487 | if ((asect->flags & SEC_SORT_ENTRIES) != 0)
|
|---|
| 488 | shdr->sh_type = SHT_ORDERED;
|
|---|
| 489 |
|
|---|
| 490 | return true;
|
|---|
| 491 | }
|
|---|
| 492 | |
|---|
| 493 |
|
|---|
| 494 | #if 0
|
|---|
| 495 | /* Create a special linker section */
|
|---|
| 496 | /* XXX hack alert bogus This routine is mostly all junk and almost
|
|---|
| 497 | * certainly does the wrong thing. Its here simply because it does
|
|---|
| 498 | * just enough to allow glibc-2.1 ld.so to compile & link.
|
|---|
| 499 | */
|
|---|
| 500 |
|
|---|
| 501 | static elf_linker_section_t *
|
|---|
| 502 | i370_elf_create_linker_section (abfd, info, which)
|
|---|
| 503 | bfd *abfd;
|
|---|
| 504 | struct bfd_link_info *info;
|
|---|
| 505 | enum elf_linker_section_enum which;
|
|---|
| 506 | {
|
|---|
| 507 | bfd *dynobj = elf_hash_table (info)->dynobj;
|
|---|
| 508 | elf_linker_section_t *lsect;
|
|---|
| 509 |
|
|---|
| 510 | /* Record the first bfd section that needs the special section */
|
|---|
| 511 | if (!dynobj)
|
|---|
| 512 | dynobj = elf_hash_table (info)->dynobj = abfd;
|
|---|
| 513 |
|
|---|
| 514 | /* If this is the first time, create the section */
|
|---|
| 515 | lsect = elf_linker_section (dynobj, which);
|
|---|
| 516 | if (!lsect)
|
|---|
| 517 | {
|
|---|
| 518 | elf_linker_section_t defaults;
|
|---|
| 519 | static elf_linker_section_t zero_section;
|
|---|
| 520 |
|
|---|
| 521 | defaults = zero_section;
|
|---|
| 522 | defaults.which = which;
|
|---|
| 523 | defaults.hole_written_p = false;
|
|---|
| 524 | defaults.alignment = 2;
|
|---|
| 525 |
|
|---|
| 526 | /* Both of these sections are (technically) created by the user
|
|---|
| 527 | putting data in them, so they shouldn't be marked
|
|---|
| 528 | SEC_LINKER_CREATED.
|
|---|
| 529 |
|
|---|
| 530 | The linker creates them so it has somewhere to attach their
|
|---|
| 531 | respective symbols. In fact, if they were empty it would
|
|---|
| 532 | be OK to leave the symbol set to 0 (or any random number), because
|
|---|
| 533 | the appropriate register should never be used. */
|
|---|
| 534 | defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
|
|---|
| 535 | | SEC_IN_MEMORY);
|
|---|
| 536 |
|
|---|
| 537 | switch (which)
|
|---|
| 538 | {
|
|---|
| 539 | default:
|
|---|
| 540 | (*_bfd_error_handler) ("%s: Unknown special linker type %d",
|
|---|
| 541 | bfd_get_filename (abfd),
|
|---|
| 542 | (int)which);
|
|---|
| 543 |
|
|---|
| 544 | bfd_set_error (bfd_error_bad_value);
|
|---|
| 545 | return (elf_linker_section_t *)0;
|
|---|
| 546 |
|
|---|
| 547 | case LINKER_SECTION_SDATA: /* .sdata/.sbss section */
|
|---|
| 548 | defaults.name = ".sdata";
|
|---|
| 549 | defaults.rel_name = ".rela.sdata";
|
|---|
| 550 | defaults.bss_name = ".sbss";
|
|---|
| 551 | defaults.sym_name = "_SDA_BASE_";
|
|---|
| 552 | defaults.sym_offset = 32768;
|
|---|
| 553 | break;
|
|---|
| 554 |
|
|---|
| 555 | case LINKER_SECTION_SDATA2: /* .sdata2/.sbss2 section */
|
|---|
| 556 | defaults.name = ".sdata2";
|
|---|
| 557 | defaults.rel_name = ".rela.sdata2";
|
|---|
| 558 | defaults.bss_name = ".sbss2";
|
|---|
| 559 | defaults.sym_name = "_SDA2_BASE_";
|
|---|
| 560 | defaults.sym_offset = 32768;
|
|---|
| 561 | defaults.flags |= SEC_READONLY;
|
|---|
| 562 | break;
|
|---|
| 563 | }
|
|---|
| 564 |
|
|---|
| 565 | lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
|
|---|
|
|---|