Fri Jan 3 16:58:31 1997 Richard Henderson <rth@tamu.edu>

elf64-alpha multiple .got rewrite:

	* elf-bfd.h (struct elf_backend_data): Add always_size_sections entry.
	(bfd_elf*_mkobject): Don't define here ...
	* elfxx-target.h: ... but rather here.  Default always_size_sections
	hook to NULL.
	* elf.c (elf_mkobject): Rename to bfd_elf_mkobject, since that was
	what the #defines in elf-bfd.h transmuted it to anyway.

	* section.c: Add SEC_LINKER_CREATED flag.
	* bfd-in2.h: Rebuild.
	* elf32-i386.c (elf_i386_check_relocs): Add SEC_LINKER_CREATED to
	relocation section flags.
	(elf_i386_size_dynamic_sections): Use SEC_LINKER_CREATED instead of
	SEC_IN_MEMORY to recognize generated bits.
	* elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_size_dynamic_sections):
	Likewise.
	* elf32-mips.c (mips_elf_final_link, mips_elf_create_dynamic_sections,
	mips_elf_create_compact_rel_section, mips_elf_create_got_section,
	mips_elf_check_relocs, mips_elf_size_dynamic_sections): Likewise.
	* elf32-ppc.c (ppc_elf_create_linker_section,
	ppc_elf_size_dynamic_sections): Likewise.
	* elf32-sparc.c (elf32_sparc_check_relocs,
	elf32_sparc_size_dynamic_sections): Likewise.
	* elflink.c (_bfd_elf_create_got_section): Add SEC_LINKER_CREATED to
	section flags.
	(_bfd_elf_create_dynamic_sections): Likewise.
	(_bfd_elf_make_linker_section_rela): Likewise.
	* elflink.h (elf_link_create_dynamic_sections): Likewise.
	(bfd_elf,size_dynamic_sections): Call the always_size_sections hook.
	(elf_bfd_final_link): Use SEC_LINKER_CREATED instead of SEC_IN_MEMORY
	to identify generated bits.
	(elf_link_input_bfd): Likewise.

	* elf64-alpha.c: Rewrite everything touching relocations.
This commit is contained in:
Ian Lance Taylor 1997-01-03 22:09:40 +00:00
parent 98141a3cc1
commit ff12f30335
14 changed files with 1537 additions and 923 deletions

View File

@ -1,3 +1,41 @@
Fri Jan 3 16:58:31 1997 Richard Henderson <rth@tamu.edu>
elf64-alpha multiple .got rewrite:
* elf-bfd.h (struct elf_backend_data): Add always_size_sections entry.
(bfd_elf*_mkobject): Don't define here ...
* elfxx-target.h: ... but rather here. Default always_size_sections
hook to NULL.
* elf.c (elf_mkobject): Rename to bfd_elf_mkobject, since that was
what the #defines in elf-bfd.h transmuted it to anyway.
* section.c: Add SEC_LINKER_CREATED flag.
* bfd-in2.h: Rebuild.
* elf32-i386.c (elf_i386_check_relocs): Add SEC_LINKER_CREATED to
relocation section flags.
(elf_i386_size_dynamic_sections): Use SEC_LINKER_CREATED instead of
SEC_IN_MEMORY to recognize generated bits.
* elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_size_dynamic_sections):
Likewise.
* elf32-mips.c (mips_elf_final_link, mips_elf_create_dynamic_sections,
mips_elf_create_compact_rel_section, mips_elf_create_got_section,
mips_elf_check_relocs, mips_elf_size_dynamic_sections): Likewise.
* elf32-ppc.c (ppc_elf_create_linker_section,
ppc_elf_size_dynamic_sections): Likewise.
* elf32-sparc.c (elf32_sparc_check_relocs,
elf32_sparc_size_dynamic_sections): Likewise.
* elflink.c (_bfd_elf_create_got_section): Add SEC_LINKER_CREATED to
section flags.
(_bfd_elf_create_dynamic_sections): Likewise.
(_bfd_elf_make_linker_section_rela): Likewise.
* elflink.h (elf_link_create_dynamic_sections): Likewise.
(bfd_elf,size_dynamic_sections): Call the always_size_sections hook.
(elf_bfd_final_link): Use SEC_LINKER_CREATED instead of SEC_IN_MEMORY
to identify generated bits.
(elf_link_input_bfd): Likewise.
* elf64-alpha.c: Rewrite everything touching relocations.
start-sanitize-v850
Fri Jan 3 11:42:53 1997 Michael Meissner <meissner@tiktok.cygnus.com>

View File

@ -939,6 +939,12 @@ typedef struct sec
contents. */
#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
/* This section was created by the linker as part of dynamic
relocation or other arcane processing. It is skipped when
going through the first-pass output, trusting that someone
else up the line will take care of it later. */
#define SEC_LINKER_CREATED 0x800000
/* End of section flags. */
/* Some internal packed boolean fields. */

View File

@ -360,6 +360,13 @@ struct elf_backend_data
boolean (*elf_backend_adjust_dynamic_symbol)
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
/* The ALWAYS_SIZE_SECTIONS function is called by the backend linker
after all the linker input files have been seen but before the
section sizes have been set. This is called after
ADJUST_DYNAMIC_SYMBOL, but before SIZE_DYNAMIC_SECTIONS. */
boolean (*elf_backend_always_size_sections)
PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
/* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend
linker after all the linker input files have been seen but before
the sections sizes have been set. This is called after
@ -660,9 +667,6 @@ extern void bfd_elf_print_symbol PARAMS ((bfd *, PTR, asymbol *,
#define bfd_elf32_print_symbol bfd_elf_print_symbol
#define bfd_elf64_print_symbol bfd_elf_print_symbol
#define bfd_elf32_mkobject bfd_elf_mkobject
#define bfd_elf64_mkobject bfd_elf_mkobject
#define elf_mkobject bfd_elf_mkobject
extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *));

View File

@ -103,7 +103,7 @@ elf_read (abfd, offset, size)
}
boolean
elf_mkobject (abfd)
bfd_elf_mkobject (abfd)
bfd * abfd;
{
/* this just does initialization */

View File

@ -60,6 +60,13 @@ enum reloc_type
R_386_RELATIVE,
R_386_GOTOFF,
R_386_GOTPC,
FIRST_INVALID_RELOC,
LAST_INVALID_RELOC = 19,
/* The remaining relocs are a GNU extension. */
R_386_16 = 20,
R_386_PC16,
R_386_8,
R_386_PC8,
R_386_max
};
@ -93,6 +100,20 @@ static reloc_howto_type elf_howto_table[]=
HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false),
HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false),
HOWTO(R_386_GOTPC, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,true),
{ 11 },
{ 12 },
{ 13 },
{ 14 },
{ 15 },
{ 16 },
{ 17 },
{ 18 },
{ 19 },
/* The remaining relocs are a GNU extension. */
HOWTO(R_386_16, 0,1,16,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_16", true,0xffff,0xffff,false),
HOWTO(R_386_PC16, 0,1,16,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC16", true,0xffff,0xffff,true),
HOWTO(R_386_8, 0,0,8,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_8", true,0xff,0xff,false),
HOWTO(R_386_PC8, 0,0,8,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC8", true,0xff,0xff,true),
};
#ifdef DEBUG_GEN_RELOC
@ -152,6 +173,23 @@ elf_i386_reloc_type_lookup (abfd, code)
TRACE ("BFD_RELOC_386_GOTPC");
return &elf_howto_table[ (int)R_386_GOTPC ];
/* The remaining relocs are a GNU extension. */
case BFD_RELOC_16:
TRACE ("BFD_RELOC_16");
return &elf_howto_table[(int) R_386_16];
case BFD_RELOC_16_PCREL:
TRACE ("BFD_RELOC_16_PCREL");
return &elf_howto_table[(int) R_386_PC16];
case BFD_RELOC_8:
TRACE ("BFD_RELOC_8");
return &elf_howto_table[(int) R_386_8];
case BFD_RELOC_8_PCREL:
TRACE ("BFD_RELOC_8_PCREL");
return &elf_howto_table[(int) R_386_PC8];
default:
break;
}
@ -166,20 +204,22 @@ elf_i386_info_to_howto (abfd, cache_ptr, dst)
arelent *cache_ptr;
Elf32_Internal_Rela *dst;
{
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max);
cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)];
abort ();
}
static void
elf_i386_info_to_howto_rel (abfd, cache_ptr, dst)
bfd *abfd;
arelent *cache_ptr;
bfd *abfd;
arelent *cache_ptr;
Elf32_Internal_Rel *dst;
{
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max);
enum reloc_type type;
cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)];
type = (enum reloc_type) ELF32_R_TYPE (dst->r_info);
BFD_ASSERT (type < R_386_max);
BFD_ASSERT (type < FIRST_INVALID_RELOC || type > LAST_INVALID_RELOC);
cache_ptr->howto = &elf_howto_table[(int) type];
}
/* Functions for the i386 ELF linker. */
@ -222,8 +262,8 @@ static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
{
0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
0, 0, 0, 0 /* pad out to 16 bytes. */
};
@ -307,7 +347,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
{
case R_386_GOT32:
/* This symbol requires a global offset table entry. */
if (sgot == NULL)
{
sgot = bfd_get_section_by_name (dynobj, ".got");
@ -327,6 +367,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, srelgot, 2))
return false;
@ -391,22 +432,16 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
case R_386_PLT32:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code without
linking in any dynamic objects, in which case we don't
need to generate a procedure linkage table after all. */
because this might be a case of linking PIC code which is
never referenced by a dynamic object, in which case we
don't need to generate a procedure linkage table entry
after all. */
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
if (h == NULL)
continue;
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
}
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
break;
@ -414,7 +449,6 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
case R_386_32:
case R_386_PC32:
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0
&& (ELF32_R_TYPE (rel->r_info) != R_386_PC32 || h != NULL))
{
/* When creating a shared object, we must copy these
@ -438,14 +472,15 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
sreloc = bfd_get_section_by_name (dynobj, name);
if (sreloc == NULL)
{
flagword flags;
sreloc = bfd_make_section (dynobj, name);
flags = (SEC_HAS_CONTENTS | SEC_READONLY
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
if (sreloc == NULL
|| ! bfd_set_section_flags (dynobj, sreloc,
(SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_READONLY))
|| ! bfd_set_section_flags (dynobj, sreloc, flags)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
@ -453,7 +488,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
sreloc->_raw_size += sizeof (Elf32_External_Rel);
}
break;
default:
@ -498,17 +533,26 @@ elf_i386_adjust_dynamic_symbol (info, h)
if (h->type == STT_FUNC
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
if (! elf_hash_table (info)->dynamic_sections_created)
if (! info->shared
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
{
/* This case can occur if we saw a PLT32 reloc in an input
file, but none of the input files were dynamic objects.
In such a case, we don't actually need to build a
procedure linkage table, and we can just do a PC32 reloc
instead. */
file, but the symbol was never referred to by a dynamic
object. In such a case, we don't actually need to build
a procedure linkage table, and we can just do a PC32
reloc instead. */
BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
return true;
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
}
s = bfd_get_section_by_name (dynobj, ".plt");
BFD_ASSERT (s != NULL);
@ -677,7 +721,7 @@ elf_i386_size_dynamic_sections (output_bfd, info)
const char *name;
boolean strip;
if ((s->flags & SEC_IN_MEMORY) == 0)
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
/* It's OK to base decisions on the section name, because none
@ -766,7 +810,7 @@ elf_i386_size_dynamic_sections (output_bfd, info)
if (s->contents == NULL && s->_raw_size != 0)
return false;
}
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
@ -855,7 +899,10 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_reloc_status_type r;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type < 0 || r_type >= (int) R_386_max)
if (r_type < 0
|| r_type >= (int) R_386_max
|| (r_type >= (int) FIRST_INVALID_RELOC
&& r_type <= (int) LAST_INVALID_RELOC))
{
bfd_set_error (bfd_error_bad_value);
return false;
@ -923,14 +970,21 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)
&& (r_type == R_386_32
|| r_type == R_386_PC32)
&& (input_section->flags & SEC_ALLOC) != 0))
|| r_type == R_386_PC32)))
{
/* In these cases, we don't need the relocation
value. We check specially because in some
obscure cases sec->output_section will be NULL. */
relocation = 0;
}
else if (sec->output_section == NULL)
{
(*_bfd_error_handler)
("%s: warning: unresolvable relocation against symbol `%s' from %s section",
bfd_get_filename (input_bfd), h->root.root.string,
bfd_get_section_name (input_bfd, input_section));
relocation = 0;
}
else
relocation = (h->root.u.def.value
+ sec->output_section->vma
@ -1105,7 +1159,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
case R_386_32:
case R_386_PC32:
if (info->shared
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type != R_386_PC32
|| (h != NULL
&& (! info->symbolic
@ -1327,7 +1380,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
/* This symbol has an entry in the global offset table. Set it
up. */
BFD_ASSERT (h->dynindx != -1);
sgot = bfd_get_section_by_name (dynobj, ".got");

View File

@ -187,9 +187,9 @@ reloc_type_lookup (abfd, code)
static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
{
0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
0, 0, 0, 0, /* replaced with address of .got + 4. */
0, 0, 0, 0, /* replaced with offset to .got + 4. */
0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
0, 0, 0, 0, /* replaced with address of .got + 8. */
0, 0, 0, 0, /* replaced with offset to .got + 8. */
0, 0, 0, 0 /* pad out to 20 bytes. */
};
@ -197,8 +197,8 @@ static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
{
0x4e, 0xfb, 0x01, 0x71, /* jmp ([addr]) */
0, 0, 0, 0, /* replaced with address of this symbol in .got. */
0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */
0x2f, 0x3c, /* move.l #offset,-(%sp) */
0, 0, 0, 0, /* replaced with offset into relocation table. */
0x60, 0xff, /* bra.l .plt */
@ -256,15 +256,15 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
case R_68K_GOT8:
case R_68K_GOT16:
case R_68K_GOT32:
if (h != NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
/* Fall through. */
case R_68K_GOT8O:
case R_68K_GOT16O:
case R_68K_GOT32O:
/* This symbol requires a global offset table entry. */
if (h != NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
if (dynobj == NULL)
{
/* Create the .got section. */
@ -292,6 +292,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| !bfd_set_section_alignment (dynobj, srelgot, 2))
return false;
@ -355,20 +356,35 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
case R_68K_PLT8:
case R_68K_PLT16:
case R_68K_PLT32:
case R_68K_PLT8O:
case R_68K_PLT16O:
case R_68K_PLT32O:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code without
linking in any dynamic objects, in which case we don't
need to generate a procedure linkage table after all. */
because this might be a case of linking PIC code which is
never referenced by a dynamic object, in which case we
don't need to generate a procedure linkage table entry
after all. */
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
if (h == NULL)
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
break;
case R_68K_PLT8O:
case R_68K_PLT16O:
case R_68K_PLT32O:
/* This symbol requires a procedure linkage table entry. */
if (h == NULL)
{
/* It does not make sense to have this relocation for a
local symbol. FIXME: does it? How to handle it if
it does make sense? */
bfd_set_error (bfd_error_bad_value);
return false;
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@ -389,7 +405,13 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
case R_68K_16:
case R_68K_32:
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0)
&& (sec->flags & SEC_ALLOC) != 0
&& ((ELF32_R_TYPE (rel->r_info) != R_68K_PC8
&& ELF32_R_TYPE (rel->r_info) != R_68K_PC16
&& ELF32_R_TYPE (rel->r_info) != R_68K_PC32)
|| (!info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
{
/* When creating a shared object, we must copy these
reloc types into the output file. We create a reloc
@ -419,6 +441,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| !bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
@ -472,17 +495,30 @@ elf_m68k_adjust_dynamic_symbol (info, h)
if (h->type == STT_FUNC
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
if (!elf_hash_table (info)->dynamic_sections_created)
if (! info->shared
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
/* We must always create the plt entry if it was referenced
by a PLTxxO relocation. In this case we already recorded
it as a dynamic symbol. */
&& h->dynindx == -1)
{
/* This case can occur if we saw a PLT32 reloc in an input
file, but none of the input files were dynamic objects.
In such a case, we don't actually need to build a
procedure linkage table, and we can just do a PC32 reloc
instead. */
/* This case can occur if we saw a PLTxx reloc in an input
file, but the symbol was never referred to by a dynamic
object. In such a case, we don't actually need to build
a procedure linkage table, and we can just do a PCxx
reloc instead. */
BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
return true;
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
}
s = bfd_get_section_by_name (dynobj, ".plt");
BFD_ASSERT (s != NULL);
@ -651,7 +687,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
const char *name;
boolean strip;
if ((s->flags & SEC_IN_MEMORY) == 0)
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
/* It's OK to base decisions on the section name, because none
@ -800,7 +836,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
struct elf_link_hash_entry **sym_hashes;
bfd_vma *local_got_offsets;
asection *sgot;
asection *sgotplt;
asection *splt;
asection *sreloc;
Elf_Internal_Rela *rel;
@ -812,7 +847,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
local_got_offsets = elf_local_got_offsets (input_bfd);
sgot = NULL;
sgotplt = NULL;
splt = NULL;
sreloc = NULL;
@ -941,8 +975,8 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
case R_68K_GOT8:
case R_68K_GOT16:
case R_68K_GOT32:
/* Relocation is to the entry for this symbol in the global
offset table. */
/* Relocation is to the address of the entry for this symbol
in the global offset table. */
if (h != NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
@ -953,105 +987,97 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
/* Relocation is the offset of the entry for this symbol in
the global offset table. */
if (sgot == NULL)
{
sgot = bfd_get_section_by_name (dynobj, ".got");
BFD_ASSERT (sgot != NULL);
}
{
bfd_vma off;
if (sgotplt == NULL)
{
sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
BFD_ASSERT (sgotplt != NULL);
}
if (sgot == NULL)
{
sgot = bfd_get_section_by_name (dynobj, ".got");
BFD_ASSERT (sgot != NULL);
}
if (h != NULL)
{
bfd_vma off;
if (h != NULL)
{
off = h->got_offset;
BFD_ASSERT (off != (bfd_vma) -1);
off = h->got_offset;
BFD_ASSERT (off != (bfd_vma) -1);
if (!elf_hash_table (info)->dynamic_sections_created
|| (info->shared
&& info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally. We must initialize this entry in the
global offset table. Since the offset must
always be a multiple of 4, we use the least
significant bit to record whether we have
initialized it already.
if (!elf_hash_table (info)->dynamic_sections_created
|| (info->shared
&& info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally. We must initialize this entry in the
global offset table. Since the offset must
always be a multiple of 4, we use the least
significant bit to record whether we have
initialized it already.
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
sgot->contents + off);
h->got_offset |= 1;
}
}
}
else
{
BFD_ASSERT (local_got_offsets != NULL
&& local_got_offsets[r_symndx] != (bfd_vma) -1);
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
sgot->contents + off);
h->got_offset |= 1;
}
}
off = local_got_offsets[r_symndx];
relocation = sgot->output_offset + off;
if (r_type == R_68K_GOT8O
|| r_type == R_68K_GOT16O
|| r_type == R_68K_GOT32O)
relocation -= sgotplt->output_offset;
}
else
{
bfd_vma off;
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation, sgot->contents + off);
BFD_ASSERT (local_got_offsets != NULL
&& local_got_offsets[r_symndx] != (bfd_vma) -1);
if (info->shared)
{
asection *srelgot;
Elf_Internal_Rela outrel;
off = local_got_offsets[r_symndx];
srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation, sgot->contents + off);
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
outrel.r_addend = relocation;
bfd_elf32_swap_reloca_out (output_bfd, &outrel,
(((Elf32_External_Rela *)
srelgot->contents)
+ srelgot->reloc_count));
++srelgot->reloc_count;
}
if (info->shared)
{
asection *srelgot;
Elf_Internal_Rela outrel;
srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
outrel.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &outrel,
(((Elf32_External_Rela *)
srelgot->contents)
+ srelgot->reloc_count));
++srelgot->reloc_count;
}
local_got_offsets[r_symndx] |= 1;
}
relocation = sgot->output_offset + off;
if (r_type == R_68K_GOT8O
|| r_type == R_68K_GOT16O
|| r_type == R_68K_GOT32O)
relocation -= sgotplt->output_offset;
}
local_got_offsets[r_symndx] |= 1;
}
}
relocation = sgot->output_offset + off;
if (r_type == R_68K_GOT8O
|| r_type == R_68K_GOT16O
|| r_type == R_68K_GOT32O)
{
/* This relocation does not use the addend. */
rel->r_addend = 0;
}
else
relocation += sgot->output_section->vma;
}
break;
case R_68K_PLT8:
@ -1060,7 +1086,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
/* Resolve a PLT32 reloc against a local symbol directly,
/* Resolve a PLTxx reloc against a local symbol directly,
without using the procedure linkage table. */
if (h == NULL)
break;
@ -1089,14 +1115,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
case R_68K_PLT32O:
/* Relocation is the offset of the entry for this symbol in
the procedure linkage table. */
BFD_ASSERT (h != NULL);
if (h->plt_offset == (bfd_vma) -1)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code. */
break;
}
BFD_ASSERT (h != NULL && h->plt_offset == (bfd_vma) -1);
if (splt == NULL)
{
@ -1105,6 +1124,10 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
}
relocation = h->plt_offset;
/* This relocation does not use the addend. */
rel->r_addend = 0;
break;
case R_68K_PC8:
@ -1117,9 +1140,16 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
case R_68K_16:
case R_68K_32:
if (info->shared
&& (input_section->flags & SEC_ALLOC) != 0)
&& (input_section->flags & SEC_ALLOC) != 0
&& ((r_type != R_68K_PC8
&& r_type != R_68K_PC16
&& r_type != R_68K_PC32)
|| (!info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
{
Elf_Internal_Rela outrel;
int relocate;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
@ -1154,13 +1184,15 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
& ELF_LINK_HASH_DEF_REGULAR) == 0))
{
BFD_ASSERT (h->dynindx != -1);
relocate = false;
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
outrel.r_addend = rel->r_addend;
outrel.r_addend = relocation + rel->r_addend;
}
else
{
if (r_type == R_68K_32)
{
relocate = true;
outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
outrel.r_addend = relocation + rel->r_addend;
}
@ -1194,6 +1226,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
abort ();
}
relocate = false;
outrel.r_info = ELF32_R_INFO (indx, r_type);
outrel.r_addend = relocation + rel->r_addend;
}
@ -1206,8 +1239,11 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
++sreloc->reloc_count;
/* This reloc will be computed at runtime, so there's no
need to do anything now. */
continue;
need to do anything now, except for R_68K_32
relocations that have been turned into
R_68K_RELATIVE. */
if (!relocate)
continue;
}
break;
@ -1351,7 +1387,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
/* This symbol has an entry in the global offset table. Set it
up. */
BFD_ASSERT (h->dynindx != -1);
sgot = bfd_get_section_by_name (dynobj, ".got");
@ -1369,14 +1405,19 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
if (info->shared
&& info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
{
rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
rela.r_addend = bfd_get_32 (output_bfd,
sgot->contents + (h->got_offset & ~1));
}
else
{
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
bfd_put_32 (output_bfd, (bfd_vma) 0,
sgot->contents + (h->got_offset & ~1));
rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
rela.r_addend = 0;
}
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela,
((Elf32_External_Rela *) srela->contents
+ srela->reloc_count));
@ -1480,17 +1521,13 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
break;
case DT_RELASZ:
/* My reading of the SVR4 ABI indicates that the
procedure linkage table relocs (DT_JMPREL) should be
included in the overall relocs (DT_RELA). This is
what Solaris does. However, UnixWare can not handle
that case. Therefore, we override the DT_RELASZ entry
here to make it not include the JMPREL relocs. Since
the linker script arranges for .rela.plt to follow all
/* The procedure linkage table relocs (DT_JMPREL) should
not be included in the overall relocs (DT_RELA).
Therefore, we override the DT_RELASZ entry here to
make it not include the JMPREL relocs. Since the
linker script arranges for .rela.plt to follow all
other relocation sections, we don't have to worry
about changing the DT_RELA entry. */
/* FIXME: This comment is from elf32-i386.c, what about
the SVR4/m68k implementations? */
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
if (s != NULL)
{

View File

@ -2415,7 +2415,7 @@ static asymbol mips_elf_scom_symbol;
static asymbol *mips_elf_scom_symbol_ptr;
/* MIPS ELF also uses an acommon section, which represents an
allocated common symbol which may be overridden by a
allocated common symbol which may be overridden by a
definition in a shared library. */
static asection mips_elf_acom_section;
static asymbol mips_elf_acom_symbol;
@ -2581,7 +2581,7 @@ mips_elf_modify_segment_map (abfd)
*pm = m;
}
}
/* 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
@ -3307,7 +3307,7 @@ mips_elf_output_extsym (h, data)
else
{
name = bfd_section_name (output_section->owner, output_section);
if (strcmp (name, ".text") == 0)
h->esym.asym.sc = scText;
else if (strcmp (name, ".data") == 0)
@ -3373,7 +3373,7 @@ mips_elf_output_extsym (h, data)
#if 0 /* FIXME? */
h->esym.ifd = 0;
#endif
}
}
if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
h->root.root.root.string,
@ -3768,7 +3768,7 @@ mips_elf_final_link (abfd, info)
}
else
esym.asym.value = last;
if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
name[i], &esym))
return false;
@ -3886,7 +3886,7 @@ mips_elf_final_link (abfd, info)
if (rtproc_sec == NULL)
{
flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_READONLY);
| SEC_LINKER_CREATED | SEC_READONLY);
rtproc_sec = bfd_make_section (abfd, ".rtproc");
if (rtproc_sec == NULL
@ -5043,7 +5043,7 @@ mips_elf_create_dynamic_sections (abfd, info)
const char * const *namep;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_READONLY);
| SEC_LINKER_CREATED | SEC_READONLY);
/* Mips ABI requests the .dynamic section to be read only. */
s = bfd_get_section_by_name (abfd, ".dynamic");
@ -5175,7 +5175,8 @@ mips_elf_create_compact_rel_section (abfd, info)
if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
{
flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY;
flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED
| SEC_READONLY);
s = bfd_make_section (abfd, ".compact_rel");
if (s == NULL
@ -5188,7 +5189,7 @@ mips_elf_create_compact_rel_section (abfd, info)
return true;
}
/* Create the .got section to hold the global offset table. */
static boolean
@ -5205,7 +5206,8 @@ mips_elf_create_got_section (abfd, info)
if (bfd_get_section_by_name (abfd, ".got") != NULL)
return true;
flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
s = bfd_make_section (abfd, ".got");
if (s == NULL
@ -5436,6 +5438,7 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, sreloc,
4))
@ -5661,7 +5664,7 @@ mips_elf_size_dynamic_sections (output_bfd, info)
of the dynobj section names depend upon the input files. */
name = bfd_get_section_name (dynobj, s);
if ((s->flags & SEC_IN_MEMORY) == 0)
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
strip = false;
@ -6226,7 +6229,7 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
time ((time_t *) &dyn.d_un.d_val);
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_MIPS_ICHECKSUM:
/* XXX FIXME: */
break;
@ -6398,7 +6401,7 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
+ sizeof (Elf32_External_compact_rel));
cpt.reserved0 = 0;
cpt.reserved1 = 0;
bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
((Elf32_External_compact_rel *)
s->contents));

View File

@ -1290,7 +1290,8 @@ ppc_elf_create_linker_section (abfd, info, which)
defaults.which = which;
defaults.hole_written_p = false;
defaults.alignment = 2;
defaults.flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
switch (which)
{
@ -1648,7 +1649,7 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
const char *name;
boolean strip;
if ((s->flags & SEC_IN_MEMORY) == 0)
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
/* It's OK to base decisions on the section name, because none
@ -2067,6 +2068,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
{

View File

@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static reloc_howto_type *elf32_sparc_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
static void elf_info_to_howto
static void elf32_sparc_info_to_howto
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
static boolean elf32_sparc_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
@ -64,7 +64,7 @@ static bfd_reloc_status_type sparc_elf_notsupported_reloc
static bfd_reloc_status_type sparc_elf_wdisp16_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
reloc_howto_type _bfd_sparc_elf_howto_table[] =
reloc_howto_type _bfd_sparc_elf_howto_table[] =
{
HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true),
@ -126,7 +126,7 @@ reloc_howto_type _bfd_sparc_elf_howto_table[] =
#endif
HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true),
HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true),
HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true),
HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_JMP",false,0,0x00000000,true),
HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true),
HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true),
HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true),
@ -202,7 +202,7 @@ elf32_sparc_reloc_type_lookup (abfd, code)
and elf64-sparc.c has its own copy. */
static void
elf_info_to_howto (abfd, cache_ptr, dst)
elf32_sparc_info_to_howto (abfd, cache_ptr, dst)
bfd *abfd;
arelent *cache_ptr;
Elf_Internal_Rela *dst;
@ -394,6 +394,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, srelgot, 2))
return false;
@ -512,8 +513,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
case R_SPARC_13:
case R_SPARC_LO10:
case R_SPARC_UA32:
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0)
if (info->shared)
{
/* When creating a shared object, we must copy these
relocs into the output file. We create a reloc
@ -536,14 +536,15 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
sreloc = bfd_get_section_by_name (dynobj, name);
if (sreloc == NULL)
{
flagword flags;
sreloc = bfd_make_section (dynobj, name);
flags = (SEC_HAS_CONTENTS | SEC_READONLY
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
if (sreloc == NULL
|| ! bfd_set_section_flags (dynobj, sreloc,
(SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_READONLY))
|| ! bfd_set_section_flags (dynobj, sreloc, flags)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
@ -778,7 +779,7 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
const char *name;
boolean strip;
if ((s->flags & SEC_IN_MEMORY) == 0)
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
/* It's OK to base decisions on the section name, because none
@ -1043,7 +1044,6 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
&& (! info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type == R_SPARC_8
|| r_type == R_SPARC_16
|| r_type == R_SPARC_32
@ -1232,8 +1232,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
case R_SPARC_13:
case R_SPARC_LO10:
case R_SPARC_UA32:
if (info->shared
&& (input_section->flags & SEC_ALLOC) != 0)
if (info->shared)
{
Elf_Internal_Rela outrel;
@ -1328,7 +1327,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
default:
break;
}
}
if (r_type != R_SPARC_WDISP16)
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
@ -1673,10 +1672,8 @@ elf32_sparc_merge_private_bfd_data (ibfd, obfd)
{
boolean error;
/* This function is selected based on the input vector. We only
want to copy information over if the output BFD also uses Elf
format. */
if (bfd_get_flavour (obfd) != bfd_target_elf_flavour)
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return true;
error = false;
@ -1784,6 +1781,7 @@ elf32_sparc_final_write_processing (abfd, linker)
#define ELF_MAXPAGESIZE 0x10000
#define bfd_elf32_bfd_reloc_type_lookup elf32_sparc_reloc_type_lookup
#define elf_info_to_howto elf32_sparc_info_to_howto
#define elf_backend_create_dynamic_sections \
_bfd_elf_create_dynamic_sections
#define elf_backend_check_relocs elf32_sparc_check_relocs

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,8 @@ _bfd_elf_create_got_section (abfd, info)
if (bfd_get_section_by_name (abfd, ".got") != NULL)
return true;
flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
s = bfd_make_section (abfd, ".got");
if (s == NULL
@ -72,6 +73,8 @@ _bfd_elf_create_got_section (abfd, info)
&& ! _bfd_elf_link_record_dynamic_symbol (info, h))
return false;
elf_hash_table (info)->hgot = h;
/* The first three global offset table entries are reserved. */
s->_raw_size += 3 * 4;
@ -93,7 +96,8 @@ _bfd_elf_create_dynamic_sections (abfd, info)
/* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
.rel[a].bss sections. */
flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
s = bfd_make_section (abfd, ".plt");
if (s == NULL
@ -226,7 +230,6 @@ _bfd_elf_create_linker_section (abfd, info, which, defaults)
if (!lsect)
{
asection *s;
static elf_linker_section_t zero_section;
lsect = (elf_linker_section_t *)
bfd_alloc (dynobj, sizeof (elf_linker_section_t));
@ -238,9 +241,9 @@ _bfd_elf_create_linker_section (abfd, info, which, defaults)
/* See if the sections already exist */
lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
if (!s)
if (!s || (s->flags & defaults->flags) != defaults->flags)
{
lsect->section = s = bfd_make_section (dynobj, lsect->name);
lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
if (s == NULL)
return (elf_linker_section_t *)0;
@ -284,21 +287,28 @@ _bfd_elf_create_linker_section (abfd, info, which, defaults)
lsect->sym_name,
lsect->name);
#endif
if (!(_bfd_generic_link_add_one_symbol (info,
abfd,
lsect->sym_name,
BSF_GLOBAL,
s,
((lsect->hole_size)
? s->_raw_size - lsect->hole_size + lsect->sym_offset
: lsect->sym_offset),
(const char *) NULL,
false,
get_elf_backend_data (abfd)->collect,
(struct bfd_link_hash_entry **) &h)))
h = (struct elf_link_hash_entry *)
bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);
if ((h == NULL || h->root.type == bfd_link_hash_undefined)
&& !(_bfd_generic_link_add_one_symbol (info,
abfd,
lsect->sym_name,
BSF_GLOBAL,
s,
((lsect->hole_size)
? s->_raw_size - lsect->hole_size + lsect->sym_offset
: lsect->sym_offset),
(const char *) NULL,
false,
get_elf_backend_data (abfd)->collect,
(struct bfd_link_hash_entry **) &h)))
return (elf_linker_section_t *)0;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
if ((defaults->which != LINKER_SECTION_SDATA)
&& (defaults->which != LINKER_SECTION_SDATA2))
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
h->type = STT_OBJECT;
lsect->sym_hash = h;
@ -359,6 +369,7 @@ _bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
return false;
@ -366,4 +377,3 @@ _bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
return true;
}

View File

@ -35,7 +35,7 @@ struct elf_info_failed
{
boolean failed;
struct bfd_link_info *info;
};
};
/* Given an ELF BFD, add symbols to the global hash table as
appropriate. */
@ -281,7 +281,7 @@ elf_link_add_object_symbols (abfd, info)
goto error_return;
if (! (_bfd_generic_link_add_one_symbol
(info, abfd,
(info, abfd,
name + sizeof ".gnu.warning." - 1,
BSF_WARNING, s, (bfd_vma) 0, msg, false, collect,
(struct bfd_link_hash_entry **) NULL)))
@ -1051,7 +1051,8 @@ elf_link_create_dynamic_sections (abfd, info)
/* Note that we set the SEC_IN_MEMORY flag for all of these
sections. */
flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
/* A dynamically linked executable has a .interp section, but a
shared library does not. */
@ -1257,7 +1258,7 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs,
/* Cache the results for next time, if we can. */
if (keep_memory)
elf_section_data (o)->relocs = internal_relocs;
if (alloc1 != NULL)
free (alloc1);
@ -1371,6 +1372,13 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (info->hash->creator->flavour != bfd_target_elf_flavour)
return true;
/* The backend may have to create some sections regardless of whether
we're dynamic or not. */
bed = get_elf_backend_data (output_bfd);
if (bed->elf_backend_always_size_sections
&& ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
return false;
dynobj = elf_hash_table (info)->dynobj;
/* If there were no dynamic objects in the link, there is nothing to
@ -1410,7 +1418,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (indx == (bfd_size_type) -1
|| ! elf_add_dynamic_entry (info, DT_SONAME, indx))
return false;
}
}
if (info->symbolic)
{
@ -1494,7 +1502,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
/* The backend must work out the sizes of all the other dynamic
sections. */
bed = get_elf_backend_data (output_bfd);
if (! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
return false;
@ -1805,7 +1812,7 @@ struct elf_finfo_failed
{
boolean failed;
struct elf_final_link_info *finfo;
};
};
/* Do the final step of an ELF link. */
@ -2221,7 +2228,7 @@ elf_bfd_final_link (abfd, info)
{
if (*rel_hash == NULL)
continue;
BFD_ASSERT ((*rel_hash)->indx >= 0);
if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
@ -2375,11 +2382,10 @@ elf_bfd_final_link (abfd, info)
if ((o->flags & SEC_HAS_CONTENTS) == 0
|| o->_raw_size == 0)
continue;
if ((o->flags & SEC_IN_MEMORY) == 0)
if ((o->flags & SEC_LINKER_CREATED) == 0)
{
/* At this point, we are only interested in sections
created by elf_link_create_dynamic_sections. FIXME:
This test is fragile. */
created by elf_link_create_dynamic_sections. */
continue;
}
if ((elf_section_data (o->output_section)->this_hdr.sh_type
@ -2927,11 +2933,10 @@ elf_link_input_bfd (finfo, input_bfd)
|| (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
continue;
if ((o->flags & SEC_IN_MEMORY) != 0
&& input_bfd == elf_hash_table (finfo->info)->dynobj)
if ((o->flags & SEC_LINKER_CREATED) != 0)
{
/* Section was created by elf_link_create_dynamic_sections.
FIXME: This test is fragile. */
/* Section was created by elf_link_create_dynamic_sections
or somesuch. */
continue;
}

View File

@ -154,6 +154,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define bfd_elfNN_write_archive_contents _bfd_write_archive_contents
#endif
#ifndef bfd_elfNN_mkobject
#define bfd_elfNN_mkobject bfd_elf_mkobject
#endif
#ifndef bfd_elfNN_mkarchive
#define bfd_elfNN_mkarchive _bfd_generic_mkarchive
#endif
@ -220,6 +224,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef elf_backend_adjust_dynamic_symbol
#define elf_backend_adjust_dynamic_symbol 0
#endif
#ifndef elf_backend_always_size_sections
#define elf_backend_always_size_sections 0
#endif
#ifndef elf_backend_size_dynamic_sections
#define elf_backend_size_dynamic_sections 0
#endif
@ -289,6 +296,7 @@ static CONST struct elf_backend_data elfNN_bed =
elf_backend_create_dynamic_sections,
elf_backend_check_relocs,
elf_backend_adjust_dynamic_symbol,
elf_backend_always_size_sections,
elf_backend_size_dynamic_sections,
elf_backend_relocate_section,
elf_backend_finish_dynamic_symbol,
@ -324,7 +332,7 @@ const bfd_target TARGET_BIG_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES),
@ -363,7 +371,7 @@ const bfd_target TARGET_BIG_SYM =
/* bfd_set_format: set the format of a file being written */
{ bfd_false,
bfd_elf_mkobject,
bfd_elfNN_mkobject,
bfd_elfNN_mkarchive,
bfd_false
},
@ -412,7 +420,7 @@ const bfd_target TARGET_LITTLE_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES),
@ -451,7 +459,7 @@ const bfd_target TARGET_LITTLE_SYM =
/* bfd_set_format: set the format of a file being written */
{ bfd_false,
bfd_elf_mkobject,
bfd_elfNN_mkobject,
bfd_elfNN_mkarchive,
bfd_false
},

View File

@ -240,7 +240,7 @@ CODE_FRAGMENT
. sections. *}
.#define SEC_COFF_SHARED_LIBRARY 0x800
.
. {* The section is a common section (symbols may be defined
. {* The section contains common symbols (symbols may be defined
. multiple times, the value of a symbol is the amount of
. space it requires, and the largest symbol value is the one
. used). Most targets have exactly one of these (which we
@ -269,6 +269,40 @@ CODE_FRAGMENT
. table. *}
.#define SEC_SORT_ENTRIES 0x80000
.
. {* When linking, duplicate sections of the same name should be
. discarded, rather than being combined into a single section as
. is usually done. This is similar to how common symbols are
. handled. See SEC_LINK_DUPLICATES below. *}
.#define SEC_LINK_ONCE 0x100000
.
. {* If SEC_LINK_ONCE is set, this bitfield describes how the linker
. should handle duplicate sections. *}
.#define SEC_LINK_DUPLICATES 0x600000
.
. {* This value for SEC_LINK_DUPLICATES means that duplicate
. sections with the same name should simply be discarded. *}
.#define SEC_LINK_DUPLICATES_DISCARD 0x0
.
. {* This value for SEC_LINK_DUPLICATES means that the linker
. should warn if there are any duplicate sections, although
. it should still only link one copy. *}
.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
.
. {* This value for SEC_LINK_DUPLICATES means that the linker
. should warn if any duplicate sections are a different size. *}
.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
.
. {* This value for SEC_LINK_DUPLICATES means that the linker
. should warn if any duplicate sections contain different
. contents. *}
.#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
.
. {* This section was created by the linker as part of dynamic
. relocation or other arcane processing. It is skipped when
. going through the first-pass output, trusting that someone
. else up the line will take care of it later. *}
.#define SEC_LINKER_CREATED 0x800000
.
. {* End of section flags. *}
.
. {* Some internal packed boolean fields. *}
@ -982,6 +1016,6 @@ DESCRIPTION
Not enough memory exists to create private data for @var{osec}.
.#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
. BFD_SEND (ibfd, _bfd_copy_private_section_data, \
. BFD_SEND (obfd, _bfd_copy_private_section_data, \
. (ibfd, isection, obfd, osection))
*/