2000-07-17 Koundinya K <kk@ddeorg.soft.net>
Enable the support for Traditional MIPS. * elf32-mips.c (IRIX_COMPAT): Recognize bfd_elf32_tradbigmips_vecand return ict_none appropriately for traditional mips targets. (STUB_LW): Change 0x8f998000 to 0x8f998010 for traditional mips. (STUB_MOVE): Conditionalize for traditonal mips. (STUB_LI16): Likewise. (_bfd_mips_elf_modify_segment_map): Conditionalize to avoid making room for RTPROC header. (_bfd_mips_elf_modify_segment_map): For a normal mips executable set the permission for the PT_DYNAMIC as read, write and execute. (mips_elf_calculate_relocation): Check for the symbol _DYNAMIC_LINKING for traditonal mips. (_bfd_mips_elf_create_dynamic_sections): Add the symbol _DYNAMIC_LINKING for traditonal mips. (_bfd_mips_elf_create_dynamic_sections): Add the symbol __RLD_MAP in case of traditonal mips. (_bfd_mips_elf_adjust_dynamic_symbol): Create a stub only if a PLT entry is required. For a function if PLT is not required then set the corresponding hash table entry to 0. (_bfd_mips_elf_size_dynamic_sections): Add DT_DEBUG entry for traditonal mips. (_bfd_mips_elf_finish_dynamic_symbol): for a undefined symbol in a shared object set the value to 0. (_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol _DYNAMIC_LINKING for traditonal mips. (_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol __RLD_MAP for traditonal mips.
This commit is contained in:
parent
0ad8cf4c25
commit
f7cb7d68c2
2 changed files with 250 additions and 150 deletions
|
@ -1,3 +1,33 @@
|
||||||
|
2000-07-17 Koundinya K <kk@ddeorg.soft.net>
|
||||||
|
|
||||||
|
Enable the support for Traditional MIPS.
|
||||||
|
* elf32-mips.c (IRIX_COMPAT): Recognize bfd_elf32_tradbigmips_vecand
|
||||||
|
return ict_none appropriately for traditional mips targets.
|
||||||
|
(STUB_LW): Change 0x8f998000 to 0x8f998010 for traditional mips.
|
||||||
|
(STUB_MOVE): Conditionalize for traditonal mips.
|
||||||
|
(STUB_LI16): Likewise.
|
||||||
|
(_bfd_mips_elf_modify_segment_map): Conditionalize to avoid making
|
||||||
|
room for RTPROC header.
|
||||||
|
(_bfd_mips_elf_modify_segment_map): For a normal mips executable set
|
||||||
|
the permission for the PT_DYNAMIC as read, write and execute.
|
||||||
|
(mips_elf_calculate_relocation): Check for the symbol _DYNAMIC_LINKING
|
||||||
|
for traditonal mips.
|
||||||
|
(_bfd_mips_elf_create_dynamic_sections): Add the symbol
|
||||||
|
_DYNAMIC_LINKING for traditonal mips.
|
||||||
|
(_bfd_mips_elf_create_dynamic_sections): Add the symbol __RLD_MAP
|
||||||
|
in case of traditonal mips.
|
||||||
|
(_bfd_mips_elf_adjust_dynamic_symbol): Create a stub only if a PLT
|
||||||
|
entry is required. For a function if PLT is not required then set the
|
||||||
|
corresponding hash table entry to 0.
|
||||||
|
(_bfd_mips_elf_size_dynamic_sections): Add DT_DEBUG entry for
|
||||||
|
traditonal mips.
|
||||||
|
(_bfd_mips_elf_finish_dynamic_symbol): for a undefined symbol in a
|
||||||
|
shared object set the value to 0.
|
||||||
|
(_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol
|
||||||
|
_DYNAMIC_LINKING for traditonal mips.
|
||||||
|
(_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol __RLD_MAP
|
||||||
|
for traditonal mips.
|
||||||
|
|
||||||
2000-07-15 H.J. Lu <hjl@gnu.org>
|
2000-07-15 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
* aoutx.h (translate_to_native_sym_flags): Handle BSF_LOCAL.
|
* aoutx.h (translate_to_native_sym_flags): Handle BSF_LOCAL.
|
||||||
|
|
370
bfd/elf32-mips.c
370
bfd/elf32-mips.c
|
@ -5,6 +5,8 @@
|
||||||
<ian@cygnus.com>.
|
<ian@cygnus.com>.
|
||||||
N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
|
N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
|
||||||
<mark@codesourcery.com>
|
<mark@codesourcery.com>
|
||||||
|
Traditional MIPS targets support added by Koundinya.K, Dansk Data
|
||||||
|
Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
|
|
||||||
|
@ -198,6 +200,8 @@ static boolean mips_elf_stub_section_p
|
||||||
static int sort_dynamic_relocs
|
static int sort_dynamic_relocs
|
||||||
PARAMS ((const void *, const void *));
|
PARAMS ((const void *, const void *));
|
||||||
|
|
||||||
|
extern const bfd_target bfd_elf32_tradbigmips_vec;
|
||||||
|
|
||||||
/* The level of IRIX compatibility we're striving for. */
|
/* The level of IRIX compatibility we're striving for. */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -219,12 +223,12 @@ static bfd *reldyn_sorting_bfd;
|
||||||
#define ABI_64_P(abfd) \
|
#define ABI_64_P(abfd) \
|
||||||
((elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) != 0)
|
((elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) != 0)
|
||||||
|
|
||||||
/* What version of Irix we are trying to be compatible with. FIXME:
|
/* Depending on the target vector we generate some version of Irix
|
||||||
At the moment, we never generate "normal" MIPS ELF ABI executables;
|
executables or "normal" MIPS ELF ABI executables. */
|
||||||
we always use some version of Irix. */
|
|
||||||
|
|
||||||
#define IRIX_COMPAT(abfd) \
|
#define IRIX_COMPAT(abfd) \
|
||||||
((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5)
|
(abfd->xvec == &bfd_elf32_tradbigmips_vec ? ict_none : \
|
||||||
|
((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))
|
||||||
|
|
||||||
/* Whether we are trying to be compatible with IRIX at all. */
|
/* Whether we are trying to be compatible with IRIX at all. */
|
||||||
|
|
||||||
|
@ -302,10 +306,12 @@ static bfd *reldyn_sorting_bfd;
|
||||||
? (ABI_64_P (abfd) \
|
? (ABI_64_P (abfd) \
|
||||||
? 0xdf998010 /* ld t9,0x8010(gp) */ \
|
? 0xdf998010 /* ld t9,0x8010(gp) */ \
|
||||||
: 0x8f998010) /* lw t9,0x8010(gp) */ \
|
: 0x8f998010) /* lw t9,0x8010(gp) */ \
|
||||||
: 0x8f998000) /* lw t9,0x8000(gp) */
|
: 0x8f998010) /* lw t9,0x8000(gp) */
|
||||||
#define STUB_MOVE 0x03e07825 /* move t7,ra */
|
#define STUB_MOVE(abfd) \
|
||||||
#define STUB_JALR 0x0320f809 /* jal t9 */
|
(SGI_COMPAT (abfd) ? 0x03e07825 : 0x03e07821) /* move t7,ra */
|
||||||
#define STUB_LI16 0x34180000 /* ori t8,zero,0 */
|
#define STUB_JALR 0x0320f809 /* jal t9 */
|
||||||
|
#define STUB_LI16(abfd) \
|
||||||
|
(SGI_COMPAT (abfd) ? 0x34180000 : 0x24180000) /* ori t8,zero,0 */
|
||||||
#define MIPS_FUNCTION_STUB_SIZE (16)
|
#define MIPS_FUNCTION_STUB_SIZE (16)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -2875,17 +2881,23 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
|
||||||
hdr->sh_type = SHT_MIPS_REGINFO;
|
hdr->sh_type = SHT_MIPS_REGINFO;
|
||||||
/* In a shared object on Irix 5.3, the .reginfo section has an
|
/* In a shared object on Irix 5.3, the .reginfo section has an
|
||||||
entsize of 0x18. FIXME: Does this matter? */
|
entsize of 0x18. FIXME: Does this matter? */
|
||||||
if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
|
if (SGI_COMPAT (abfd))
|
||||||
hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
|
{
|
||||||
|
if ((abfd->flags & DYNAMIC) != 0)
|
||||||
|
hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
|
||||||
|
else
|
||||||
|
hdr->sh_entsize = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
hdr->sh_entsize = 1;
|
hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
|
||||||
}
|
}
|
||||||
else if (SGI_COMPAT (abfd)
|
else if (SGI_COMPAT (abfd)
|
||||||
&& (strcmp (name, ".hash") == 0
|
&& (strcmp (name, ".hash") == 0
|
||||||
|| strcmp (name, ".dynamic") == 0
|
|| strcmp (name, ".dynamic") == 0
|
||||||
|| strcmp (name, ".dynstr") == 0))
|
|| strcmp (name, ".dynstr") == 0))
|
||||||
{
|
{
|
||||||
hdr->sh_entsize = 0;
|
if ( SGI_COMPAT(abfd))
|
||||||
|
hdr->sh_entsize = 0;
|
||||||
#if 0
|
#if 0
|
||||||
/* This isn't how the Irix 6 linker behaves. */
|
/* This isn't how the Irix 6 linker behaves. */
|
||||||
hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
|
hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
|
||||||
|
@ -3258,9 +3270,6 @@ _bfd_mips_elf_additional_program_headers (abfd)
|
||||||
asection *s;
|
asection *s;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!SGI_COMPAT (abfd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* See if we need a PT_MIPS_REGINFO segment. */
|
/* See if we need a PT_MIPS_REGINFO segment. */
|
||||||
s = bfd_get_section_by_name (abfd, ".reginfo");
|
s = bfd_get_section_by_name (abfd, ".reginfo");
|
||||||
if (s && (s->flags & SEC_LOAD))
|
if (s && (s->flags & SEC_LOAD))
|
||||||
|
@ -3290,9 +3299,6 @@ _bfd_mips_elf_modify_segment_map (abfd)
|
||||||
asection *s;
|
asection *s;
|
||||||
struct elf_segment_map *m, **pm;
|
struct elf_segment_map *m, **pm;
|
||||||
|
|
||||||
if (! SGI_COMPAT (abfd))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* If there is a .reginfo section, we need a PT_MIPS_REGINFO
|
/* If there is a .reginfo section, we need a PT_MIPS_REGINFO
|
||||||
segment. */
|
segment. */
|
||||||
s = bfd_get_section_by_name (abfd, ".reginfo");
|
s = bfd_get_section_by_name (abfd, ".reginfo");
|
||||||
|
@ -3362,58 +3368,72 @@ _bfd_mips_elf_modify_segment_map (abfd)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If there are .dynamic and .mdebug sections, we make a room
|
if (IRIX_COMPAT (abfd) == ict_irix5)
|
||||||
for the RTPROC header. FIXME: Rewrite without section names. */
|
|
||||||
if (bfd_get_section_by_name (abfd, ".interp") == NULL
|
|
||||||
&& bfd_get_section_by_name (abfd, ".dynamic") != NULL
|
|
||||||
&& bfd_get_section_by_name (abfd, ".mdebug") != NULL)
|
|
||||||
{
|
{
|
||||||
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
|
/* If there are .dynamic and .mdebug sections, we make a room
|
||||||
if (m->p_type == PT_MIPS_RTPROC)
|
for the RTPROC header. FIXME: Rewrite without section names. */
|
||||||
break;
|
if (bfd_get_section_by_name (abfd, ".interp") == NULL
|
||||||
if (m == NULL)
|
&& bfd_get_section_by_name (abfd, ".dynamic") != NULL
|
||||||
|
&& bfd_get_section_by_name (abfd, ".mdebug") != NULL)
|
||||||
{
|
{
|
||||||
m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
|
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
|
||||||
|
if (m->p_type == PT_MIPS_RTPROC)
|
||||||
|
break;
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return false;
|
|
||||||
|
|
||||||
m->p_type = PT_MIPS_RTPROC;
|
|
||||||
|
|
||||||
s = bfd_get_section_by_name (abfd, ".rtproc");
|
|
||||||
if (s == NULL)
|
|
||||||
{
|
{
|
||||||
m->count = 0;
|
m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
|
||||||
m->p_flags = 0;
|
if (m == NULL)
|
||||||
m->p_flags_valid = 1;
|
return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m->count = 1;
|
|
||||||
m->sections[0] = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We want to put it after the DYNAMIC segment. */
|
m->p_type = PT_MIPS_RTPROC;
|
||||||
pm = &elf_tdata (abfd)->segment_map;
|
|
||||||
while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
|
|
||||||
pm = &(*pm)->next;
|
|
||||||
if (*pm != NULL)
|
|
||||||
pm = &(*pm)->next;
|
|
||||||
|
|
||||||
m->next = *pm;
|
s = bfd_get_section_by_name (abfd, ".rtproc");
|
||||||
*pm = m;
|
if (s == NULL)
|
||||||
|
{
|
||||||
|
m->count = 0;
|
||||||
|
m->p_flags = 0;
|
||||||
|
m->p_flags_valid = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m->count = 1;
|
||||||
|
m->sections[0] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We want to put it after the DYNAMIC segment. */
|
||||||
|
pm = &elf_tdata (abfd)->segment_map;
|
||||||
|
while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
|
||||||
|
pm = &(*pm)->next;
|
||||||
|
if (*pm != NULL)
|
||||||
|
pm = &(*pm)->next;
|
||||||
|
|
||||||
|
m->next = *pm;
|
||||||
|
*pm = m;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On Irix 5, the PT_DYNAMIC segment includes the .dynamic,
|
/* On Irix 5, the PT_DYNAMIC segment includes the .dynamic,
|
||||||
.dynstr, .dynsym, and .hash sections, and everything in
|
.dynstr, .dynsym, and .hash sections, and everything in
|
||||||
between. */
|
between. */
|
||||||
for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
|
for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL;
|
||||||
|
pm = &(*pm)->next)
|
||||||
if ((*pm)->p_type == PT_DYNAMIC)
|
if ((*pm)->p_type == PT_DYNAMIC)
|
||||||
break;
|
break;
|
||||||
m = *pm;
|
m = *pm;
|
||||||
|
if (IRIX_COMPAT (abfd) == ict_none)
|
||||||
|
{
|
||||||
|
/* For a normal mips executable the permissions for the PT_DYNAMIC
|
||||||
|
segment are read, write and execute. We do that here since
|
||||||
|
the code in elf.c sets only the read permission. This matters
|
||||||
|
sometimes for the dynamic linker. */
|
||||||
|
if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
|
||||||
|
{
|
||||||
|
m->p_flags = PF_R | PF_W | PF_X;
|
||||||
|
m->p_flags_valid = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m != NULL
|
if (m != NULL
|
||||||
&& m->count == 1
|
&& m->count == 1 && strcmp (m->sections[0]->name, ".dynamic") == 0)
|
||||||
&& strcmp (m->sections[0]->name, ".dynamic") == 0)
|
|
||||||
{
|
{
|
||||||
static const char *sec_names[] =
|
static const char *sec_names[] =
|
||||||
{ ".dynamic", ".dynstr", ".dynsym", ".hash" };
|
{ ".dynamic", ".dynstr", ".dynsym", ".hash" };
|
||||||
|
@ -3445,8 +3465,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
|
||||||
if ((s->flags & SEC_LOAD) != 0
|
if ((s->flags & SEC_LOAD) != 0
|
||||||
&& s->vma >= low
|
&& s->vma >= low
|
||||||
&& ((s->vma
|
&& ((s->vma
|
||||||
+ (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
|
+ (s->_cooked_size !=
|
||||||
<= high))
|
0 ? s->_cooked_size : s->_raw_size)) <= high))
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
n = ((struct elf_segment_map *)
|
n = ((struct elf_segment_map *)
|
||||||
|
@ -3463,8 +3483,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
|
||||||
&& s->vma >= low
|
&& s->vma >= low
|
||||||
&& ((s->vma
|
&& ((s->vma
|
||||||
+ (s->_cooked_size != 0 ?
|
+ (s->_cooked_size != 0 ?
|
||||||
s->_cooked_size : s->_raw_size))
|
s->_cooked_size : s->_raw_size)) <= high))
|
||||||
<= high))
|
|
||||||
{
|
{
|
||||||
n->sections[i] = s;
|
n->sections[i] = s;
|
||||||
++i;
|
++i;
|
||||||
|
@ -4145,9 +4164,8 @@ mips_elf_output_extsym (h, data)
|
||||||
h->esym.asym.value = 0;
|
h->esym.asym.value = 0;
|
||||||
h->esym.asym.st = stGlobal;
|
h->esym.asym.st = stGlobal;
|
||||||
|
|
||||||
if (SGI_COMPAT (einfo->abfd)
|
if (h->root.root.type == bfd_link_hash_undefined
|
||||||
&& (h->root.root.type == bfd_link_hash_undefined
|
|| h->root.root.type == bfd_link_hash_undefweak)
|
||||||
|| h->root.root.type == bfd_link_hash_undefweak))
|
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
@ -4457,6 +4475,15 @@ _bfd_mips_elf_final_link (abfd, info)
|
||||||
= get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
|
= get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
|
||||||
HDRR *symhdr = &debug.symbolic_header;
|
HDRR *symhdr = &debug.symbolic_header;
|
||||||
PTR mdebug_handle = NULL;
|
PTR mdebug_handle = NULL;
|
||||||
|
asection *s;
|
||||||
|
EXTR esym;
|
||||||
|
bfd_vma last;
|
||||||
|
unsigned int i;
|
||||||
|
static const char * const name[] =
|
||||||
|
{ ".text", ".init", ".fini", ".data",
|
||||||
|
".rodata", ".sdata", ".sbss", ".bss" };
|
||||||
|
static const int sc[] = { scText, scInit, scFini, scData,
|
||||||
|
scRData, scSData, scSBss, scBss };
|
||||||
|
|
||||||
/* If all the things we linked together were PIC, but we're
|
/* If all the things we linked together were PIC, but we're
|
||||||
producing an executable (rather than a shared object), then the
|
producing an executable (rather than a shared object), then the
|
||||||
|
@ -4505,7 +4532,7 @@ _bfd_mips_elf_final_link (abfd, info)
|
||||||
include it, even though we don't process it quite right. (Some
|
include it, even though we don't process it quite right. (Some
|
||||||
entries are supposed to be merged.) Empirically, we seem to be
|
entries are supposed to be merged.) Empirically, we seem to be
|
||||||
better off including it then not. */
|
better off including it then not. */
|
||||||
if (IRIX_COMPAT (abfd) == ict_irix5)
|
if (IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
|
||||||
for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
|
for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
|
||||||
{
|
{
|
||||||
if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
|
if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
|
||||||
|
@ -4667,45 +4694,31 @@ _bfd_mips_elf_final_link (abfd, info)
|
||||||
if (mdebug_handle == (PTR) NULL)
|
if (mdebug_handle == (PTR) NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (SGI_COMPAT (abfd))
|
esym.jmptbl = 0;
|
||||||
{
|
esym.cobol_main = 0;
|
||||||
asection *s;
|
esym.weakext = 0;
|
||||||
EXTR esym;
|
esym.reserved = 0;
|
||||||
bfd_vma last;
|
esym.ifd = ifdNil;
|
||||||
unsigned int i;
|
esym.asym.iss = issNil;
|
||||||
static const char * const name[] =
|
esym.asym.st = stLocal;
|
||||||
{ ".text", ".init", ".fini", ".data",
|
esym.asym.reserved = 0;
|
||||||
".rodata", ".sdata", ".sbss", ".bss" };
|
esym.asym.index = indexNil;
|
||||||
static const int sc[] = { scText, scInit, scFini, scData,
|
last = 0;
|
||||||
scRData, scSData, scSBss, scBss };
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
esym.jmptbl = 0;
|
esym.asym.sc = sc[i];
|
||||||
esym.cobol_main = 0;
|
s = bfd_get_section_by_name (abfd, name[i]);
|
||||||
esym.weakext = 0;
|
if (s != NULL)
|
||||||
esym.reserved = 0;
|
{
|
||||||
esym.ifd = ifdNil;
|
esym.asym.value = s->vma;
|
||||||
esym.asym.iss = issNil;
|
last = s->vma + s->_raw_size;
|
||||||
esym.asym.st = stLocal;
|
}
|
||||||
esym.asym.reserved = 0;
|
else
|
||||||
esym.asym.index = indexNil;
|
esym.asym.value = last;
|
||||||
last = 0;
|
if (!bfd_ecoff_debug_one_external (abfd, &debug, swap,
|
||||||
for (i = 0; i < 8; i++)
|
name[i], &esym))
|
||||||
{
|
return false;
|
||||||
esym.asym.sc = sc[i];
|
}
|
||||||
s = bfd_get_section_by_name (abfd, name[i]);
|
|
||||||
if (s != NULL)
|
|
||||||
{
|
|
||||||
esym.asym.value = s->vma;
|
|
||||||
last = s->vma + s->_raw_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
esym.asym.value = last;
|
|
||||||
|
|
||||||
if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
|
|
||||||
name[i], &esym))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = o->link_order_head;
|
for (p = o->link_order_head;
|
||||||
p != (struct bfd_link_order *) NULL;
|
p != (struct bfd_link_order *) NULL;
|
||||||
|
@ -6011,10 +6024,12 @@ mips_elf_calculate_relocation (abfd,
|
||||||
else if (info->shared && !info->symbolic && !info->no_undefined
|
else if (info->shared && !info->symbolic && !info->no_undefined
|
||||||
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
|
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
|
||||||
symbol = 0;
|
symbol = 0;
|
||||||
else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0)
|
else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 ||
|
||||||
|
strcmp (h->root.root.root.string, "_DYNAMIC_LINKING") == 0)
|
||||||
{
|
{
|
||||||
/* If this is a dynamic link, we should have created a
|
/* If this is a dynamic link, we should have created a
|
||||||
_DYNAMIC_LINK symbol in mips_elf_create_dynamic_sections.
|
_DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol
|
||||||
|
in in mips_elf_create_dynamic_sections.
|
||||||
Otherwise, we should define the symbol with a value of 0.
|
Otherwise, we should define the symbol with a value of 0.
|
||||||
FIXME: It should probably get into the symbol table
|
FIXME: It should probably get into the symbol table
|
||||||
somehow as well. */
|
somehow as well. */
|
||||||
|
@ -7084,7 +7099,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IRIX_COMPAT (abfd) == ict_irix5
|
if (IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none
|
||||||
&& !info->shared
|
&& !info->shared
|
||||||
&& bfd_get_section_by_name (abfd, ".rld_map") == NULL)
|
&& bfd_get_section_by_name (abfd, ".rld_map") == NULL)
|
||||||
{
|
{
|
||||||
|
@ -7120,8 +7135,11 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to create a .compact_rel section. */
|
/* We need to create a .compact_rel section. */
|
||||||
if (! mips_elf_create_compact_rel_section (abfd, info))
|
if (SGI_COMPAT (abfd))
|
||||||
return false;
|
{
|
||||||
|
if (!mips_elf_create_compact_rel_section (abfd, info))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Change aligments of some sections. */
|
/* Change aligments of some sections. */
|
||||||
s = bfd_get_section_by_name (abfd, ".hash");
|
s = bfd_get_section_by_name (abfd, ".hash");
|
||||||
|
@ -7144,12 +7162,25 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
|
||||||
if (!info->shared)
|
if (!info->shared)
|
||||||
{
|
{
|
||||||
h = NULL;
|
h = NULL;
|
||||||
if (! (_bfd_generic_link_add_one_symbol
|
if (SGI_COMPAT (abfd))
|
||||||
|
{
|
||||||
|
if (!(_bfd_generic_link_add_one_symbol
|
||||||
(info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr,
|
(info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr,
|
||||||
(bfd_vma) 0, (const char *) NULL, false,
|
(bfd_vma) 0, (const char *) NULL, false,
|
||||||
get_elf_backend_data (abfd)->collect,
|
get_elf_backend_data (abfd)->collect,
|
||||||
(struct bfd_link_hash_entry **) &h)))
|
(struct bfd_link_hash_entry **) &h)))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For normal mips it is _DYNAMIC_LINKING. */
|
||||||
|
if (!(_bfd_generic_link_add_one_symbol
|
||||||
|
(info, abfd, "_DYNAMIC_LINKING", BSF_GLOBAL,
|
||||||
|
bfd_abs_section_ptr, (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_NON_ELF;
|
h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
|
||||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
||||||
h->type = STT_SECTION;
|
h->type = STT_SECTION;
|
||||||
|
@ -7167,12 +7198,25 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
|
||||||
BFD_ASSERT (s != NULL);
|
BFD_ASSERT (s != NULL);
|
||||||
|
|
||||||
h = NULL;
|
h = NULL;
|
||||||
if (! (_bfd_generic_link_add_one_symbol
|
if (SGI_COMPAT (abfd))
|
||||||
|
{
|
||||||
|
if (!(_bfd_generic_link_add_one_symbol
|
||||||
(info, abfd, "__rld_map", BSF_GLOBAL, s,
|
(info, abfd, "__rld_map", BSF_GLOBAL, s,
|
||||||
(bfd_vma) 0, (const char *) NULL, false,
|
(bfd_vma) 0, (const char *) NULL, false,
|
||||||
get_elf_backend_data (abfd)->collect,
|
get_elf_backend_data (abfd)->collect,
|
||||||
(struct bfd_link_hash_entry **) &h)))
|
(struct bfd_link_hash_entry **) &h)))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For normal mips the symbol is __RLD_MAP. */
|
||||||
|
if (!(_bfd_generic_link_add_one_symbol
|
||||||
|
(info, abfd, "__RLD_MAP", 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_NON_ELF;
|
h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
|
||||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
||||||
h->type = STT_OBJECT;
|
h->type = STT_OBJECT;
|
||||||
|
@ -7914,8 +7958,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
|
||||||
hmips->possibly_dynamic_relocs);
|
hmips->possibly_dynamic_relocs);
|
||||||
|
|
||||||
/* For a function, create a stub, if needed. */
|
/* For a function, create a stub, if needed. */
|
||||||
if (h->type == STT_FUNC
|
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
|
||||||
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
|
|
||||||
{
|
{
|
||||||
if (! elf_hash_table (info)->dynamic_sections_created)
|
if (! elf_hash_table (info)->dynamic_sections_created)
|
||||||
return true;
|
return true;
|
||||||
|
@ -7945,6 +7988,14 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((h->type == STT_FUNC)
|
||||||
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0)
|
||||||
|
{
|
||||||
|
/* This will set the entry for this symbol in the GOT to 0, and
|
||||||
|
the dynamic linker will take care of this. */
|
||||||
|
h->root.u.def.value = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is a weak symbol, and there is a real definition, the
|
/* If this is a weak symbol, and there is a real definition, the
|
||||||
processor independent code will have arranged for us to see the
|
processor independent code will have arranged for us to see the
|
||||||
|
@ -8245,19 +8296,26 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
|
||||||
dynamic linker and used by the debugger. */
|
dynamic linker and used by the debugger. */
|
||||||
if (! info->shared)
|
if (! info->shared)
|
||||||
{
|
{
|
||||||
if (SGI_COMPAT (output_bfd))
|
/* SGI object has the equivalence of DT_DEBUG in the
|
||||||
{
|
DT_MIPS_RLD_MAP entry. */
|
||||||
/* SGI object has the equivalence of DT_DEBUG in the
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
|
||||||
DT_MIPS_RLD_MAP entry. */
|
return false;
|
||||||
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
|
if (!SGI_COMPAT (output_bfd))
|
||||||
return false;
|
{
|
||||||
}
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
|
||||||
else
|
return false;
|
||||||
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
|
}
|
||||||
return false;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
if (reltext)
|
/* Shared libraries on traditional mips have DT_DEBUG. */
|
||||||
|
if (!SGI_COMPAT (output_bfd))
|
||||||
|
{
|
||||||
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reltext && SGI_COMPAT(output_bfd))
|
||||||
{
|
{
|
||||||
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
|
||||||
return false;
|
return false;
|
||||||
|
@ -8279,11 +8337,17 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICTNO, 0))
|
if (SGI_COMPAT (output_bfd))
|
||||||
return false;
|
{
|
||||||
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICTNO, 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLISTNO, 0))
|
if (SGI_COMPAT (output_bfd))
|
||||||
return false;
|
{
|
||||||
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLISTNO, 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (bfd_get_section_by_name (dynobj, ".conflict") != NULL)
|
if (bfd_get_section_by_name (dynobj, ".conflict") != NULL)
|
||||||
{
|
{
|
||||||
|
@ -8444,7 +8508,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
p = stub;
|
p = stub;
|
||||||
bfd_put_32 (output_bfd, STUB_LW(output_bfd), p);
|
bfd_put_32 (output_bfd, STUB_LW(output_bfd), p);
|
||||||
p += 4;
|
p += 4;
|
||||||
bfd_put_32 (output_bfd, STUB_MOVE, p);
|
bfd_put_32 (output_bfd, STUB_MOVE(output_bfd), p);
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
/* FIXME: Can h->dynindex be more than 64K? */
|
/* FIXME: Can h->dynindex be more than 64K? */
|
||||||
|
@ -8453,7 +8517,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
|
|
||||||
bfd_put_32 (output_bfd, STUB_JALR, p);
|
bfd_put_32 (output_bfd, STUB_JALR, p);
|
||||||
p += 4;
|
p += 4;
|
||||||
bfd_put_32 (output_bfd, STUB_LI16 + h->dynindx, p);
|
bfd_put_32 (output_bfd, STUB_LI16(output_bfd) + h->dynindx, p);
|
||||||
|
|
||||||
BFD_ASSERT (h->plt.offset <= s->_raw_size);
|
BFD_ASSERT (h->plt.offset <= s->_raw_size);
|
||||||
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
|
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
|
||||||
|
@ -8489,13 +8553,18 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
if (sym->st_value)
|
if (sym->st_value)
|
||||||
value = sym->st_value;
|
value = sym->st_value;
|
||||||
else
|
else
|
||||||
/* For an entity defined in a shared object, this will be
|
{
|
||||||
NULL. (For functions in shared objects for
|
/* For an entity defined in a shared object, this will be
|
||||||
which we have created stubs, ST_VALUE will be non-NULL.
|
NULL. (For functions in shared objects for
|
||||||
That's because such the functions are now no longer defined
|
which we have created stubs, ST_VALUE will be non-NULL.
|
||||||
in a shared object.) */
|
That's because such the functions are now no longer defined
|
||||||
value = h->root.u.def.value;
|
in a shared object.) */
|
||||||
|
|
||||||
|
if (info->shared && h->root.type == bfd_link_hash_undefined)
|
||||||
|
value = 0;
|
||||||
|
else
|
||||||
|
value = h->root.u.def.value;
|
||||||
|
}
|
||||||
offset = mips_elf_global_got_index (dynobj, h);
|
offset = mips_elf_global_got_index (dynobj, h);
|
||||||
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
|
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
|
||||||
}
|
}
|
||||||
|
@ -8521,21 +8590,22 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
if (strcmp (name, "_DYNAMIC") == 0
|
if (strcmp (name, "_DYNAMIC") == 0
|
||||||
|| strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
|
|| strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
|
||||||
sym->st_shndx = SHN_ABS;
|
sym->st_shndx = SHN_ABS;
|
||||||
else if (strcmp (name, "_DYNAMIC_LINK") == 0)
|
else if (strcmp (name, "_DYNAMIC_LINK") == 0
|
||||||
|
|| strcmp (name, "_DYNAMIC_LINKING") == 0)
|
||||||
{
|
{
|
||||||
sym->st_shndx = SHN_ABS;
|
sym->st_shndx = SHN_ABS;
|
||||||
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
||||||
sym->st_value = 1;
|
sym->st_value = 1;
|
||||||
}
|
}
|
||||||
|
else if (strcmp (name, "_gp_disp") == 0)
|
||||||
|
{
|
||||||
|
sym->st_shndx = SHN_ABS;
|
||||||
|
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
||||||
|
sym->st_value = elf_gp (output_bfd);
|
||||||
|
}
|
||||||
else if (SGI_COMPAT (output_bfd))
|
else if (SGI_COMPAT (output_bfd))
|
||||||
{
|
{
|
||||||
if (strcmp (name, "_gp_disp") == 0)
|
if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
|
||||||
{
|
|
||||||
sym->st_shndx = SHN_ABS;
|
|
||||||
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
|
||||||
sym->st_value = elf_gp (output_bfd);
|
|
||||||
}
|
|
||||||
else if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
|
|
||||||
|| strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
|
|| strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
|
||||||
{
|
{
|
||||||
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
||||||
|
@ -8563,11 +8633,10 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
if (IRIX_COMPAT (output_bfd) == ict_irix6)
|
if (IRIX_COMPAT (output_bfd) == ict_irix6)
|
||||||
mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
|
mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
|
||||||
|
|
||||||
if (SGI_COMPAT (output_bfd)
|
if (! info->shared)
|
||||||
&& ! info->shared)
|
|
||||||
{
|
{
|
||||||
if (! mips_elf_hash_table (info)->use_rld_obj_head
|
if (! mips_elf_hash_table (info)->use_rld_obj_head
|
||||||
&& strcmp (name, "__rld_map") == 0)
|
&& strcmp (name, "__rld_map") == 0 || strcmp (name, "__RLD_MAP") == 0)
|
||||||
{
|
{
|
||||||
asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
|
asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
|
||||||
BFD_ASSERT (s != NULL);
|
BFD_ASSERT (s != NULL);
|
||||||
|
@ -8580,7 +8649,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
&& strcmp (name, "__rld_obj_head") == 0)
|
&& strcmp (name, "__rld_obj_head") == 0)
|
||||||
{
|
{
|
||||||
/* IRIX6 does not use a .rld_map section. */
|
/* IRIX6 does not use a .rld_map section. */
|
||||||
if (IRIX_COMPAT (output_bfd) == ict_irix5)
|
if (IRIX_COMPAT (output_bfd) == ict_irix5
|
||||||
|
|| IRIX_COMPAT (output_bfd) == ict_none)
|
||||||
BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
|
BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
|
||||||
!= NULL);
|
!= NULL);
|
||||||
mips_elf_hash_table (info)->rld_value = sym->st_value;
|
mips_elf_hash_table (info)->rld_value = sym->st_value;
|
||||||
|
|
Loading…
Add table
Reference in a new issue