This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
PATCH for more IRIX6 changes to elf32-mips.c
- To: binutils@sourceware.cygnus.com
- Subject: PATCH for more IRIX6 changes to elf32-mips.c
- From: Mark Mitchell <mark@codesourcery.com>
- Date: Sun, 27 Jun 1999 17:06:27 -0700
- Organization: CodeSourcery, LLC
Here's the next batch 'o patch. (Thanks to Richard & Ian for
processing these, and in pretty short order, too.) We're getting
pretty close to the meaty stuff, now.
This chunk:
o Uses macros instead of string literals for section names in
many places. This is a) necessary (since IRIX6 uses different
names than IRIX5 apparently did) and b) cleaner.
o Adds support for .srdata and the .MIPS.options section.
o Adjusts ELF_DYNAMIC_INTERPRETER to reflect the correct N32
interpreter.
o Makes a few other minor tweaks required for N32 support.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-06-27 Mark Mitchell <mark@codesourcery.com>
* elf32-mips.c (MIPS_ELF_SRDATA_SECTION_NAME): New macro.
(MIPS_ELF_OPTIONS_SECTION_NAME): Likewise.
(MIPS_ELF_STUB_SECTION_NAME): Likewise.
(_bfd_mips_elf_section_from_shdr): Use them.
(_bfd_mips_elf_fake_sections): Likewise. Add .srdata to the list
of GP-relative sections.
(_bfd_mips_elf_set_section_contents): Use them.
(_bfd_mips_elf_section_processing): Share code between .sdata and
.lit4/.lit8 sections. Set appropriate flags for .srdata.
(mips_elf_additional_program_headers): Add handling for
PT_MIPS_OPTIONS segment on IRIX6.
(mips_elf_modify_segment_map): Likeiwse.
(mips_elf_final_link): Set EF_MIPS_CPIC when required by the ABI.
Include the options sections on IRIX6. Don't look for GP-relative
sections by name; use SHF_MIPS_GPREL instead.
(ELF_DYNAMIC_INTERPRETER): Adjust to use /usr/lib32/libc.so.1 for
the N32 ABI.
(mips_elf_create_dynamic_sections): Don't muck about with section
alignments and such on IRIX6.
(mips_elf_adjust_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
(mips_elf_size_dynamic_sections): Likewise. Adjust to handle the
fact that ELF_DYNAMIC_INTERPRETER is no longer a constant. Use
bfd_zalloc rather than bfd_alloc and memset.
(mips_elf_finish_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
Don't assert the existence of .rld_map on IRIX6.
(mips_elf_finish_dynamic_sections): Use MIPS_ELF_STUB_SECTION_NAME.
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-mips.c
--- elf32-mips.c 1999/06/27 16:11:13 1.8
+++ elf32-mips.c 1999/06/28 00:01:08
@@ -170,6 +170,17 @@ struct mips_got_info
/* The name of the msym section. */
#define MIPS_ELF_MSYM_SECTION_NAME(abfd) ".msym"
+/* The name of the srdata section. */
+#define MIPS_ELF_SRDATA_SECTION_NAME(abfd) ".srdata"
+
+/* The name of the options section. */
+#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
+ (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.options" : ".options")
+
+/* The name of the stub section. */
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
+ (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.stubs" : ".stub")
+
/* The number of local .got entries we reserve. */
#define MIPS_RESERVED_GOTNO (2)
@@ -2449,8 +2460,7 @@ _bfd_mips_elf_section_from_shdr (abfd, h
return false;
break;
case SHT_MIPS_OPTIONS:
- if (strcmp (name, ".options") != 0
- && strcmp (name, ".MIPS.options") != 0)
+ if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) != 0)
return false;
break;
case SHT_MIPS_DWARF:
@@ -2627,6 +2637,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr,
#endif
}
else if (strcmp (name, ".got") == 0
+ || strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0
|| strcmp (name, ".sdata") == 0
|| strcmp (name, ".sbss") == 0
|| strcmp (name, ".lit4") == 0
@@ -2643,8 +2654,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr,
hdr->sh_flags |= SHF_MIPS_NOSTRIP;
/* The sh_info field is set in final_write_processing. */
}
- else if (strcmp (name, ".options") == 0
- || strcmp (name, ".MIPS.options") == 0)
+ else if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
{
hdr->sh_type = SHT_MIPS_OPTIONS;
hdr->sh_entsize = 1;
@@ -2714,8 +2724,7 @@ _bfd_mips_elf_set_section_contents (abfd
file_ptr offset;
bfd_size_type count;
{
- if (strcmp (section->name, ".options") == 0
- || strcmp (section->name, ".MIPS.options") == 0)
+ if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
{
bfd_byte *c;
@@ -2762,7 +2771,9 @@ _bfd_mips_elf_section_processing (abfd,
{
const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
- if (strcmp (name, ".sdata") == 0)
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".lit8") == 0
+ || strcmp (name, ".lit4") == 0)
{
hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
hdr->sh_type = SHT_PROGBITS;
@@ -2772,10 +2783,9 @@ _bfd_mips_elf_section_processing (abfd,
hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
hdr->sh_type = SHT_NOBITS;
}
- else if (strcmp (name, ".lit8") == 0
- || strcmp (name, ".lit4") == 0)
+ else if (strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0)
{
- hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+ hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
hdr->sh_type = SHT_PROGBITS;
}
else if (strcmp (name, ".compact_rel") == 0)
@@ -2981,26 +2991,27 @@ mips_elf_additional_program_headers (abf
bfd *abfd;
{
asection *s;
- int ret;
+ int ret = 0;
- ret = 0;
-
- if (! SGI_COMPAT (abfd))
- return ret;
+ if (!SGI_COMPAT (abfd))
+ return 0;
+ /* See if we need a PT_MIPS_REGINFO segment. */
s = bfd_get_section_by_name (abfd, ".reginfo");
- if (s != NULL && (s->flags & SEC_LOAD) != 0)
- {
- /* We need a PT_MIPS_REGINFO segment. */
- ++ret;
- }
+ if (s && (s->flags & SEC_LOAD))
+ ++ret;
- if (bfd_get_section_by_name (abfd, ".dynamic") != NULL
- && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
- {
- /* We need a PT_MIPS_RTPROC segment. */
- ++ret;
- }
+ /* See if we need a PT_MIPS_OPTIONS segment. */
+ if (IRIX_COMPAT (abfd) == ict_irix6
+ && bfd_get_section_by_name (abfd,
+ MIPS_ELF_OPTIONS_SECTION_NAME (abfd)))
+ ++ret;
+
+ /* See if we need a PT_MIPS_RTPROC segment. */
+ if (IRIX_COMPAT (abfd) == ict_irix5
+ && bfd_get_section_by_name (abfd, ".dynamic")
+ && bfd_get_section_by_name (abfd, ".mdebug"))
+ ++ret;
return ret;
}
@@ -3047,6 +3058,44 @@ mips_elf_modify_segment_map (abfd)
}
}
+ /* For IRIX 6, we don't have .mdebug sections, nor does anything but
+ .dynamic end up in PT_DYNAMIC. However, we do have to insert a
+ PT_OPTIONS segement immediately following the program header
+ table. */
+ if (IRIX_COMPAT (abfd) == ict_irix6)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s; s = s->next)
+ if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
+ break;
+
+ if (s)
+ {
+ struct elf_segment_map *options_segment;
+
+ for (m = elf_tdata (abfd)->segment_map; m; m = m->next)
+ if (m->p_type == PT_PHDR)
+ break;
+
+ /* There should always be a program header table. */
+ if (m == NULL)
+ return false;
+
+ options_segment = bfd_zalloc (abfd,
+ sizeof (struct elf_segment_map));
+ options_segment->next = m->next;
+ options_segment->p_type = PT_MIPS_OPTIONS;
+ options_segment->p_flags = PF_R;
+ options_segment->p_flags_valid = true;
+ options_segment->count = 1;
+ options_segment->sections[0] = s;
+ m->next = options_segment;
+ }
+
+ return true;
+ }
+
/* If there are .dynamic and .mdebug sections, we make a room for
the RTPROC header. FIXME: Rewrite without section names. */
if (bfd_get_section_by_name (abfd, ".interp") == NULL
@@ -4121,21 +4170,35 @@ mips_elf_final_link (abfd, info)
HDRR *symhdr = &debug.symbolic_header;
PTR mdebug_handle = NULL;
- /* Drop the .options section, since it has special semantics which I
- haven't bothered to figure out. */
- for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
- {
- if (strcmp ((*secpp)->name, ".options") == 0)
- {
- for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
- if (p->type == bfd_indirect_link_order)
- p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
- (*secpp)->link_order_head = NULL;
- *secpp = (*secpp)->next;
- --abfd->section_count;
- break;
- }
- }
+ /* If all the things we linked together were PIC, but we're
+ producing an executable (rather than a shared object), then the
+ resulting file is CPIC (i.e., it calls PIC code.) */
+ if (!info->shared && elf_elfheader (abfd)->e_flags & EF_MIPS_PIC)
+ {
+ elf_elfheader (abfd)->e_flags &= ~EF_MIPS_PIC;
+ elf_elfheader (abfd)->e_flags |= EF_MIPS_CPIC;
+
+ }
+
+ /* On IRIX5, we omit the .options section. On IRIX6, however, we
+ included it, even though we don't process it quite right. (Some
+ entries are supposed to be merged.) Emprically, we seem to be
+ better off including it then not. */
+ if (IRIX_COMPAT (abfd) == ict_irix5)
+ for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
+ {
+ if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
+ {
+ for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
+ if (p->type == bfd_indirect_link_order)
+ p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
+ (*secpp)->link_order_head = NULL;
+ *secpp = (*secpp)->next;
+ --abfd->section_count;
+
+ break;
+ }
+ }
/* Get a value for the GP register. */
if (elf_gp (abfd) == 0)
@@ -4152,17 +4215,14 @@ mips_elf_final_link (abfd, info)
{
bfd_vma lo;
- /* Make up a value. */
+ /* Find the GP-relative section with the lowest offset. */
lo = (bfd_vma) -1;
for (o = abfd->sections; o != (asection *) NULL; o = o->next)
- {
- if (o->vma < lo
- && (strcmp (o->name, ".sbss") == 0
- || strcmp (o->name, ".sdata") == 0
- || strcmp (o->name, ".lit4") == 0
- || strcmp (o->name, ".lit8") == 0))
- lo = o->vma;
- }
+ if (o->vma < lo
+ && (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
+ lo = o->vma;
+
+ /* And calculate GP relative to that. */
elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd);
}
else
@@ -5815,7 +5875,8 @@ mips_elf_link_output_symbol_hook (abfd,
/* The name of the dynamic interpreter. This is put in the .interp
section. */
-#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+#define ELF_DYNAMIC_INTERPRETER(abfd) \
+ (ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1" : "/usr/lib/libc.so.1")
/* Create dynamic sections when linking against a dynamic object. */
@@ -5872,7 +5933,11 @@ mips_elf_create_dynamic_sections (abfd,
return false;
}
- if (SGI_COMPAT (abfd))
+ /* On IRIX5, we adjust add some additional symbols and change the
+ alignments of several sections. There is no ABI documentation
+ indicating that this is necessary on IRIX6, nor any evidence that
+ the linker takes such action. */
+ if (IRIX_COMPAT (abfd) == ict_irix5)
{
for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
{
@@ -6679,7 +6744,8 @@ mips_elf_adjust_dynamic_symbol (info, h)
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
/* We need .stub section. */
- s = bfd_get_section_by_name (dynobj, ".stub");
+ s = bfd_get_section_by_name (dynobj,
+ MIPS_ELF_STUB_SECTION_NAME (dynobj));
BFD_ASSERT (s != NULL);
h->root.u.def.section = s;
@@ -6819,8 +6885,10 @@ mips_elf_size_dynamic_sections (output_b
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
- s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ s->_raw_size
+ = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
+ s->contents
+ = (unsigned char *) ELF_DYNAMIC_INTERPRETER (output_bfd);
}
}
@@ -6929,7 +6997,7 @@ mips_elf_size_dynamic_sections (output_b
i = elf_hash_table (info)->dynsymcount - g->global_gotsym;
s->_raw_size += i * 4;
}
- else if (strncmp (name, ".stub", 5) == 0)
+ else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
{
/* Irix rld assumes that the function stub isn't at the end
of .text section. So put a dummy. XXX */
@@ -6964,13 +7032,12 @@ mips_elf_size_dynamic_sections (output_b
}
/* Allocate memory for the section contents. */
- s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
if (s->contents == NULL && s->_raw_size != 0)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
- memset (s->contents, 0, s->_raw_size);
}
if (elf_hash_table (info)->dynamic_sections_created)
@@ -7203,7 +7270,8 @@ mips_elf_finish_dynamic_symbol (output_b
BFD_ASSERT (h->dynindx != -1);
- s = bfd_get_section_by_name (dynobj, ".stub");
+ s = bfd_get_section_by_name (dynobj,
+ MIPS_ELF_STUB_SECTION_NAME (dynobj));
BFD_ASSERT (s != NULL);
/* Fill the stub. */
@@ -7333,8 +7401,10 @@ mips_elf_finish_dynamic_symbol (output_b
else if (mips_elf_hash_table (info)->use_rld_obj_head
&& strcmp (name, "__rld_obj_head") == 0)
{
- asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
- BFD_ASSERT (s != NULL);
+ /* IRIX6 does not use a .rld_map section. */
+ if (IRIX_COMPAT (output_bfd) == ict_irix5)
+ BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
+ != NULL);
mips_elf_hash_table (info)->rld_value = sym->st_value;
}
}
@@ -7673,7 +7743,8 @@ mips_elf_finish_dynamic_sections (output
s->contents));
/* Clean up a dummy stub function entry in .text. */
- s = bfd_get_section_by_name (dynobj, ".stub");
+ s = bfd_get_section_by_name (dynobj,
+ MIPS_ELF_STUB_SECTION_NAME (dynobj));
if (s != NULL)
{
file_ptr dummy_offset;