* elf64-sparc.c (sparc64_elf_howto_table): Add UA64 & UA16.
authorRichard Henderson <rth@redhat.com>
Thu, 23 Oct 1997 21:16:43 +0000 (21:16 +0000)
committerRichard Henderson <rth@redhat.com>
Thu, 23 Oct 1997 21:16:43 +0000 (21:16 +0000)
        (sparc64_elf_check_relocs): Handle them.
        (sparc64_elf_relocate_section): Likewise.  Before emitting a dyn reloc,
        check alignment and transmute R_SPARC_x<->R_SPARC_UAx.

bfd/ChangeLog
bfd/elf64-sparc.c

index 3f2e17694077b67fa56627d9bec2b922cb70f233..e124f92e72c63e3a4c2d689d17c98d8775b3d63c 100644 (file)
@@ -1,3 +1,10 @@
+Thu Oct 23 14:09:33 1997  Richard Henderson  <rth@cygnus.com>
+
+       * elf64-sparc.c (sparc64_elf_howto_table): Add UA64 & UA16.
+       (sparc64_elf_check_relocs): Handle them.
+       (sparc64_elf_relocate_section): Likewise.  Before emitting a dyn reloc,
+       check alignment and transmute R_SPARC_x<->R_SPARC_UAx.
+
 Thu Oct 23 00:53:14 1997  Richard Henderson  <rth@dot.cygnus.com>
 
        * configure.in (sparc*-*-linux*): Use trad-core and ...
index c2a8a8af9cad1f0ffab3e62a62c9bc6acc36bbc9..a579ba42227e6cf3f0b70d84ffd72a0bf14eb9da 100644 (file)
@@ -121,7 +121,9 @@ static reloc_howto_type sparc64_elf_howto_table[] =
   HOWTO(R_SPARC_H44,      22,2,22,false,0,complain_overflow_unsigned,bfd_elf_generic_reloc,  "R_SPARC_H44",     false,0,0x003fffff,false),
   HOWTO(R_SPARC_M44,      12,2,10,false,0,complain_overflow_dont,    bfd_elf_generic_reloc,  "R_SPARC_M44",     false,0,0x000003ff,false),
   HOWTO(R_SPARC_L44,       0,2,13,false,0,complain_overflow_dont,    bfd_elf_generic_reloc,  "R_SPARC_L44",     false,0,0x00000fff,false),
-  HOWTO(R_SPARC_REGISTER,  0,4, 0,false,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_REGISTER",false,0,MINUS_ONE, false)
+  HOWTO(R_SPARC_REGISTER,  0,4, 0,false,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_REGISTER",false,0,MINUS_ONE, false),
+  HOWTO(R_SPARC_UA64,        0,4,64,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_UA64",      false,0,MINUS_ONE, true),
+  HOWTO(R_SPARC_UA16,        0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_UA16",      false,0,0x0000ffff,true)
 };
 
 struct elf_reloc_map {
@@ -883,6 +885,8 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs)
        case R_SPARC_H44:
        case R_SPARC_M44:
        case R_SPARC_L44:
+       case R_SPARC_UA64:
+       case R_SPARC_UA16:
          /* When creating a shared object, we must copy these relocs
             into the output file.  We create a reloc section in
             dynobj and make room for the reloc. 
@@ -1495,6 +1499,8 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                case R_SPARC_H44:
                case R_SPARC_M44:
                case R_SPARC_L44:
+               case R_SPARC_UA64:
+               case R_SPARC_UA16:
                  if (info->shared
                      && ((!info->symbolic && h->dynindx != -1)
                          || !(h->elf_link_hash_flags
@@ -1580,6 +1586,8 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            case R_SPARC_H44:
            case R_SPARC_M44:
            case R_SPARC_L44:
+           case R_SPARC_UA64:
+           case R_SPARC_UA16:
              {
                Elf_Internal_Rela outrel;
                boolean skip;
@@ -1625,6 +1633,30 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                outrel.r_offset += (input_section->output_section->vma
                                    + input_section->output_offset);
 
+               /* Optimize unaligned reloc usage now that we know where
+                  it finally resides.  */
+               switch (r_type)
+                 {
+                 case R_SPARC_16:
+                   if (outrel.r_offset & 1) r_type = R_SPARC_UA16;
+                   break;
+                 case R_SPARC_UA16:
+                   if (!(outrel.r_offset & 1)) r_type = R_SPARC_16;
+                   break;
+                 case R_SPARC_32:
+                   if (outrel.r_offset & 3) r_type = R_SPARC_UA32;
+                   break;
+                 case R_SPARC_UA32:
+                   if (!(outrel.r_offset & 3)) r_type = R_SPARC_32;
+                   break;
+                 case R_SPARC_64:
+                   if (outrel.r_offset & 7) r_type = R_SPARC_UA64;
+                   break;
+                 case R_SPARC_UA64:
+                   if (!(outrel.r_offset & 7)) r_type = R_SPARC_64;
+                   break;
+                 }
+
                if (skip)
                  memset (&outrel, 0, sizeof outrel);
                /* h->dynindx may be -1 if the symbol was marked to