* aoutx.h (aout_link_check_ar_symbols): When changing a symbol to

common, set the alignment.
	(aout_link_add_symbols): Restrict the alignment of a common symbol
	to the alignment power given by the architecture.
	* elf.c (_bfd_elf_link_hash_newfunc): Don't initialize align.  Do
	initialize copy_offset.
	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Use copy_offset
	field rather than align field.  Get alignment using bfd_log2
	rather than switch.
	* elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
	* elf32-i386.c (elf_i386_finish_dynamic_symbol): Use copy_offset,
	not align.
	* elf32-sparc.c (elf32_sparc_finish_dynamic_symbol): Likewise.
This commit is contained in:
Ian Lance Taylor 1994-07-22 18:53:23 +00:00
parent 36c6e8c37f
commit 7c6da9cade
5 changed files with 55 additions and 100 deletions

View File

@ -197,7 +197,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
flags |= SEC_READONLY;
if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
flags |= SEC_CODE;
else if ((flags & SEC_ALLOC) != 0)
else if ((flags & SEC_LOAD) != 0)
flags |= SEC_DATA;
/* The debugging sections appear to be recognized only by name, not
@ -331,10 +331,10 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
/* Set local fields. */
ret->indx = -1;
ret->size = 0;
ret->align = 0;
ret->dynindx = -1;
ret->dynstr_index = 0;
ret->weakdef = NULL;
ret->copy_offset = 0;
ret->type = STT_NOTYPE;
ret->elf_link_hash_flags = 0;
}
@ -383,3 +383,15 @@ _bfd_elf_link_hash_table_create (abfd)
return &ret->root;
}
/* This is a hook for the ELF emulation code in the generic linker to
tell the backend linker what file name to use for the DT_NEEDED
entry for a dynamic object. */
void
bfd_elf_set_dt_needed_name (abfd, name)
bfd *abfd;
const char *name;
{
elf_dt_needed_name (abfd) = name;
}

View File

@ -39,7 +39,7 @@ static boolean elf_i386_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf_i386_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **, char *));
static boolean elf_i386_finish_dynamic_symbol
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
Elf_Internal_Sym *));
@ -306,7 +306,6 @@ elf_i386_adjust_dynamic_symbol (info, h)
bfd *dynobj;
asection *s;
unsigned int power_of_two;
size_t align;
dynobj = elf_hash_table (info)->dynobj;
@ -365,7 +364,7 @@ elf_i386_adjust_dynamic_symbol (info, h)
BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
h->align = (bfd_size_type) -1;
h->copy_offset = (bfd_vma) -1;
return true;
}
@ -389,55 +388,28 @@ elf_i386_adjust_dynamic_symbol (info, h)
R_386_COPY reloc to tell the dynamic linker to copy the initial
value out of the dynamic object and into the runtime process
image. We need to remember the offset into the .rel.bss section
we are going to use, and we coopt the align field for this
purpose (the align field is only used for common symbols, and
these symbols are always defined). It would be cleaner to use a
new field, but that would waste memory. */
we are going to use. */
if ((h->root.u.def.section->flags & SEC_LOAD) == 0)
h->align = (bfd_size_type) -1;
h->copy_offset = (bfd_vma) -1;
else
{
asection *srel;
srel = bfd_get_section_by_name (dynobj, ".rel.bss");
BFD_ASSERT (srel != NULL);
h->align = srel->_raw_size;
h->copy_offset = srel->_raw_size;
srel->_raw_size += sizeof (Elf32_External_Rel);
}
/* We need to figure out the alignment required for this symbol. I
have no idea how ELF linkers handle this. */
switch (h->size)
{
case 0:
case 1:
power_of_two = 0;
align = 1;
break;
case 2:
power_of_two = 1;
align = 2;
break;
case 3:
case 4:
power_of_two = 2;
align = 4;
break;
case 5:
case 6:
case 7:
case 8:
power_of_two = 3;
align = 8;
break;
default:
power_of_two = 4;
align = 16;
break;
}
power_of_two = bfd_log2 (h->size);
if (power_of_two > 3)
power_of_two = 3;
/* Apply the required alignment. */
s->_raw_size = BFD_ALIGN (s->_raw_size, align);
s->_raw_size = BFD_ALIGN (s->_raw_size,
(bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (dynobj, s))
{
if (! bfd_set_section_alignment (dynobj, s, power_of_two))
@ -556,7 +528,8 @@ elf_i386_size_dynamic_sections (output_bfd, info)
static boolean
elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
contents, relocs, local_syms, local_sections,
output_names)
bfd *output_bfd;
struct bfd_link_info *info;
bfd *input_bfd;
@ -565,6 +538,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
Elf_Internal_Rela *relocs;
Elf_Internal_Sym *local_syms;
asection **local_sections;
char *output_names;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Rela *rel;
@ -674,9 +648,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
name = h->root.root.string;
else
{
name = elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
sym->st_name);
name = output_names + sym->st_name;
if (name == NULL)
return false;
if (*name == '\0')
@ -792,7 +764,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
/* This is not a function. We have already allocated memory for
it in the .bss section (via .dynbss). All we have to do here
is create a COPY reloc if required. */
if (h->align != (bfd_size_type) -1)
if (h->copy_offset != (bfd_vma) -1)
{
asection *s;
Elf_Internal_Rel rel;
@ -807,7 +779,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
bfd_elf32_swap_reloc_out (output_bfd, &rel,
((Elf32_External_Rel *)
(s->contents + h->align)));
(s->contents + h->copy_offset)));
}
}

View File

@ -37,7 +37,7 @@ static boolean elf32_sparc_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf32_sparc_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **, char *));
static boolean elf32_sparc_finish_dynamic_symbol
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
Elf_Internal_Sym *));
@ -294,7 +294,6 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
bfd *dynobj;
asection *s;
unsigned int power_of_two;
size_t align;
dynobj = elf_hash_table (info)->dynobj;
@ -349,7 +348,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
h->align = (bfd_size_type) -1;
h->copy_offset = (bfd_vma) -1;
return true;
}
@ -373,55 +372,28 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
R_SPARC_COPY reloc to tell the dynamic linker to copy the initial
value out of the dynamic object and into the runtime process
image. We need to remember the offset into the .rel.bss section
we are going to use, and we coopt the align field for this
purpose (the align field is only used for common symbols, and
these symbols are always defined). It would be cleaner to use a
new field, but that would waste memory. */
we are going to use. */
if ((h->root.u.def.section->flags & SEC_LOAD) == 0)
h->align = (bfd_size_type) -1;
h->copy_offset = (bfd_vma) -1;
else
{
asection *srel;
srel = bfd_get_section_by_name (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
h->align = srel->_raw_size;
h->copy_offset = srel->_raw_size;
srel->_raw_size += sizeof (Elf32_External_Rela);
}
/* We need to figure out the alignment required for this symbol. I
have no idea how ELF linkers handle this. */
switch (h->size)
{
case 0:
case 1:
power_of_two = 0;
align = 1;
break;
case 2:
power_of_two = 1;
align = 2;
break;
case 3:
case 4:
power_of_two = 2;
align = 4;
break;
case 5:
case 6:
case 7:
case 8:
power_of_two = 3;
align = 8;
break;
default:
power_of_two = 4;
align = 16;
break;
}
power_of_two = bfd_log2 (h->size);
if (power_of_two > 3)
power_of_two = 3;
/* Apply the required alignment. */
s->_raw_size = BFD_ALIGN (s->_raw_size, align);
s->_raw_size = BFD_ALIGN (s->_raw_size,
(bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (dynobj, s))
{
if (! bfd_set_section_alignment (dynobj, s, power_of_two))
@ -517,7 +489,8 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
static boolean
elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
contents, relocs, local_syms, local_sections,
output_names)
bfd *output_bfd;
struct bfd_link_info *info;
bfd *input_bfd;
@ -526,6 +499,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
Elf_Internal_Rela *relocs;
Elf_Internal_Sym *local_syms;
asection **local_sections;
char *output_names;
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
@ -633,9 +607,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
name = h->root.root.string;
else
{
name = elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
sym->st_name);
name = output_names + sym->st_name;
if (name == NULL)
return false;
if (*name == '\0')
@ -724,7 +696,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
/* This is not a function. We have already allocated memory for
it in the .bss section (via .dynbss). All we have to do here
is create a COPY reloc if required. */
if (h->align != (bfd_size_type) -1)
if (h->copy_offset != (bfd_vma) -1)
{
asection *s;
Elf_Internal_Rela rela;
@ -740,7 +712,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela,
((Elf32_External_Rela *)
(s->contents + h->align)));
(s->contents + h->copy_offset)));
}
}

View File

@ -4334,6 +4334,10 @@ elf_link_add_object_symbols (abfd, info)
weaks = *sym_hash;
}
if (sym.st_shndx == SHN_COMMON
&& h->root.type == bfd_link_hash_common)
h->root.u.c.alignment_power = bfd_log2 (sym.st_value);
if (info->hash->creator->flavour == bfd_target_elf_flavour)
{
int old_flags;
@ -4347,9 +4351,6 @@ elf_link_add_object_symbols (abfd, info)
the symbol size changes. */
h->size = sym.st_size;
}
if (sym.st_shndx == SHN_COMMON
&& sym.st_value > h->align)
h->align = sym.st_value;
if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE)
{
/* FIXME: We should probably somehow give a warning if
@ -5701,10 +5702,7 @@ elf_link_output_extsym (h, data)
case bfd_link_hash_common:
input_sec = bfd_com_section_ptr;
sym.st_shndx = SHN_COMMON;
if (h->align == 0)
sym.st_value = 1;
else
sym.st_value = h->align;
sym.st_value = 1 << h->root.u.c.alignment_power;
break;
case bfd_link_hash_indirect:

View File

@ -77,9 +77,6 @@ struct elf_link_hash_entry
/* Symbol size. */
bfd_size_type size;
/* Symbol alignment (common symbols only). */
bfd_size_type align;
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
-1 if this is not a dynamic symbol. */
long dynindx;
@ -92,6 +89,10 @@ struct elf_link_hash_entry
one. Otherwise it is NULL. */
struct elf_link_hash_entry *weakdef;
/* If we need to generate a COPY reloc, the processor specific
backend uses this to hold the offset into the reloc section. */
bfd_vma copy_offset;
/* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
char type;