bfd/
* elf-bfd.h (eh_cie_fde): Remove need_lsda_relative. Move make_lsda_relative to u.cie. * elf-eh-frame.c (cie): Rename make_lsda_relative to can_make_lsda_relative. (_bfd_elf_parse_eh_frame): Don't set the old eh_cie_fde make_lsda_relative field. Update after cie renaming. Set u.cie.make_lsda_relative if can_make_lsda_relative and if we find a relocation against the LSDA. (_bfd_elf_discard_section_eh_frame): Copy make_lsda_relative when changing a CIE's group representative. (_bfd_elf_eh_frame_section_offset): Don't set need_ldsa_relative here. (_bfd_elf_write_section_eh_frame): Check u.cie.make_lsda_relative rather than need_lsda_relative.
This commit is contained in:
parent
9d0a14d3f3
commit
9f4b847e23
|
@ -1,3 +1,19 @@
|
||||||
|
2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||||
|
|
||||||
|
* elf-bfd.h (eh_cie_fde): Remove need_lsda_relative.
|
||||||
|
Move make_lsda_relative to u.cie.
|
||||||
|
* elf-eh-frame.c (cie): Rename make_lsda_relative to
|
||||||
|
can_make_lsda_relative.
|
||||||
|
(_bfd_elf_parse_eh_frame): Don't set the old eh_cie_fde
|
||||||
|
make_lsda_relative field. Update after cie renaming.
|
||||||
|
Set u.cie.make_lsda_relative if can_make_lsda_relative
|
||||||
|
and if we find a relocation against the LSDA.
|
||||||
|
(_bfd_elf_discard_section_eh_frame): Copy make_lsda_relative when
|
||||||
|
changing a CIE's group representative.
|
||||||
|
(_bfd_elf_eh_frame_section_offset): Don't set need_ldsa_relative here.
|
||||||
|
(_bfd_elf_write_section_eh_frame): Check u.cie.make_lsda_relative
|
||||||
|
rather than need_lsda_relative.
|
||||||
|
|
||||||
2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
|
2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||||
|
|
||||||
* elf-bfd.h (eh_cie_fde): Add u.fde.next_for_section and
|
* elf-bfd.h (eh_cie_fde): Add u.fde.next_for_section and
|
||||||
|
|
|
@ -285,6 +285,11 @@ struct eh_cie_fde
|
||||||
|
|
||||||
/* True if we have marked relocations associated with this CIE. */
|
/* True if we have marked relocations associated with this CIE. */
|
||||||
unsigned int gc_mark : 1;
|
unsigned int gc_mark : 1;
|
||||||
|
|
||||||
|
/* True if we have decided to turn an absolute LSDA encoding into
|
||||||
|
a PC-relative one. It is the group representative's setting
|
||||||
|
that matters. */
|
||||||
|
unsigned int make_lsda_relative : 1;
|
||||||
} cie;
|
} cie;
|
||||||
} u;
|
} u;
|
||||||
unsigned int reloc_index;
|
unsigned int reloc_index;
|
||||||
|
@ -299,8 +304,6 @@ struct eh_cie_fde
|
||||||
unsigned int add_augmentation_size : 1;
|
unsigned int add_augmentation_size : 1;
|
||||||
unsigned int add_fde_encoding : 1;
|
unsigned int add_fde_encoding : 1;
|
||||||
unsigned int make_relative : 1;
|
unsigned int make_relative : 1;
|
||||||
unsigned int make_lsda_relative : 1;
|
|
||||||
unsigned int need_lsda_relative : 1;
|
|
||||||
unsigned int per_encoding_relative : 1;
|
unsigned int per_encoding_relative : 1;
|
||||||
unsigned int *set_loc;
|
unsigned int *set_loc;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct cie
|
||||||
unsigned char fde_encoding;
|
unsigned char fde_encoding;
|
||||||
unsigned char initial_insn_length;
|
unsigned char initial_insn_length;
|
||||||
unsigned char make_relative;
|
unsigned char make_relative;
|
||||||
unsigned char make_lsda_relative;
|
unsigned char can_make_lsda_relative;
|
||||||
unsigned char initial_instructions[50];
|
unsigned char initial_instructions[50];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -799,7 +799,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||||
->elf_backend_can_make_lsda_relative_eh_frame
|
->elf_backend_can_make_lsda_relative_eh_frame
|
||||||
(abfd, info, sec))
|
(abfd, info, sec))
|
||||||
&& (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
|
&& (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
|
||||||
cie->make_lsda_relative = 1;
|
cie->can_make_lsda_relative = 1;
|
||||||
|
|
||||||
/* If FDE encoding was not specified, it defaults to
|
/* If FDE encoding was not specified, it defaults to
|
||||||
DW_EH_absptr. */
|
DW_EH_absptr. */
|
||||||
|
@ -817,7 +817,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||||
ENSURE_NO_RELOCS (buf);
|
ENSURE_NO_RELOCS (buf);
|
||||||
|
|
||||||
this_inf->make_relative = cie->make_relative;
|
this_inf->make_relative = cie->make_relative;
|
||||||
this_inf->make_lsda_relative = cie->make_lsda_relative;
|
|
||||||
this_inf->per_encoding_relative
|
this_inf->per_encoding_relative
|
||||||
= (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
|
= (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
|
||||||
}
|
}
|
||||||
|
@ -862,6 +861,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||||
be adjusted if any future augmentations do the same thing. */
|
be adjusted if any future augmentations do the same thing. */
|
||||||
if (cie->lsda_encoding != DW_EH_PE_omit)
|
if (cie->lsda_encoding != DW_EH_PE_omit)
|
||||||
{
|
{
|
||||||
|
SKIP_RELOCS (buf);
|
||||||
|
if (cie->can_make_lsda_relative && GET_RELOC (buf))
|
||||||
|
cie->cie_inf->u.cie.make_lsda_relative = 1;
|
||||||
this_inf->lsda_offset = buf - start;
|
this_inf->lsda_offset = buf - start;
|
||||||
/* If there's no 'z' augmentation, we don't know where the
|
/* If there's no 'z' augmentation, we don't know where the
|
||||||
CFA insns begin. Assume no padding. */
|
CFA insns begin. Assume no padding. */
|
||||||
|
@ -1097,6 +1099,8 @@ _bfd_elf_discard_section_eh_frame
|
||||||
/* Make the local CIE represent the merged group. */
|
/* Make the local CIE represent the merged group. */
|
||||||
merged->u.cie.merged = cie;
|
merged->u.cie.merged = cie;
|
||||||
cie->removed = 0;
|
cie->removed = 0;
|
||||||
|
cie->u.cie.make_lsda_relative
|
||||||
|
= merged->u.cie.make_lsda_relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,15 +1252,10 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
/* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
|
/* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
|
||||||
for run-time relocation against LSDA field. */
|
for run-time relocation against LSDA field. */
|
||||||
if (!sec_info->entry[mid].cie
|
if (!sec_info->entry[mid].cie
|
||||||
&& sec_info->entry[mid].u.fde.cie_inf->make_lsda_relative
|
&& sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
|
||||||
&& (offset == (sec_info->entry[mid].offset + 8
|
&& offset == (sec_info->entry[mid].offset + 8
|
||||||
+ sec_info->entry[mid].lsda_offset))
|
+ sec_info->entry[mid].lsda_offset))
|
||||||
&& (sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative
|
return (bfd_vma) -2;
|
||||||
|| !hdr_info->offsets_adjusted))
|
|
||||||
{
|
|
||||||
sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative = 1;
|
|
||||||
return (bfd_vma) -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If converting to DW_EH_PE_pcrel, there will be no need for run-time
|
/* If converting to DW_EH_PE_pcrel, there will be no need for run-time
|
||||||
relocation against DW_CFA_set_loc's arguments. */
|
relocation against DW_CFA_set_loc's arguments. */
|
||||||
|
@ -1394,7 +1393,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
{
|
{
|
||||||
/* CIE */
|
/* CIE */
|
||||||
if (ent->make_relative
|
if (ent->make_relative
|
||||||
|| ent->need_lsda_relative
|
|| ent->u.cie.make_lsda_relative
|
||||||
|| ent->per_encoding_relative)
|
|| ent->per_encoding_relative)
|
||||||
{
|
{
|
||||||
char *aug;
|
char *aug;
|
||||||
|
@ -1404,7 +1403,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
/* Need to find 'R' or 'L' augmentation's argument and modify
|
/* Need to find 'R' or 'L' augmentation's argument and modify
|
||||||
DW_EH_PE_* value. */
|
DW_EH_PE_* value. */
|
||||||
action = ((ent->make_relative ? 1 : 0)
|
action = ((ent->make_relative ? 1 : 0)
|
||||||
| (ent->need_lsda_relative ? 2 : 0)
|
| (ent->u.cie.make_lsda_relative ? 2 : 0)
|
||||||
| (ent->per_encoding_relative ? 4 : 0));
|
| (ent->per_encoding_relative ? 4 : 0));
|
||||||
extra_string = extra_augmentation_string_bytes (ent);
|
extra_string = extra_augmentation_string_bytes (ent);
|
||||||
extra_data = extra_augmentation_data_bytes (ent);
|
extra_data = extra_augmentation_data_bytes (ent);
|
||||||
|
@ -1548,7 +1547,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
|
if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
|
||||||
|| cie->need_lsda_relative)
|
|| cie->u.cie.make_lsda_relative)
|
||||||
{
|
{
|
||||||
buf += ent->lsda_offset;
|
buf += ent->lsda_offset;
|
||||||
width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
|
width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
|
||||||
|
@ -1558,7 +1557,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
{
|
{
|
||||||
if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
|
if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
|
||||||
value += ent->offset - ent->new_offset;
|
value += ent->offset - ent->new_offset;
|
||||||
else if (cie->need_lsda_relative)
|
else if (cie->u.cie.make_lsda_relative)
|
||||||
value -= (sec->output_section->vma + ent->new_offset + 8
|
value -= (sec->output_section->vma + ent->new_offset + 8
|
||||||
+ ent->lsda_offset);
|
+ ent->lsda_offset);
|
||||||
write_value (abfd, buf, value, width);
|
write_value (abfd, buf, value, width);
|
||||||
|
|
Loading…
Reference in New Issue