summaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c436
1 files changed, 0 insertions, 436 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
deleted file mode 100644
index 829d977aaeb..00000000000
--- a/bfd/elflink.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* ELF linking support for BFD.
- Copyright 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-#define ARCH_SIZE 0
-#include "elf-bfd.h"
-
-boolean
-_bfd_elf_create_got_section (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
-{
- flagword flags;
- register asection *s;
- struct elf_link_hash_entry *h;
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
- int ptralign;
-
- /* This function may be called more than once. */
- if (bfd_get_section_by_name (abfd, ".got") != NULL)
- return true;
-
- switch (bed->s->arch_size)
- {
- case 32: ptralign = 2; break;
- case 64: ptralign = 3; break;
- default: abort();
- }
-
- flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
- | SEC_LINKER_CREATED);
-
- s = bfd_make_section (abfd, ".got");
- if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags)
- || !bfd_set_section_alignment (abfd, s, ptralign))
- return false;
-
- if (bed->want_got_plt)
- {
- s = bfd_make_section (abfd, ".got.plt");
- if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags)
- || !bfd_set_section_alignment (abfd, s, ptralign))
- return false;
- }
-
- /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
- (or .got.plt) section. We don't do this in the linker script
- because we don't want to define the symbol if we are not creating
- a global offset table. */
- h = NULL;
- if (!(_bfd_generic_link_add_one_symbol
- (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
- bed->got_symbol_offset, (const char *) NULL, false,
- bed->collect, (struct bfd_link_hash_entry **) &h)))
- return false;
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
- h->type = STT_OBJECT;
-
- if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
- return false;
-
- elf_hash_table (info)->hgot = h;
-
- /* The first bit of the global offset table is the header. */
- s->_raw_size += bed->got_header_size + bed->got_symbol_offset;
-
- return true;
-}
-
-
-/* Create dynamic sections when linking against a dynamic object. */
-
-boolean
-_bfd_elf_create_dynamic_sections (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
-{
- flagword flags, pltflags;
- register asection *s;
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
- int ptralign;
-
- switch (bed->s->arch_size)
- {
- case 32: ptralign = 2; break;
- case 64: ptralign = 3; break;
- default: abort();
- }
-
- /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
- .rel[a].bss sections. */
-
- flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
- | SEC_LINKER_CREATED);
-
- pltflags = flags;
- pltflags |= SEC_CODE;
- if (bed->plt_not_loaded)
- pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
- if (bed->plt_readonly)
- pltflags |= SEC_READONLY;
-
- s = bfd_make_section (abfd, ".plt");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, pltflags)
- || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
- return false;
-
- if (bed->want_plt_sym)
- {
- /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
- .plt section. */
- struct elf_link_hash_entry *h = NULL;
- if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
- (bfd_vma) 0, (const char *) NULL, false,
- get_elf_backend_data (abfd)->collect,
- (struct bfd_link_hash_entry **) &h)))
- return false;
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
- h->type = STT_OBJECT;
-
- if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
- return false;
- }
-
- s = bfd_make_section (abfd,
- bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
- || ! bfd_set_section_alignment (abfd, s, ptralign))
- return false;
-
- if (! _bfd_elf_create_got_section (abfd, info))
- return false;
-
- /* The .dynbss section is a place to put symbols which are defined
- by dynamic objects, are referenced by regular objects, and are
- not functions. We must allocate space for them in the process
- image and use a R_*_COPY reloc to tell the dynamic linker to
- initialize them at run time. The linker script puts the .dynbss
- section into the .bss section of the final image. */
- s = bfd_make_section (abfd, ".dynbss");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
- return false;
-
- /* The .rel[a].bss section holds copy relocs. This section is not
- normally needed. We need to create it here, though, so that the
- linker will map it to an output section. We can't just create it
- only if we need it, because we will not know whether we need it
- until we have seen all the input files, and the first time the
- main linker code calls BFD after examining all the input files
- (size_dynamic_sections) the input sections have already been
- mapped to the output sections. If the section turns out not to
- be needed, we can discard it later. We will never need this
- section when generating a shared object, since they do not use
- copy relocs. */
- if (! info->shared)
- {
- s = bfd_make_section (abfd,
- (bed->default_use_rela_p
- ? ".rela.bss" : ".rel.bss"));
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
- || ! bfd_set_section_alignment (abfd, s, ptralign))
- return false;
- }
-
- return true;
-}
-
-
-/* Record a new dynamic symbol. We record the dynamic symbols as we
- read the input files, since we need to have a list of all of them
- before we can determine the final sizes of the output sections.
- Note that we may actually call this function even though we are not
- going to output any dynamic symbols; in some cases we know that a
- symbol should be in the dynamic symbol table, but only if there is
- one. */
-
-boolean
-_bfd_elf_link_record_dynamic_symbol (info, h)
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
-{
- if (h->dynindx == -1)
- {
- struct bfd_strtab_hash *dynstr;
- char *p, *alc;
- const char *name;
- boolean copy;
- bfd_size_type indx;
-
- h->dynindx = elf_hash_table (info)->dynsymcount;
- ++elf_hash_table (info)->dynsymcount;
-
- dynstr = elf_hash_table (info)->dynstr;
- if (dynstr == NULL)
- {
- /* Create a strtab to hold the dynamic symbol names. */
- elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
- if (dynstr == NULL)
- return false;
- }
-
- /* We don't put any version information in the dynamic string
- table. */
- name = h->root.root.string;
- p = strchr (name, ELF_VER_CHR);
- if (p == NULL)
- {
- alc = NULL;
- copy = false;
- }
- else
- {
- alc = bfd_malloc (p - name + 1);
- if (alc == NULL)
- return false;
- strncpy (alc, name, p - name);
- alc[p - name] = '\0';
- name = alc;
- copy = true;
- }
-
- indx = _bfd_stringtab_add (dynstr, name, true, copy);
-
- if (alc != NULL)
- free (alc);
-
- if (indx == (bfd_size_type) -1)
- return false;
- h->dynstr_index = indx;
- }
-
- return true;
-}
-
-/* Create a special linker section, or return a pointer to a linker section already created */
-
-elf_linker_section_t *
-_bfd_elf_create_linker_section (abfd, info, which, defaults)
- bfd *abfd;
- struct bfd_link_info *info;
- enum elf_linker_section_enum which;
- elf_linker_section_t *defaults;
-{
- bfd *dynobj = elf_hash_table (info)->dynobj;
- elf_linker_section_t *lsect;
-
- /* Record the first bfd section that needs the special section */
- if (!dynobj)
- dynobj = elf_hash_table (info)->dynobj = abfd;
-
- /* If this is the first time, create the section */
- lsect = elf_linker_section (dynobj, which);
- if (!lsect)
- {
- asection *s;
-
- lsect = (elf_linker_section_t *)
- bfd_alloc (dynobj, sizeof (elf_linker_section_t));
-
- *lsect = *defaults;
- elf_linker_section (dynobj, which) = lsect;
- lsect->which = which;
- lsect->hole_written_p = false;
-
- /* See if the sections already exist */
- lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
- if (!s || (s->flags & defaults->flags) != defaults->flags)
- {
- lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
-
- if (s == NULL)
- return (elf_linker_section_t *)0;
-
- bfd_set_section_flags (dynobj, s, defaults->flags);
- bfd_set_section_alignment (dynobj, s, lsect->alignment);
- }
- else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
- bfd_set_section_alignment (dynobj, s, lsect->alignment);
-
- s->_raw_size = align_power (s->_raw_size, lsect->alignment);
-
- /* Is there a hole we have to provide? If so check whether the segment is
- too big already */
- if (lsect->hole_size)
- {
- lsect->hole_offset = s->_raw_size;
- s->_raw_size += lsect->hole_size;
- if (lsect->hole_offset > lsect->max_hole_offset)
- {
- (*_bfd_error_handler) (_("%s: Section %s is already to large to put hole of %ld bytes in"),
- bfd_get_filename (abfd),
- lsect->name,
- (long)lsect->hole_size);
-
- bfd_set_error (bfd_error_bad_value);
- return (elf_linker_section_t *)0;
- }
- }
-
-#ifdef DEBUG
- fprintf (stderr, "Creating section %s, current size = %ld\n",
- lsect->name, (long)s->_raw_size);
-#endif
-
- if (lsect->sym_name)
- {
- struct elf_link_hash_entry *h = NULL;
-#ifdef DEBUG
- fprintf (stderr, "Adding %s to section %s\n",
- lsect->sym_name,
- lsect->name);
-#endif
- h = (struct elf_link_hash_entry *)
- bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);
-
- if ((h == NULL || h->root.type == bfd_link_hash_undefined)
- && !(_bfd_generic_link_add_one_symbol (info,
- abfd,
- lsect->sym_name,
- BSF_GLOBAL,
- s,
- ((lsect->hole_size)
- ? s->_raw_size - lsect->hole_size + lsect->sym_offset
- : lsect->sym_offset),
- (const char *) NULL,
- false,
- get_elf_backend_data (abfd)->collect,
- (struct bfd_link_hash_entry **) &h)))
- return (elf_linker_section_t *)0;
-
- if ((defaults->which != LINKER_SECTION_SDATA)
- && (defaults->which != LINKER_SECTION_SDATA2))
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
-
- h->type = STT_OBJECT;
- lsect->sym_hash = h;
-
- if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
- return (elf_linker_section_t *)0;
- }
- }
-
-#if 0
- /* This does not make sense. The sections which may exist in the
- object file have nothing to do with the sections we want to
- create. */
-
- /* Find the related sections if they have been created */
- if (lsect->bss_name && !lsect->bss_section)
- lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);
-
- if (lsect->rel_name && !lsect->rel_section)
- lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
-#endif
-
- return lsect;
-}
-
-
-/* Find a linker generated pointer with a given addend and type. */
-
-elf_linker_section_pointers_t *
-_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)
- elf_linker_section_pointers_t *linker_pointers;
- bfd_signed_vma addend;
- elf_linker_section_enum_t which;
-{
- for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
- {
- if (which == linker_pointers->which && addend == linker_pointers->addend)
- return linker_pointers;
- }
-
- return (elf_linker_section_pointers_t *)0;
-}
-
-
-/* Make the .rela section corresponding to the generated linker section. */
-
-boolean
-_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
- bfd *dynobj;
- elf_linker_section_t *lsect;
- int alignment;
-{
- if (lsect->rel_section)
- return true;
-
- lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
- if (lsect->rel_section == NULL)
- {
- lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);
- if (lsect->rel_section == NULL
- || ! bfd_set_section_flags (dynobj,
- lsect->rel_section,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY))
- || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
- return false;
- }
-
- return true;
-}