Line 1... |
Line 1... |
/* M32R-specific support for 32-bit ELF.
|
/* M32R-specific support for 32-bit ELF.
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
2006, 2007 Free Software Foundation, Inc.
|
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
Line 1524... |
Line 1524... |
asection *splt;
|
asection *splt;
|
asection *srelplt;
|
asection *srelplt;
|
asection *sdynbss;
|
asection *sdynbss;
|
asection *srelbss;
|
asection *srelbss;
|
|
|
/* Small local sym to section mapping cache. */
|
/* Small local sym cache. */
|
struct sym_sec_cache sym_sec;
|
struct sym_cache sym_cache;
|
};
|
};
|
|
|
/* Traverse an m32r ELF linker hash table. */
|
/* Traverse an m32r ELF linker hash table. */
|
|
|
#define m32r_elf_link_hash_traverse(table, func, info) \
|
#define m32r_elf_link_hash_traverse(table, func, info) \
|
Line 1602... |
Line 1602... |
ret->srelgot = NULL;
|
ret->srelgot = NULL;
|
ret->splt = NULL;
|
ret->splt = NULL;
|
ret->srelplt = NULL;
|
ret->srelplt = NULL;
|
ret->sdynbss = NULL;
|
ret->sdynbss = NULL;
|
ret->srelbss = NULL;
|
ret->srelbss = NULL;
|
ret->sym_sec.abfd = NULL;
|
ret->sym_cache.abfd = NULL;
|
|
|
return &ret->root.root;
|
return &ret->root.root;
|
}
|
}
|
|
|
/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
|
/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
|
Line 1621... |
Line 1621... |
return FALSE;
|
return FALSE;
|
|
|
htab = m32r_elf_hash_table (info);
|
htab = m32r_elf_hash_table (info);
|
htab->sgot = bfd_get_section_by_name (dynobj, ".got");
|
htab->sgot = bfd_get_section_by_name (dynobj, ".got");
|
htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
|
htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
|
if (! htab->sgot || ! htab->sgotplt)
|
htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
|
|
if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
|
abort ();
|
abort ();
|
|
|
htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
|
|
(SEC_ALLOC
|
|
| SEC_LOAD
|
|
| SEC_HAS_CONTENTS
|
|
| SEC_IN_MEMORY
|
|
| SEC_LINKER_CREATED
|
|
| SEC_READONLY));
|
|
if (htab->srelgot == NULL
|
|
|| ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* Create dynamic sections when linking against a dynamic object. */
|
/* Create dynamic sections when linking against a dynamic object. */
|
|
|
Line 2909... |
Line 2899... |
/* When generating a shared object, these relocations
|
/* When generating a shared object, these relocations
|
are copied into the output file to be resolved at run
|
are copied into the output file to be resolved at run
|
time. */
|
time. */
|
if (sreloc == NULL)
|
if (sreloc == NULL)
|
{
|
{
|
const char *name;
|
sreloc = _bfd_elf_get_dynamic_reloc_section
|
|
(input_bfd, input_section, /*rela?*/ TRUE);
|
name = (bfd_elf_string_from_elf_section
|
if (sreloc == NULL)
|
(input_bfd,
|
|
elf_elfheader (input_bfd)->e_shstrndx,
|
|
elf_section_data (input_section)->rel_hdr.sh_name));
|
|
if (name == NULL)
|
|
return FALSE;
|
return FALSE;
|
|
|
BFD_ASSERT (CONST_STRNEQ (name, ".rela")
|
|
&& strcmp (bfd_get_section_name (input_bfd,
|
|
input_section),
|
|
name + 5) == 0);
|
|
|
|
sreloc = bfd_get_section_by_name (dynobj, name);
|
|
BFD_ASSERT (sreloc != NULL);
|
|
}
|
}
|
|
|
skip = FALSE;
|
skip = FALSE;
|
relocate = FALSE;
|
relocate = FALSE;
|
|
|
Line 3948... |
Line 3926... |
/* When creating a shared object, we must copy these
|
/* When creating a shared object, we must copy these
|
relocs into the output file. We create a reloc
|
relocs into the output file. We create a reloc
|
section in dynobj and make room for the reloc. */
|
section in dynobj and make room for the reloc. */
|
if (sreloc == NULL)
|
if (sreloc == NULL)
|
{
|
{
|
const char *name;
|
sreloc = _bfd_elf_make_dynamic_reloc_section
|
|
(sec, dynobj, 2, abfd, /*rela?*/ TRUE);
|
name = (bfd_elf_string_from_elf_section
|
|
(abfd,
|
|
elf_elfheader (abfd)->e_shstrndx,
|
|
elf_section_data (sec)->rel_hdr.sh_name));
|
|
if (name == NULL)
|
|
return FALSE;
|
|
|
|
BFD_ASSERT (CONST_STRNEQ (name, ".rela")
|
|
&& strcmp (bfd_get_section_name (abfd, sec),
|
|
name + 5) == 0);
|
|
|
|
sreloc = bfd_get_section_by_name (dynobj, name);
|
|
if (sreloc == NULL)
|
if (sreloc == NULL)
|
{
|
|
flagword flags;
|
|
|
|
flags = (SEC_HAS_CONTENTS | SEC_READONLY
|
|
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
|
|
if ((sec->flags & SEC_ALLOC) != 0)
|
|
flags |= SEC_ALLOC | SEC_LOAD;
|
|
sreloc = bfd_make_section_with_flags (dynobj,
|
|
name,
|
|
flags);
|
|
if (sreloc == NULL
|
|
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
|
|
return FALSE;
|
return FALSE;
|
}
|
}
|
elf_section_data (sec)->sreloc = sreloc;
|
|
}
|
|
|
|
/* If this is a global symbol, we count the number of
|
/* If this is a global symbol, we count the number of
|
relocations we need for this symbol. */
|
relocations we need for this symbol. */
|
if (h != NULL)
|
if (h != NULL)
|
head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
|
head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
|
else
|
else
|
{
|
{
|
|
/* Track dynamic relocs needed for local syms too. */
|
asection *s;
|
asection *s;
|
void *vpp;
|
void *vpp;
|
|
Elf_Internal_Sym *isym;
|
|
|
/* Track dynamic relocs needed for local syms too. */
|
isym = bfd_sym_from_r_symndx (&htab->sym_cache,
|
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
|
abfd, r_symndx);
|
sec, r_symndx);
|
if (isym == NULL)
|
if (s == NULL)
|
|
return FALSE;
|
return FALSE;
|
|
|
|
s = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
|
if (s == NULL)
|
|
s = sec;
|
|
|
vpp = &elf_section_data (s)->local_dynrel;
|
vpp = &elf_section_data (s)->local_dynrel;
|
head = (struct elf_m32r_dyn_relocs **) vpp;
|
head = (struct elf_m32r_dyn_relocs **) vpp;
|
}
|
}
|
|
|
p = *head;
|
p = *head;
|