#define ARM_ELF_ABI_VERSION 0
#define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
-static reloc_howto_type * elf32_arm_reloc_type_lookup
- PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
-static bfd_boolean elf32_arm_nabi_grok_prstatus
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-static bfd_boolean elf32_arm_nabi_grok_psinfo
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
/* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
in that slot. */
};
static reloc_howto_type *
-elf32_arm_reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
unsigned int i;
for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
/* Support for core dump NOTE sections */
static bfd_boolean
-elf32_arm_nabi_grok_prstatus (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
size_t size;
}
static bfd_boolean
-elf32_arm_nabi_grok_psinfo (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
switch (note->descsz)
{
/* These are the only relocation types we care about. */
if ( r_type != R_ARM_PC24
&& r_type != R_ARM_PLT32
-#ifndef OLD_ARM_ABI
&& r_type != R_ARM_CALL
&& r_type != R_ARM_JUMP24
-#endif
&& r_type != R_ARM_THM_CALL)
continue;
{
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
/* This one is a call from arm code. We need to look up
the target of the call. If it is a thumb target, we
insert glue. */
#endif
-#ifndef OLD_ARM_ABI
/* Set target relocation values needed during linking. */
void
globals->fix_v4bx = fix_v4bx;
globals->use_blx |= use_blx;
}
-#endif
/* The thumb form of a long branch is a bit finicky, because the offset
encoding is split over two fields, each in it's own instruction. They
return TRUE;
}
-
-#ifndef OLD_ARM_ABI
/* Some relocations map to different relocations depending on the
target. Return the real relocation. */
static int
return r_type;
}
}
-#endif /* OLD_ARM_ABI */
-
/* Return the base VMA address which should be subtracted from real addresses
when resolving @dtpoff relocation.
globals = elf32_arm_hash_table (info);
-#ifndef OLD_ARM_ABI
/* Some relocation type map to different relocations depending on the
target. We pick the right one here. */
r_type = arm_real_reloc_type (globals, r_type);
if (r_type != howto->type)
howto = elf32_arm_howto_from_type (r_type);
-#endif /* OLD_ARM_ABI */
/* If the start address has been set, then set the EF_ARM_HASENTRY
flag. Setting this more than once is redundant, but the cost is
case R_ARM_PC24:
case R_ARM_ABS32:
case R_ARM_REL32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_XPC25:
case R_ARM_PREL31:
-#endif
case R_ARM_PLT32:
/* r_symndx will be zero only for relocs against symbols
from removed linkonce sections, or sections discarded by
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
&& r_type != R_ARM_PC24
-#ifndef OLD_ARM_ABI
&& r_type != R_ARM_CALL
&& r_type != R_ARM_JUMP24
&& r_type != R_ARM_PREL31
-#endif
&& r_type != R_ARM_PLT32)
{
Elf_Internal_Rela outrel;
}
else switch (r_type)
{
-#ifndef OLD_ARM_ABI
case R_ARM_XPC25: /* Arm BLX instruction. */
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
case R_ARM_PC24: /* Arm B/BL instruction */
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
if (r_type == R_ARM_XPC25)
{
/* Check for Arm calling Arm function. */
h ? h->root.root.string : "(local)");
}
else
-#endif
{
/* Check for Arm calling Thumb function. */
if (sym_flags == STT_ARM_TFUNC)
return bfd_reloc_overflow;
}
-#ifndef OLD_ARM_ABI
/* If necessary set the H bit in the BLX instruction. */
if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
value = (signed_addend & howto->dst_mask)
| (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))
| (1 << 24);
else
-#endif
value = (signed_addend & howto->dst_mask)
| (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
break;
value += addend;
break;
-#ifndef OLD_ARM_ABI
case R_ARM_PREL31:
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
if (sym_flags == STT_ARM_TFUNC)
value |= 1;
break;
-#endif
}
bfd_put_32 (input_bfd, value, hit_data);
bfd_put_16 (input_bfd, value, hit_data);
return bfd_reloc_ok;
-#ifndef OLD_ARM_ABI
case R_ARM_THM_XPC22:
-#endif
case R_ARM_THM_CALL:
/* Thumb BL (branch long instruction). */
{
addend = (upper << 12) | (lower << 1);
signed_addend = addend;
}
-#ifndef OLD_ARM_ABI
+
if (r_type == R_ARM_THM_XPC22)
{
/* Check for Thumb to Thumb call. */
h ? h->root.root.string : "(local)");
}
else
-#endif
{
/* If it is not a call to Thumb, assume call to Arm.
If it is a call relative to a section name, then it is not a
if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
overflow = TRUE;
-#ifndef OLD_ARM_ABI
if ((r_type == R_ARM_THM_XPC22
&& ((lower_insn & 0x1800) == 0x0800))
|| thumb_plt_call)
which specifies that bit 1 of the target address will come from bit
1 of the base address. */
relocation = (relocation + 2) & ~ 3;
-#endif
+
/* Put RELOCATION back into the insn. */
upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
return bfd_reloc_ok;
}
-#ifndef OLD_ARM_ABI
case R_ARM_ALU_PCREL7_0:
case R_ARM_ALU_PCREL15_8:
case R_ARM_ALU_PCREL23_15:
bfd_put_32 (input_bfd, value, hit_data);
}
return bfd_reloc_ok;
-#endif
case R_ARM_GNU_VTINHERIT:
case R_ARM_GNU_VTENTRY:
(bfd_vma) 0);
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
/* Relocation is to the entry for this symbol in the
global offset table. */
if (sgot == NULL)
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
addend <<= howto->size;
addend += increment;
}
r_type = ELF32_R_TYPE (rel->r_info);
-#ifndef OLD_ARM_ABI
r_type = arm_real_reloc_type (globals, r_type);
-#endif
switch (r_type)
{
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
if (h != NULL)
case R_ARM_REL32:
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PREL31:
-#endif
case R_ARM_THM_CALL:
/* Should the interworking branches be here also? */
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
-#ifndef OLD_ARM_ABI
r_type = arm_real_reloc_type (htab, r_type);
-#endif
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
eh = (struct elf32_arm_link_hash_entry *) h;
switch (r_type)
{
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
/* This symbol requires a global offset table entry. */
case R_ARM_REL32:
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PREL31:
-#endif
case R_ARM_THM_CALL:
/* Should the interworking branches be listed here? */
if (h != NULL)
sure yet, because something later might force the
symbol local. */
if (r_type == R_ARM_PC24
-#ifndef OLD_ARM_ABI
|| r_type == R_ARM_CALL
|| r_type == R_ARM_JUMP24
|| r_type == R_ARM_PREL31
-#endif
|| r_type == R_ARM_PLT32
|| r_type == R_ARM_THM_CALL)
h->needs_plt = 1;
return TRUE;
}
+static bfd_boolean
+elf32_arm_find_inliner_info (bfd * abfd,
+ const char ** filename_ptr,
+ const char ** functionname_ptr,
+ unsigned int * line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char * name;
- bfd_boolean strip;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
of the dynobj section names depend upon the input files. */
name = bfd_get_section_name (dynobj, s);
- strip = FALSE;
-
if (strcmp (name, ".plt") == 0)
{
- if (s->size == 0)
- {
- /* Strip this section if we don't need it; see the
- comment below. */
- strip = TRUE;
- }
- else
- {
- /* Remember whether there is a PLT. */
- plt = TRUE;
- }
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
}
else if (strncmp (name, ".rel", 4) == 0)
{
- if (s->size == 0)
- {
- /* If we don't need this section, strip it from the
- output file. This is mostly to handle .rel.bss and
- .rel.plt. We must create both sections in
- create_dynamic_sections, because they must be created
- before the linker maps input sections to output
- sections. The linker does that before
- adjust_dynamic_symbol is called, and it is that
- function which decides whether anything needs to go
- into these sections. */
- strip = TRUE;
- }
- else
+ if (s->size != 0)
{
/* Remember whether there are any reloc sections other
than .rel.plt. */
s->reloc_count = 0;
}
}
- else if (strncmp (name, ".got", 4) != 0)
+ else if (strncmp (name, ".got", 4) != 0
+ && strcmp (name, ".dynbss") != 0)
{
/* It's not one of our sections, so don't allocate space. */
continue;
}
- if (strip)
+ if (s->size == 0)
{
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rel.bss and
+ .rel.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
s->flags |= SEC_EXCLUDE;
continue;
}
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
/* Allocate memory for the section contents. */
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
- if (s->contents == NULL && s->size != 0)
+ if (s->contents == NULL)
return FALSE;
}
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (!info->shared)
+ if (info->executable)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
{
if (!add_dynamic_entry (DT_TEXTREL, 0))
return FALSE;
- info->flags |= DF_TEXTREL;
}
}
-#undef add_synamic_entry
+#undef add_dynamic_entry
return TRUE;
}
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
+#define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info
#define bfd_elf32_new_section_hook elf32_arm_new_section_hook
#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
return ret;
}
-static struct bfd_elf_special_section const
- symbian_special_sections_d[]=
+static const struct bfd_elf_special_section
+elf32_arm_symbian_special_sections[] =
{
/* In a BPABI executable, the dynamic linking sections do not go in
the loadable read-only segment. The post-linker may wish to
{ ".dynamic", 8, 0, SHT_DYNAMIC, 0 },
{ ".dynstr", 7, 0, SHT_STRTAB, 0 },
{ ".dynsym", 7, 0, SHT_DYNSYM, 0 },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- symbian_special_sections_g[]=
-{
- /* In a BPABI executable, the dynamic linking sections do not go in
- the loadable read-only segment. The post-linker may wish to
- refer to these sections, but they are not part of the final
- program image. */
{ ".got", 4, 0, SHT_PROGBITS, 0 },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- symbian_special_sections_h[]=
-{
- /* In a BPABI executable, the dynamic linking sections do not go in
- the loadable read-only segment. The post-linker may wish to
- refer to these sections, but they are not part of the final
- program image. */
{ ".hash", 5, 0, SHT_HASH, 0 },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- symbian_special_sections_i[]=
-{
/* These sections do not need to be writable as the SymbianOS
postlinker will arrange things so that no dynamic relocation is
required. */
{ ".init_array", 11, 0, SHT_INIT_ARRAY, SHF_ALLOC },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- symbian_special_sections_f[]=
-{
- /* These sections do not need to be writable as the SymbianOS
- postlinker will arrange things so that no dynamic relocation is
- required. */
{ ".fini_array", 11, 0, SHT_FINI_ARRAY, SHF_ALLOC },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- symbian_special_sections_p[]=
-{
- /* These sections do not need to be writable as the SymbianOS
- postlinker will arrange things so that no dynamic relocation is
- required. */
{ ".preinit_array", 14, 0, SHT_PREINIT_ARRAY, SHF_ALLOC },
{ NULL, 0, 0, 0, 0 }
};
-static struct bfd_elf_special_section const *
- elf32_arm_symbian_special_sections[27]=
-{
- NULL, /* 'a' */
- NULL, /* 'b' */
- NULL, /* 'c' */
- symbian_special_sections_d, /* 'd' */
- NULL, /* 'e' */
- symbian_special_sections_f, /* 'f' */
- symbian_special_sections_g, /* 'g' */
- symbian_special_sections_h, /* 'h' */
- symbian_special_sections_i, /* 'i' */
- NULL, /* 'j' */
- NULL, /* 'k' */
- NULL, /* 'l' */
- NULL, /* 'm' */
- NULL, /* 'n' */
- NULL, /* 'o' */
- symbian_special_sections_p, /* 'p' */
- NULL, /* 'q' */
- NULL, /* 'r' */
- NULL, /* 's' */
- NULL, /* 't' */
- NULL, /* 'u' */
- NULL, /* 'v' */
- NULL, /* 'w' */
- NULL, /* 'x' */
- NULL, /* 'y' */
- NULL, /* 'z' */
- NULL /* other */
-};
-
static void
elf32_arm_symbian_begin_write_processing (bfd *abfd,
struct bfd_link_info *link_info