OSDN Git Service

This patch adds m68k support for elf2flt -a. I've tested it with
authorGreg Ungerer <gerg@snapgear.com>
Mon, 10 Jul 2006 06:00:41 +0000 (06:00 +0000)
committerGreg Ungerer <gerg@snapgear.com>
Mon, 10 Jul 2006 06:00:41 +0000 (06:00 +0000)
load-to-RAM, -msep-data PIC-with-GOT and -mshared-library PIC-with-GOT.

Like ARM, but unlike V850, the new code errors out on relocs it doesn't
understand, rather than assuming that they're 32-bit fields.

It seems likely that every port that supports -a will want to print the
"reloc type not supported in this context" message; we've got two copies
already, and m68k would add a third.  I've therefore moved the v850
"bad_v850_reloc_err:" code outside the #ifdef and renamed the label to
the more neutral "bad_resolved_reloc:".  I've also changed the ARM code
to use this now-common code instead of its own copy.

In a similar vein, I've changed the default 32-bit field handling
so that it is the target of a new label, "good_32bit_resolved_reloc:".
The generic and v850 code can then jump to this code in their default
cases, while m68k can jump to it for R_68K_32 relocs.

The patch was written before Shaun Jackman made -p and -a work together:

    http://mailman.uclinux.org/pipermail/uclinux-dev/2006-June/039029.html

I'd been using this hunk too, but as well as guarding:

    q->address += got_size;

with "!use_resolved", I'd guarded the calculation of got_size itself,
as the value isn't otherwise used.  I've kept this additional check
in the attached patch.  Please apply if OK.

Signed-off-by: Richard Sandiford <richard@codesourcery.com>
elf2flt.c

index 2b4cb83..90718e4 100644 (file)
--- a/elf2flt.c
+++ b/elf2flt.c
@@ -425,7 +425,7 @@ dump_symbols(symbols, number_of_symbols);
    * Also note that both the relocatable and absolute versions have this
    * terminator even though the relocatable one doesn't have the GOT!
    */
-  if (pic_with_got) {
+  if (pic_with_got && !use_resolved) {
     unsigned long *lp = (unsigned long *)data;
     /* Should call ntohl(*lp) here but is isn't going to matter */
     while (*lp != 0xffffffff) lp++;
@@ -674,7 +674,7 @@ dump_symbols(symbols, number_of_symbols);
                                                                + lo;
                                                }
                                        } else
-                                               goto bad_v850_reloc_err;
+                                               goto bad_resolved_reloc;
                                        break;
 
                                case R_V850_LO16:
@@ -688,17 +688,13 @@ dump_symbols(symbols, number_of_symbols);
                                            && (p[-1]->addend == p[0]->addend))
                                                break; /* not an error */
                                        else
-                                               goto bad_v850_reloc_err;
+                                               goto bad_resolved_reloc;
 
                                case R_V850_HI16:
-                               bad_v850_reloc_err:
-                                       printf("ERROR: reloc type %s unsupported in this context\n",
-                                              q->howto->name);
-                                       bad_relocs++;
-                                       break;
-#endif /* TARGET_V850 */
-
-#if defined(TARGET_arm)
+                                       goto bad_resolved_reloc;
+                               default:
+                                       goto good_32bit_resolved_reloc;
+#elif defined(TARGET_arm)
                                case R_ARM_ABS32:
                                        relocation_needed = 1;
                                        break;
@@ -707,10 +703,20 @@ dump_symbols(symbols, number_of_symbols);
                                        relocation_needed = 0;
                                        break;
                                default:
-                                       printf("ERROR: reloc type %s unsupported in this context\n",
-                                              q->howto->name);
-                                       bad_relocs++;
-                                       break;
+                                       goto bad_resolved_reloc;
+#elif defined(TARGET_m68k)
+                               case R_68K_32:
+                                       goto good_32bit_resolved_reloc;
+                               case R_68K_PC32:
+                               case R_68K_PC16:
+                                       /* The linker has already resolved
+                                          PC relocs for us.  In PIC links,
+                                          the symbol must be in the data
+                                          segment.  */
+                               case R_68K_NONE:
+                                       continue;
+                               default:
+                                       goto bad_resolved_reloc;
 #else
                                default:
                                        /* The default is to assume that the
@@ -720,6 +726,9 @@ dump_symbols(symbols, number_of_symbols);
                                           give an error by default, and
                                           require `safe' relocations to be
                                           enumberated explicitly?).  */
+                                       goto good_32bit_resolve_reloc;
+#endif
+                               good_32bit_resolved_reloc:
                                        if (bfd_big_endian (abs_bfd))
                                                sym_addr =
                                                        (r_mem[0] << 24)
@@ -733,7 +742,13 @@ dump_symbols(symbols, number_of_symbols);
                                                        + (r_mem[2] << 16)
                                                        + (r_mem[3] << 24);
                                        relocation_needed = 1;
-#endif
+                                       break;
+
+                               bad_resolved_reloc:
+                                       printf("ERROR: reloc type %s unsupported in this context\n",
+                                              q->howto->name);
+                                       bad_relocs++;
+                                       break;
                                }
                        } else {
                                /* Calculate the sym address ourselves.  */