This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
PATCH for 64-bit MIPS ELF buglets
- To: binutils@sourceware.cygnus.com
- Subject: PATCH for 64-bit MIPS ELF buglets
- From: Mark Mitchell <mark@codesourcery.com>
- Date: Mon, 12 Jul 1999 12:12:19 -0700
- Organization: CodeSourcery, LLC
These patches improve the 64-bit MIPS ELF support. They handle
DW_FORM_ref8, and handle the R_MIPS_64 relocation correctly. (Like
R_MIPS_32 it must become a dynamic relocation if the relocation is
against an object in a shared library.) Finally, we allow
elf_fake_sections to figure out that .rel.dyn is the dynamic
relocation section, even when using the 64-bit ABI, and even though
the 64-bit ABI uses SHT_RELA sections by default.
The only controversy I can spot in this patch is this hunk:
@@ -678,22 +679,19 @@ static reloc_howto_type elf_mips_howto_t
0x000007c4, /* dst_mask */
false), /* pcrel_offset */
- /* A 64 bit relocation. This is used in 32 bit ELF when addresses
- are 64 bits long; the upper 32 bits are simply a sign extension.
- The fields of the howto should be the same as for R_MIPS_32,
- other than the type, name, and special_function. */
+ /* A 64 bit relocation. */
HOWTO (R_MIPS_64, /* type */
0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
mips32_64bit_reloc, /* special_function */
"R_MIPS_64", /* name */
true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
false), /* pcrel_offset */
/* Displacement in the global offset table. */
I don't understand the comment; R_MIPS_64 is clearly documented as a
64-bit relocation in the MIPS ABI. Period.
However, if someone thinks this patch is wrong, but approves the rest
of the patch, I will check in an alternative version in which we use a
special HOWTO only for the 64-bit ABI, and retain the current version
for the 32-bit ABIs.
OK to check in?
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-07-12 Mark Mitchell <mark@codesourcery.com>
* dwarf2.c (read_attribute): Support DW_FORM_ref8.
* elf32-mips.c (mips_elf_link_hash_entry): Change mips_32_relocs
to possibly_dynamic_relocs. Adjust usage throughout code.
(elf_mips_howto_table): Handle R_MIPS_64 correctly.
(elf_mips_ctor64_howto): Likewise.
(mips_elf_calculate_relocation): Handle R_MIPS_64 like R_MIPS_32.
Adjust indentation.
(_bfd_mips_elf_check_relocs): Handle R_MIPS_64 like R_MIPS_32.
Use MIPS_ELF_GOT_SIZE to calculate the size of GOT entries.
* elf64-mips.c (elf_backend_may_use_rel_p): Define.
Index: dwarf2.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/dwarf2.c,v
retrieving revision 1.7
diff -u -p -r1.7 dwarf2.c
--- dwarf2.c 1999/07/02 21:03:50 1.7
+++ dwarf2.c 1999/07/12 19:00:02
@@ -611,6 +611,10 @@ read_attribute (attr, abbrev, unit, info
DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
info_ptr += 4;
break;
+ case DW_FORM_ref8:
+ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
case DW_FORM_ref_udata:
DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-mips.c
--- elf32-mips.c 1999/07/12 07:35:06 1.17
+++ elf32-mips.c 1999/07/12 19:00:06
@@ -67,8 +67,9 @@ struct mips_elf_link_hash_entry
/* External symbol information. */
EXTR esym;
- /* Number of MIPS_32 or MIPS_REL32 relocs against this symbol. */
- unsigned int mips_32_relocs;
+ /* Number of R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 relocs against
+ this symbol. */
+ unsigned int possibly_dynamic_relocs;
/* The index of the first dynamic relocation (in the .rel.dyn
section) against this symbol. */
@@ -678,22 +679,19 @@ static reloc_howto_type elf_mips_howto_t
0x000007c4, /* dst_mask */
false), /* pcrel_offset */
- /* A 64 bit relocation. This is used in 32 bit ELF when addresses
- are 64 bits long; the upper 32 bits are simply a sign extension.
- The fields of the howto should be the same as for R_MIPS_32,
- other than the type, name, and special_function. */
+ /* A 64 bit relocation. */
HOWTO (R_MIPS_64, /* type */
0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
mips32_64bit_reloc, /* special_function */
"R_MIPS_64", /* name */
true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
false), /* pcrel_offset */
/* Displacement in the global offset table. */
@@ -901,8 +899,8 @@ static reloc_howto_type elf_mips_ctor64_
mips32_64bit_reloc, /* special_function */
"R_MIPS_64", /* name */
true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
false); /* pcrel_offset */
/* The reloc used for the mips16 jump instruction. */
@@ -3766,7 +3764,7 @@ mips_elf_link_hash_newfunc (entry, table
/* We use -2 as a marker to indicate that the information has
not been set. -1 means there is no associated ifd. */
ret->esym.ifd = -2;
- ret->mips_32_relocs = 0;
+ ret->possibly_dynamic_relocs = 0;
ret->min_dyn_reloc_index = 0;
ret->fn_stub = NULL;
ret->need_fn_stub = false;
@@ -5850,6 +5848,7 @@ mips_elf_calculate_relocation (abfd,
case R_MIPS_32:
case R_MIPS_REL32:
+ case R_MIPS_64:
/* If we're creating a shared library, or this relocation is
against a symbol in a shared library, then we can't know
where the symbol will end up. So, we create a relocation
@@ -5862,11 +5861,11 @@ mips_elf_calculate_relocation (abfd,
BFD_ASSERT (h != NULL);
reloc_index
= mips_elf_create_dynamic_relocation (abfd,
- info,
- relocation,
- h->root.dynindx,
- addend,
- input_section);
+ info,
+ relocation,
+ h->root.dynindx,
+ addend,
+ input_section);
if (h->min_dyn_reloc_index == 0
|| reloc_index < h->min_dyn_reloc_index)
h->min_dyn_reloc_index = reloc_index;
@@ -5874,7 +5873,7 @@ mips_elf_calculate_relocation (abfd,
}
else
{
- if (r_type == R_MIPS_32)
+ if (r_type != R_MIPS_REL32)
value = symbol + addend;
else
value = addend;
@@ -5975,10 +5974,6 @@ mips_elf_calculate_relocation (abfd,
value = g & howto->dst_mask;
break;
- case R_MIPS_64:
- value = (symbol + addend) & howto->dst_mask;
- break;
-
case R_MIPS_GOT_PAGE:
value = mips_elf_got_page (abfd, info, symbol + addend, NULL);
if (value == (bfd_vma) -1)
@@ -6891,6 +6886,7 @@ _bfd_mips_elf_check_relocs (abfd, info,
case R_MIPS_32:
case R_MIPS_REL32:
+ case R_MIPS_64:
if (dynobj == NULL
&& (info->shared || h != NULL)
&& (sec->flags & SEC_ALLOC) != 0)
@@ -6918,7 +6914,7 @@ _bfd_mips_elf_check_relocs (abfd, info,
conservative, we could actually build the GOT here,
rather than in relocate_section. */
g->local_gotno++;
- sgot->_raw_size += 4;
+ sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
}
switch (r_type)
@@ -6959,6 +6955,7 @@ _bfd_mips_elf_check_relocs (abfd, info,
case R_MIPS_32:
case R_MIPS_REL32:
+ case R_MIPS_64:
if ((info->shared || h != NULL)
&& (sec->flags & SEC_ALLOC) != 0)
{
@@ -6996,7 +6993,7 @@ _bfd_mips_elf_check_relocs (abfd, info,
/* We only need to copy this reloc if the symbol is
defined in a dynamic object. */
hmips = (struct mips_elf_link_hash_entry *) h;
- ++hmips->mips_32_relocs;
+ ++hmips->possibly_dynamic_relocs;
}
/* Even though we don't directly need a GOT entry for
@@ -7189,9 +7186,10 @@ _bfd_mips_elf_adjust_dynamic_symbol (inf
file. */
hmips = (struct mips_elf_link_hash_entry *) h;
if (! info->relocateable
- && hmips->mips_32_relocs != 0
+ && hmips->possibly_dynamic_relocs != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- mips_elf_allocate_dynamic_relocations (dynobj, hmips->mips_32_relocs);
+ mips_elf_allocate_dynamic_relocations (dynobj,
+ hmips->possibly_dynamic_relocs);
/* For a function, create a stub, if needed. */
if (h->type == STT_FUNC
Index: elf64-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf64-mips.c,v
retrieving revision 1.6
diff -u -p -r1.6 elf64-mips.c
--- elf64-mips.c 1999/07/07 19:23:21 1.6
+++ elf64-mips.c 1999/07/12 19:00:07
@@ -2148,6 +2148,7 @@ const struct elf_size_info mips_elf64_si
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
#define elf_backend_got_header_size (4*MIPS_RESERVED_GOTNO)
#define elf_backend_plt_header_size 0
+#define elf_backend_may_use_rel_p 1
/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
MIPS-specific function only applies to IRIX5, which had no 64-bit