aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfcode.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-12-15 19:59:18 +0000
committerIan Lance Taylor <ian@airs.com>1996-12-15 19:59:18 +0000
commite35765a9a2eaff0df62757f3e6480c8ba5ab8ee8 (patch)
tree53ee31421fdd884963cf43049adaa55a2b828ba0 /bfd/elfcode.h
parentd31b72a3144f839485f928bc2ef9dc6b51e6c87e (diff)
downloadgdb-e35765a9a2eaff0df62757f3e6480c8ba5ab8ee8.zip
gdb-e35765a9a2eaff0df62757f3e6480c8ba5ab8ee8.tar.gz
gdb-e35765a9a2eaff0df62757f3e6480c8ba5ab8ee8.tar.bz2
* elfcode.h (elf_slurp_reloc_table): Add dynamic parameter.
* elf.c (_bfd_elf_canonicalize_reloc): Pass new argument to slurp_reloc_table. (_bfd_elf_get_dynamic_reloc_upper_bound): New function. (_bfd_elf_canonicalize_dynamic_reloc): New function. * elf-bfd.h (struct elf_size_info): Update declaration of slurp_reloc_table. (_bfd_elf_get_dynamic_reloc_upper_bound): Declare. (_bfd_elf_canonicalize_dynamic_reloc): Declare. * elfxx-target.h: Use new dynamic reloc routines by default. * elf64-mips.c (mips_elf64_slurp_reloc_table): Add dynamic parameter.
Diffstat (limited to 'bfd/elfcode.h')
-rw-r--r--bfd/elfcode.h180
1 files changed, 52 insertions, 128 deletions
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 405e79f..87e02f2 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -154,21 +154,13 @@ static void elf_swap_shdr_out
#define elf_stringtab_init _bfd_elf_stringtab_init
-extern struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void));
#define section_from_elf_index bfd_section_from_elf_index
-extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *,
- int));
-static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **));
+static boolean elf_slurp_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
- int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *,
- struct symbol_cache_entry **));
-
-static boolean validate_reloc PARAMS ((bfd *, arelent *));
static void write_relocs PARAMS ((bfd *, asection *, PTR));
- boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex));
-
#ifdef DEBUG
static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));
static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *));
@@ -594,6 +586,15 @@ elf_object_p (abfd)
goto got_no_match;
elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
elf_elfsections (abfd)[shindex] = i_shdrp + shindex;
+
+ /* If the section is loaded, but not page aligned, clear
+ D_PAGED. */
+ if ((i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
+ && i_shdrp[shindex].sh_type != SHT_NOBITS
+ && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
+ % ebd->maxpagesize)
+ != 0))
+ abfd->flags &= ~D_PAGED;
}
if (i_ehdrp->e_shstrndx)
{
@@ -676,104 +677,6 @@ got_no_match:
/* ELF .o/exec file writing */
-/* Try to convert a non-ELF reloc into an ELF one. */
-
-static boolean
-validate_reloc (abfd, areloc)
- bfd *abfd;
- arelent *areloc;
-{
- /* Check whether we really have an ELF howto. */
-
- if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
- {
- bfd_reloc_code_real_type code;
- reloc_howto_type *howto;
-
- /* Alien reloc: Try to determine its type to replace it with an
- equivalent ELF reloc. */
-
- if (areloc->howto->pc_relative)
- {
- switch (areloc->howto->bitsize)
- {
- case 8:
- code = BFD_RELOC_8_PCREL;
- break;
- case 12:
- code = BFD_RELOC_12_PCREL;
- break;
- case 16:
- code = BFD_RELOC_16_PCREL;
- break;
- case 24:
- code = BFD_RELOC_24_PCREL;
- break;
- case 32:
- code = BFD_RELOC_32_PCREL;
- break;
- case 64:
- code = BFD_RELOC_64_PCREL;
- break;
- default:
- goto fail;
- }
-
- howto = bfd_reloc_type_lookup (abfd, code);
-
- if (areloc->howto->pcrel_offset != howto->pcrel_offset)
- {
- if (howto->pcrel_offset)
- areloc->addend += areloc->address;
- else
- areloc->addend -= areloc->address; /* addend is unsigned!! */
- }
- }
- else
- {
- switch (areloc->howto->bitsize)
- {
- case 8:
- code = BFD_RELOC_8;
- break;
- case 14:
- code = BFD_RELOC_14;
- break;
- case 16:
- code = BFD_RELOC_16;
- break;
- case 26:
- code = BFD_RELOC_26;
- break;
- case 32:
- code = BFD_RELOC_32;
- break;
- case 64:
- code = BFD_RELOC_64;
- break;
- default:
- goto fail;
- }
-
- howto = bfd_reloc_type_lookup (abfd, code);
- }
-
- if (howto)
- areloc->howto = howto;
- else
- goto fail;
- }
-
- return true;
-
- fail:
- (*_bfd_error_handler)
- ("%s: unsupported relocation type %s",
- bfd_get_filename (abfd), areloc->howto->name);
- bfd_set_error (bfd_error_bad_value);
- return false;
-}
-
/* Write out the relocs. */
static void
@@ -842,6 +745,8 @@ write_relocs (abfd, sec, data)
sym = *ptr->sym_ptr_ptr;
if (sym == last_sym)
n = last_sym_idx;
+ else if (bfd_is_abs_section (sym->section) && sym->value == 0)
+ n = STN_UNDEF;
else
{
last_sym = sym;
@@ -854,8 +759,9 @@ write_relocs (abfd, sec, data)
last_sym_idx = n;
}
- if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
- && ! validate_reloc (abfd, ptr))
+ if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
+ && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
{
*failedp = true;
return;
@@ -907,7 +813,7 @@ write_relocs (abfd, sec, data)
}
if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
- && ! validate_reloc (abfd, ptr))
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
{
*failedp = true;
return;
@@ -1177,13 +1083,16 @@ error_return:
/* Read in and swap the external relocs. */
static boolean
-elf_slurp_reloc_table (abfd, asect, symbols)
+elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
bfd *abfd;
asection *asect;
asymbol **symbols;
+ boolean dynamic;
{
struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
struct bfd_elf_section_data * const d = elf_section_data (asect);
+ Elf_Internal_Shdr *rel_hdr;
+ bfd_size_type reloc_count;
PTR allocated = NULL;
bfd_byte *native_relocs;
arelent *relents;
@@ -1191,37 +1100,51 @@ elf_slurp_reloc_table (abfd, asect, symbols)
unsigned int i;
int entsize;
- if (asect->relocation != NULL
- || (asect->flags & SEC_RELOC) == 0
- || asect->reloc_count == 0)
+ if (asect->relocation != NULL)
return true;
- BFD_ASSERT (asect->rel_filepos == d->rel_hdr.sh_offset
- && (asect->reloc_count
- == d->rel_hdr.sh_size / d->rel_hdr.sh_entsize));
+ if (! dynamic)
+ {
+ if ((asect->flags & SEC_RELOC) == 0
+ || asect->reloc_count == 0)
+ return true;
+
+ rel_hdr = &d->rel_hdr;
+ reloc_count = asect->reloc_count;
+
+ BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+ && reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize);
+ }
+ else
+ {
+ if (asect->_raw_size == 0)
+ return true;
+
+ rel_hdr = &d->this_hdr;
+ reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+ }
- allocated = (PTR) bfd_malloc ((size_t) d->rel_hdr.sh_size);
+ allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
if (allocated == NULL)
goto error_return;
- if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0
- || (bfd_read (allocated, 1, d->rel_hdr.sh_size, abfd)
- != d->rel_hdr.sh_size))
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd)
+ != rel_hdr->sh_size))
goto error_return;
native_relocs = (bfd_byte *) allocated;
- relents = ((arelent *)
- bfd_alloc (abfd, asect->reloc_count * sizeof (arelent)));
+ relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent));
if (relents == NULL)
goto error_return;
- entsize = d->rel_hdr.sh_entsize;
+ entsize = rel_hdr->sh_entsize;
BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
|| entsize == sizeof (Elf_External_Rela));
for (i = 0, relent = relents;
- i < asect->reloc_count;
+ i < reloc_count;
i++, relent++, native_relocs += entsize)
{
Elf_Internal_Rela rela;
@@ -1239,8 +1162,9 @@ elf_slurp_reloc_table (abfd, asect, symbols)
/* The address of an ELF reloc is section relative for an object
file, and absolute for an executable file or shared library.
- The address of a BFD reloc is always section relative. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ The address of a normal BFD reloc is always section relative,
+ and the address of a dynamic reloc is absolute.. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
relent->address = rela.r_offset;
else
relent->address = rela.r_offset - asect->vma;