#define LA25_LUI(VAL) (0x3c190000 | (VAL)) /* lui t9,VAL */
#define LA25_J(VAL) (0x08000000 | (((VAL) >> 2) & 0x3ffffff)) /* j VAL */
#define LA25_ADDIU(VAL) (0x27390000 | (VAL)) /* addiu t9,t9,VAL */
-#define LA25_LUI_MICROMIPS_1(VAL) (0x41b9) /* lui t9,VAL */
-#define LA25_LUI_MICROMIPS_2(VAL) (VAL)
-#define LA25_J_MICROMIPS_1(VAL) (0xd400 | (((VAL) >> 17) & 0x3ff)) /* j VAL */
-#define LA25_J_MICROMIPS_2(VAL) ((VAL) >> 1)
-#define LA25_ADDIU_MICROMIPS_1(VAL) (0x3339) /* addiu t9,t9,VAL */
-#define LA25_ADDIU_MICROMIPS_2(VAL) (VAL)
+#define LA25_LUI_MICROMIPS(VAL) \
+ (0x41b90000 | (VAL)) /* lui t9,VAL */
+#define LA25_J_MICROMIPS(VAL) \
+ (0xd4000000 | (((VAL) >> 1) & 0x3ffffff)) /* j VAL */
+#define LA25_ADDIU_MICROMIPS(VAL) \
+ (0x33390000 | (VAL)) /* addiu t9,t9,VAL */
/* This structure is passed to mips_elf_sort_hash_table_f when sorting
the dynamic symbols. */
0x24180000 /* li t8, <pltindex> */
};
\f
+/* microMIPS 32-bit opcode helper installer. */
+
+static void
+bfd_put_micromips_32 (const bfd *abfd, bfd_vma opcode, bfd_byte *ptr)
+{
+ bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+ bfd_put_16 (abfd, opcode & 0xffff, ptr + 2);
+}
+
+/* microMIPS 32-bit opcode helper retriever. */
+
+static bfd_vma
+bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
+{
+ return (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+}
+\f
/* Look up an entry in a MIPS ELF linker hash table. */
#define mips_elf_link_hash_lookup(table, string, create, copy, follow) \
dname = MIPS_ELF_REL_DYN_NAME (info);
dynobj = elf_hash_table (info)->dynobj;
- sreloc = bfd_get_section_by_name (dynobj, dname);
+ sreloc = bfd_get_linker_section (dynobj, dname);
if (sreloc == NULL && create_p)
{
- sreloc = bfd_make_section_with_flags (dynobj, dname,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (sreloc == NULL
|| ! bfd_set_section_alignment (dynobj, sreloc,
MIPS_ELF_LOG_FILE_ALIGN (dynobj)))
flagword flags;
register asection *s;
- if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
+ if (bfd_get_linker_section (abfd, ".compact_rel") == NULL)
{
flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED
| SEC_READONLY);
- s = bfd_make_section_with_flags (abfd, ".compact_rel", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".compact_rel", flags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
MIPS_ELF_LOG_FILE_ALIGN (abfd)))
/* We have to use an alignment of 2**4 here because this is hardcoded
in the function stub generation and in the linker script. */
- s = bfd_make_section_with_flags (abfd, ".got", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, 4))
return FALSE;
|= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
/* We also need a .got.plt section when generating PLTs. */
- s = bfd_make_section_with_flags (abfd, ".got.plt",
- SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt",
+ SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
if (s == NULL)
return FALSE;
htab->sgotplt = s;
&& (target_is_16_bit_code_p
|| target_is_micromips_code_p))));
- local_p = h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->root);
+ local_p = (h == NULL
+ || (h->got_only_for_calls
+ ? SYMBOL_CALLS_LOCAL (info, &h->root)
+ : SYMBOL_REFERENCES_LOCAL (info, &h->root)));
gp0 = _bfd_get_gp_value (input_bfd);
gp = _bfd_get_gp_value (abfd);
jalx_opcode = 0x1d;
}
- /* If the opcode is not JAL or JALX, there's a problem. */
+ /* If the opcode is not JAL or JALX, there's a problem. We cannot
+ convert J or JALS to JALX. */
if (!ok)
{
(*_bfd_error_handler)
- (_("%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."),
+ (_("%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with interlinking enabled."),
input_bfd,
input_section,
(unsigned long) relocation->r_offset);
/* On IRIX5, make an entry of compact relocation info. */
if (IRIX_COMPAT (output_bfd) == ict_irix5)
{
- asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
+ asection *scpt = bfd_get_linker_section (dynobj, ".compact_rel");
bfd_byte *cr;
if (scpt)
EABI doesn't. */
if (!htab->is_vxworks)
{
- s = bfd_get_section_by_name (abfd, ".dynamic");
+ s = bfd_get_linker_section (abfd, ".dynamic");
if (s != NULL)
{
if (! bfd_set_section_flags (abfd, s, flags))
return FALSE;
/* Create .stub section. */
- s = bfd_make_section_with_flags (abfd,
- MIPS_ELF_STUB_SECTION_NAME (abfd),
- flags | SEC_CODE);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ MIPS_ELF_STUB_SECTION_NAME (abfd),
+ flags | SEC_CODE);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
MIPS_ELF_LOG_FILE_ALIGN (abfd)))
if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
&& !info->shared
- && bfd_get_section_by_name (abfd, ".rld_map") == NULL)
+ && bfd_get_linker_section (abfd, ".rld_map") == NULL)
{
- s = bfd_make_section_with_flags (abfd, ".rld_map",
- flags &~ (flagword) SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rld_map",
+ flags &~ (flagword) SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s,
MIPS_ELF_LOG_FILE_ALIGN (abfd)))
}
/* Change alignments of some sections. */
- s = bfd_get_section_by_name (abfd, ".hash");
+ s = bfd_get_linker_section (abfd, ".hash");
if (s != NULL)
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
- s = bfd_get_section_by_name (abfd, ".dynsym");
+ s = bfd_get_linker_section (abfd, ".dynsym");
if (s != NULL)
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
- s = bfd_get_section_by_name (abfd, ".dynstr");
+ s = bfd_get_linker_section (abfd, ".dynstr");
if (s != NULL)
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+ /* ??? */
s = bfd_get_section_by_name (abfd, ".reginfo");
if (s != NULL)
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
- s = bfd_get_section_by_name (abfd, ".dynamic");
+ s = bfd_get_linker_section (abfd, ".dynamic");
if (s != NULL)
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
}
and is filled in by the rtld to contain a pointer to
the _r_debug structure. Its symbol value will be set in
_bfd_mips_elf_finish_dynamic_symbol. */
- s = bfd_get_section_by_name (abfd, ".rld_map");
+ s = bfd_get_linker_section (abfd, ".rld_map");
BFD_ASSERT (s != NULL);
name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
return FALSE;
/* Cache the sections created above. */
- htab->splt = bfd_get_section_by_name (abfd, ".plt");
- htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
+ htab->splt = bfd_get_linker_section (abfd, ".plt");
+ htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss");
if (htab->is_vxworks)
{
- htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
- htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
+ htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss");
+ htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt");
}
else
- htab->srelplt = bfd_get_section_by_name (abfd, ".rel.plt");
+ htab->srelplt = bfd_get_linker_section (abfd, ".rel.plt");
if (!htab->sdynbss
|| (htab->is_vxworks && !htab->srelbss && !info->shared)
|| !htab->srelplt
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size
= strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
}
/* Allocate space for global sym dynamic relocs. */
- elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
mips_elf_estimate_stub_size (output_bfd, info);
/* SGI object has the equivalence of DT_DEBUG in the
DT_MIPS_RLD_MAP entry. This must come first because glibc
- only fills in DT_MIPS_RLD_MAP (not DT_DEBUG) and GDB only
- looks at the first one it sees. */
+ only fills in DT_MIPS_RLD_MAP (not DT_DEBUG) and some tools
+ may only look at the first one they see. */
if (!info->shared
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
return FALSE;
if (IRIX_COMPAT (dynobj) == ict_irix6
&& (bfd_get_section_by_name
- (dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
+ (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
return FALSE;
}
loc += offset;
if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
{
- bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
- loc);
- bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
- loc + 2);
- bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
- loc + 4);
- bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
- loc + 6);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_LUI_MICROMIPS (target_high),
+ loc);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_ADDIU_MICROMIPS (target_low),
+ loc + 4);
}
else
{
loc += offset;
if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
{
- bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
- loc);
- bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
- loc + 2);
- bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_1 (target), loc + 4);
- bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_2 (target), loc + 6);
- bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
- loc + 8);
- bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
- loc + 10);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_LUI_MICROMIPS (target_high), loc);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_J_MICROMIPS (target), loc + 4);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_ADDIU_MICROMIPS (target_low), loc + 8);
bfd_put_32 (hti->output_bfd, 0, loc + 12);
}
else
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
name = h->root.root.string;
- if (strcmp (name, "_DYNAMIC") == 0
+ if (h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
else if (strcmp (name, "_DYNAMIC_LINK") == 0
dynobj = elf_hash_table (info)->dynobj;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
sgot = htab->sgot;
gg = htab->got_info;
if (SGI_COMPAT (output_bfd))
{
/* Write .compact_rel section out. */
- s = bfd_get_section_by_name (dynobj, ".compact_rel");
+ s = bfd_get_linker_section (dynobj, ".compact_rel");
if (s != NULL)
{
cpt.id1 = 1;
if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
section, symbols, offset,
filename_ptr, functionname_ptr,
- line_ptr, ABI_64_P (abfd) ? 8 : 0,
+ line_ptr, NULL, ABI_64_P (abfd) ? 8 : 0,
&elf_tdata (abfd)->dwarf2_find_line_info))
return TRUE;
unsigned long opcode;
int bdsize;
- opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+ opcode = bfd_get_micromips_32 (abfd, ptr);
if (find_match (opcode, ds_insns_32_bd32) >= 0)
/* 32-bit branch/jump with a 32-bit delay slot. */
bdsize = 4;
{
unsigned long opcode;
- opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+ opcode = bfd_get_micromips_32 (abfd, ptr);
if (MATCH (opcode, j_insn_32)
/* J */
|| MATCH (opcode, bc_insn_32)
const Elf_Internal_Rela *irel;
unsigned long opcode;
- opcode = bfd_get_16 (abfd, ptr);
- opcode <<= 16;
- opcode |= bfd_get_16 (abfd, ptr + 2);
+ opcode = bfd_get_micromips_32 (abfd, ptr);
if (find_match (opcode, bzc_insns_32) < 0)
return FALSE;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf_link_read_relocs
- (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (irel->r_offset + 4 > sec->size)
continue;
- opcode = bfd_get_16 (abfd, ptr ) << 16;
- opcode |= bfd_get_16 (abfd, ptr + 2);
+ opcode = bfd_get_micromips_32 (abfd, ptr);
/* This is the pc-relative distance from the instruction the
relocation is applied to, to the symbol referred. */
continue;
}
- nextopc = bfd_get_16 (abfd, contents + irel[1].r_offset ) << 16;
- nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2);
+ nextopc = bfd_get_micromips_32 (abfd, contents + irel[1].r_offset);
/* Give up unless the same register is used with both
relocations. */
nextopc = (addiupc_insn.match
| ADDIUPC_REG_FIELD (OP32_TREG (nextopc)));
- bfd_put_16 (abfd, (nextopc >> 16) & 0xffff,
- contents + irel[1].r_offset);
- bfd_put_16 (abfd, nextopc & 0xffff,
- contents + irel[1].r_offset + 2);
+ bfd_put_micromips_32 (abfd, nextopc,
+ contents + irel[1].r_offset);
}
/* Can't do anything, give up, sigh... */
| BZC32_REG_FIELD (reg)
| (opcode & 0xffff)); /* Addend value. */
- bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
- bfd_put_16 (abfd, opcode & 0xffff, ptr + 2);
+ bfd_put_micromips_32 (abfd, opcode, ptr);
/* Delete the 16-bit delay slot NOP: two bytes from
irel->offset + 4. */
/* Fix the relocation's type. */
irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC10_S1);
- /* Replace the the 32-bit opcode with a 16-bit opcode. */
+ /* Replace the 32-bit opcode with a 16-bit opcode. */
bfd_put_16 (abfd,
(b_insn_16.match
| (opcode & 0x3ff)), /* Addend value. */
/* Fix the relocation's type. */
irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC7_S1);
- /* Replace the the 32-bit opcode with a 16-bit opcode. */
+ /* Replace the 32-bit opcode with a 16-bit opcode. */
bfd_put_16 (abfd,
(bz_insns_16[fndopc].match
| BZ16_REG_FIELD (reg)
unsigned long n32opc;
bfd_boolean relaxed = FALSE;
- n32opc = bfd_get_16 (abfd, ptr + 4) << 16;
- n32opc |= bfd_get_16 (abfd, ptr + 6);
+ n32opc = bfd_get_micromips_32 (abfd, ptr + 4);
if (MATCH (n32opc, nop_insn_32))
{
{
/* JAL with 32-bit delay slot that is changed to a JALS
with 16-bit delay slot. */
- bfd_put_16 (abfd, (jal_insn_32_bd16.match >> 16) & 0xffff,
- ptr);
- bfd_put_16 (abfd, jal_insn_32_bd16.match & 0xffff,
- ptr + 2);
+ bfd_put_micromips_32 (abfd, jal_insn_32_bd16.match, ptr);
/* Delete 2 bytes from irel->r_offset + 6. */
delcnt = 2;
if (SGI_COMPAT (abfd) && info->shared)
{
/* Create .rtproc section. */
- rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
+ rtproc_sec = bfd_get_linker_section (abfd, ".rtproc");
if (rtproc_sec == NULL)
{
flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
- rtproc_sec = bfd_make_section_with_flags (abfd,
- ".rtproc",
- flags);
+ rtproc_sec = bfd_make_section_anyway_with_flags (abfd,
+ ".rtproc",
+ flags);
if (rtproc_sec == NULL
|| ! bfd_set_section_alignment (abfd, rtproc_sec, 4))
return FALSE;