mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
Move microblaze relax info to target specific data
Target specific data shouldn't be put in struct bfd_section. * section.c (struct bfd_section): Delete relax and relax_count. (BFD_FAKE_SECTION): Adjust to suit. (struct relax_table): Move to.. * elf32-microblaze.c (struct relax_table): ..here. (struct _microblaze_elf_section_data): New. (microblaze_elf_section_data): Define. (microblaze_elf_new_section_hook): New function. (bfd_elf32_new_section_hook): Define. (calc_fixup): Return a size_t. Adjust to suit new location of relax and relax_count. (microblaze_elf_relax_section): Adjust to suit new location of relax and relax_count. Make some variables size_t. * bfd-in2.h: Regenerate.
This commit is contained in:
parent
924cf858c9
commit
9751574e09
@ -1070,13 +1070,6 @@ typedef struct bfd_section
|
||||
/* The compressed size of the section in octets. */
|
||||
bfd_size_type compressed_size;
|
||||
|
||||
/* Relaxation table. */
|
||||
struct relax_table *relax;
|
||||
|
||||
/* Count of used relaxation table entries. */
|
||||
int relax_count;
|
||||
|
||||
|
||||
/* If this section is going to be output, then this value is the
|
||||
offset in *bytes* into the output section of the first byte in the
|
||||
input section (byte ==> smallest addressable unit on the
|
||||
@ -1177,17 +1170,6 @@ typedef struct bfd_section
|
||||
|
||||
} asection;
|
||||
|
||||
/* Relax table contains information about instructions which can
|
||||
be removed by relaxation -- replacing a long address with a
|
||||
short address. */
|
||||
struct relax_table {
|
||||
/* Address where bytes may be deleted. */
|
||||
bfd_vma addr;
|
||||
|
||||
/* Number of bytes to be deleted. */
|
||||
int size;
|
||||
};
|
||||
|
||||
static inline const char *
|
||||
bfd_section_name (const asection *sec)
|
||||
{
|
||||
@ -1336,8 +1318,8 @@ discarded_section (const asection *sec)
|
||||
/* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
|
||||
0, 0, 0, 0, 0, 0, \
|
||||
\
|
||||
/* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \
|
||||
0, 0, 0, 0, 0, 0, 0, \
|
||||
/* vma, lma, size, rawsize, compressed_size, */ \
|
||||
0, 0, 0, 0, 0, \
|
||||
\
|
||||
/* output_offset, output_section, alignment_power, */ \
|
||||
0, &SEC, 0, \
|
||||
|
@ -697,6 +697,47 @@ microblaze_elf_info_to_howto (bfd * abfd,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Relax table contains information about instructions which can
|
||||
be removed by relaxation -- replacing a long address with a
|
||||
short address. */
|
||||
struct relax_table
|
||||
{
|
||||
/* Address where bytes may be deleted. */
|
||||
bfd_vma addr;
|
||||
|
||||
/* Number of bytes to be deleted. */
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct _microblaze_elf_section_data
|
||||
{
|
||||
struct bfd_elf_section_data elf;
|
||||
/* Count of used relaxation table entries. */
|
||||
size_t relax_count;
|
||||
/* Relaxation table. */
|
||||
struct relax_table *relax;
|
||||
};
|
||||
|
||||
#define microblaze_elf_section_data(sec) \
|
||||
((struct _microblaze_elf_section_data *) elf_section_data (sec))
|
||||
|
||||
static bool
|
||||
microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
|
||||
{
|
||||
if (!sec->used_by_bfd)
|
||||
{
|
||||
struct _microblaze_elf_section_data *sdata;
|
||||
size_t amt = sizeof (*sdata);
|
||||
|
||||
sdata = bfd_zalloc (abfd, amt);
|
||||
if (sdata == NULL)
|
||||
return false;
|
||||
sec->used_by_bfd = sdata;
|
||||
}
|
||||
|
||||
return _bfd_elf_new_section_hook (abfd, sec);
|
||||
}
|
||||
|
||||
/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
|
||||
|
||||
static bool
|
||||
@ -1647,23 +1688,24 @@ microblaze_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
/* Calculate fixup value for reference. */
|
||||
|
||||
static int
|
||||
static size_t
|
||||
calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
|
||||
{
|
||||
bfd_vma end = start + size;
|
||||
int i, fixup = 0;
|
||||
size_t i, fixup = 0;
|
||||
struct _microblaze_elf_section_data *sdata;
|
||||
|
||||
if (sec == NULL || sec->relax == NULL)
|
||||
if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Look for addr in relax table, total fixup value. */
|
||||
for (i = 0; i < sec->relax_count; i++)
|
||||
for (i = 0; i < sdata->relax_count; i++)
|
||||
{
|
||||
if (end <= sec->relax[i].addr)
|
||||
if (end <= sdata->relax[i].addr)
|
||||
break;
|
||||
if ((end != start) && (start > sec->relax[i].addr))
|
||||
if (end != start && start > sdata->relax[i].addr)
|
||||
continue;
|
||||
fixup += sec->relax[i].size;
|
||||
fixup += sdata->relax[i].size;
|
||||
}
|
||||
return fixup;
|
||||
}
|
||||
@ -1712,14 +1754,15 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
bfd_byte *free_contents = NULL;
|
||||
int rel_count;
|
||||
unsigned int shndx;
|
||||
int i, sym_index;
|
||||
size_t i, sym_index;
|
||||
asection *o;
|
||||
struct elf_link_hash_entry *sym_hash;
|
||||
Elf_Internal_Sym *isymbuf, *isymend;
|
||||
Elf_Internal_Sym *isym;
|
||||
int symcount;
|
||||
int offset;
|
||||
size_t symcount;
|
||||
size_t offset;
|
||||
bfd_vma src, dest;
|
||||
struct _microblaze_elf_section_data *sdata;
|
||||
|
||||
/* We only do this once per section. We may be able to delete some code
|
||||
by running multiple passes, but it is not worth it. */
|
||||
@ -1728,8 +1771,9 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
/* Only do this for a text section. */
|
||||
if (bfd_link_relocatable (link_info)
|
||||
|| (sec->flags & SEC_RELOC) == 0
|
||||
|| (sec->reloc_count == 0)
|
||||
|| (sec->flags & SEC_CODE) == 0)
|
||||
|| (sec->flags & SEC_CODE) == 0
|
||||
|| sec->reloc_count == 0
|
||||
|| (sdata = microblaze_elf_section_data (sec)) == NULL)
|
||||
return true;
|
||||
|
||||
BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
|
||||
@ -1754,11 +1798,11 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
if (! link_info->keep_memory)
|
||||
free_relocs = internal_relocs;
|
||||
|
||||
sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
|
||||
* sizeof (struct relax_table));
|
||||
if (sec->relax == NULL)
|
||||
sdata->relax_count = 0;
|
||||
sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
|
||||
* sizeof (*sdata->relax));
|
||||
if (sdata->relax == NULL)
|
||||
goto error_return;
|
||||
sec->relax_count = 0;
|
||||
|
||||
irelend = internal_relocs + sec->reloc_count;
|
||||
rel_count = 0;
|
||||
@ -1848,9 +1892,9 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
|| (symval & 0xffff8000) == 0xffff8000)
|
||||
{
|
||||
/* We can delete this instruction. */
|
||||
sec->relax[sec->relax_count].addr = irel->r_offset;
|
||||
sec->relax[sec->relax_count].size = INST_WORD_SIZE;
|
||||
sec->relax_count++;
|
||||
sdata->relax[sdata->relax_count].addr = irel->r_offset;
|
||||
sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
|
||||
sdata->relax_count++;
|
||||
|
||||
/* Rewrite relocation type. */
|
||||
switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
|
||||
@ -1875,11 +1919,11 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
} /* Loop through all relocations. */
|
||||
|
||||
/* Loop through the relocs again, and see if anything needs to change. */
|
||||
if (sec->relax_count > 0)
|
||||
if (sdata->relax_count > 0)
|
||||
{
|
||||
shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
|
||||
rel_count = 0;
|
||||
sec->relax[sec->relax_count].addr = sec->size;
|
||||
sdata->relax[sdata->relax_count].addr = sec->size;
|
||||
|
||||
for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
|
||||
{
|
||||
@ -1913,7 +1957,7 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
{
|
||||
/* This was a PC-relative instruction that was
|
||||
completely resolved. */
|
||||
int sfix, efix;
|
||||
size_t sfix, efix;
|
||||
bfd_vma target_address;
|
||||
target_address = irel->r_addend + irel->r_offset;
|
||||
sfix = calc_fixup (irel->r_offset, 0, sec);
|
||||
@ -1928,7 +1972,7 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
{
|
||||
/* This was a PC-relative 64-bit instruction that was
|
||||
completely resolved. */
|
||||
int sfix, efix;
|
||||
size_t sfix, efix;
|
||||
bfd_vma target_address;
|
||||
target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
|
||||
sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
|
||||
@ -2195,15 +2239,16 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
}
|
||||
|
||||
/* Physically move the code and change the cooked size. */
|
||||
dest = sec->relax[0].addr;
|
||||
for (i = 0; i < sec->relax_count; i++)
|
||||
dest = sdata->relax[0].addr;
|
||||
for (i = 0; i < sdata->relax_count; i++)
|
||||
{
|
||||
int len;
|
||||
src = sec->relax[i].addr + sec->relax[i].size;
|
||||
len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
|
||||
size_t len;
|
||||
src = sdata->relax[i].addr + sdata->relax[i].size;
|
||||
len = (sdata->relax[i+1].addr - sdata->relax[i].addr
|
||||
- sdata->relax[i].size);
|
||||
|
||||
memmove (contents + dest, contents + src, len);
|
||||
sec->size -= sec->relax[i].size;
|
||||
sec->size -= sdata->relax[i].size;
|
||||
dest += len;
|
||||
}
|
||||
|
||||
@ -2229,11 +2274,11 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
free_contents = NULL;
|
||||
}
|
||||
|
||||
if (sec->relax_count == 0)
|
||||
if (sdata->relax_count == 0)
|
||||
{
|
||||
*again = false;
|
||||
free (sec->relax);
|
||||
sec->relax = NULL;
|
||||
free (sdata->relax);
|
||||
sdata->relax = NULL;
|
||||
}
|
||||
else
|
||||
*again = true;
|
||||
@ -2242,9 +2287,9 @@ microblaze_elf_relax_section (bfd *abfd,
|
||||
error_return:
|
||||
free (free_relocs);
|
||||
free (free_contents);
|
||||
free (sec->relax);
|
||||
sec->relax = NULL;
|
||||
sec->relax_count = 0;
|
||||
free (sdata->relax);
|
||||
sdata->relax = NULL;
|
||||
sdata->relax_count = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3409,6 +3454,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
|
||||
|
||||
#define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
|
||||
#define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
|
||||
#define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
|
||||
#define elf_backend_relocate_section microblaze_elf_relocate_section
|
||||
#define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
|
||||
|
@ -455,13 +455,6 @@ CODE_FRAGMENT
|
||||
. {* The compressed size of the section in octets. *}
|
||||
. bfd_size_type compressed_size;
|
||||
.
|
||||
. {* Relaxation table. *}
|
||||
. struct relax_table *relax;
|
||||
.
|
||||
. {* Count of used relaxation table entries. *}
|
||||
. int relax_count;
|
||||
.
|
||||
.
|
||||
. {* If this section is going to be output, then this value is the
|
||||
. offset in *bytes* into the output section of the first byte in the
|
||||
. input section (byte ==> smallest addressable unit on the
|
||||
@ -562,17 +555,6 @@ CODE_FRAGMENT
|
||||
.
|
||||
.} asection;
|
||||
.
|
||||
.{* Relax table contains information about instructions which can
|
||||
. be removed by relaxation -- replacing a long address with a
|
||||
. short address. *}
|
||||
.struct relax_table {
|
||||
. {* Address where bytes may be deleted. *}
|
||||
. bfd_vma addr;
|
||||
.
|
||||
. {* Number of bytes to be deleted. *}
|
||||
. int size;
|
||||
.};
|
||||
.
|
||||
.static inline const char *
|
||||
.bfd_section_name (const asection *sec)
|
||||
.{
|
||||
@ -721,8 +703,8 @@ CODE_FRAGMENT
|
||||
. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \
|
||||
. 0, 0, 0, 0, 0, 0, \
|
||||
. \
|
||||
. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
|
||||
. 0, 0, 0, 0, 0, 0, 0, \
|
||||
. {* vma, lma, size, rawsize, compressed_size, *} \
|
||||
. 0, 0, 0, 0, 0, \
|
||||
. \
|
||||
. {* output_offset, output_section, alignment_power, *} \
|
||||
. 0, &SEC, 0, \
|
||||
|
Loading…
Reference in New Issue
Block a user