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>
* Also note that both the relocatable and absolute versions have this
* terminator even though the relocatable one doesn't have the GOT!
*/
* 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 && !use_resolved) {
unsigned long *lp = (unsigned long *)data;
/* Should call ntohl(*lp) here but is isn't going to matter */
while (*lp != 0xffffffff) lp++;
unsigned long *lp = (unsigned long *)data;
/* Should call ntohl(*lp) here but is isn't going to matter */
while (*lp != 0xffffffff) lp++;
- goto bad_v850_reloc_err;
+ goto bad_resolved_reloc;
&& (p[-1]->addend == p[0]->addend))
break; /* not an error */
else
&& (p[-1]->addend == p[0]->addend))
break; /* not an error */
else
- goto bad_v850_reloc_err;
+ goto bad_resolved_reloc;
- 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;
case R_ARM_ABS32:
relocation_needed = 1;
break;
relocation_needed = 0;
break;
default:
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
#else
default:
/* The default is to assume that the
give an error by default, and
require `safe' relocations to be
enumberated explicitly?). */
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)
if (bfd_big_endian (abs_bfd))
sym_addr =
(r_mem[0] << 24)
+ (r_mem[2] << 16)
+ (r_mem[3] << 24);
relocation_needed = 1;
+ (r_mem[2] << 16)
+ (r_mem[3] << 24);
relocation_needed = 1;
+ 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. */
}
} else {
/* Calculate the sym address ourselves. */