mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-18 23:13:46 +00:00
bfd/
* elf32-spu.h (spu_elf_params): Add member emit_fixups. (spu_elf_size_sections): Declare prototype. * elf32-spu.c (spu_link_hash_table): Add member sfixup. (FIXUP_RECORD_SIZE, FIXUP_GET, FIXUP_PUT): New macros. (spu_elf_emit_fixup): New function. (spu_elf_relocate_section): Emit fixup for each SPU_ADDR32. (spu_elf_size_sections): New function. ld/ * emulparams/elf32_spu.sh (OTHER_READONLY_SECTIONS): Add .fixup section and __fixup_start symbol. * emultempl/spuelf.em (params): Initialize emit_fixups member. (spu_before_allocation): Call spu_elf_size_sections. (OPTION_SPU_EMIT_FIXUPS): Define. (PARSE_AND_LIST_LONGOPTS): Add --emit-fixups. (PARSE_AND_LIST_ARGS_CASES): Handle --emit-fixups. * ld.texinfo (--emit-fixups): Document. ld/testsuite/ * ld-spu/fixup.d: New. * ld-spu/fixup.s: New.
This commit is contained in:
parent
99e008fef7
commit
9cc305ec20
@ -1,3 +1,13 @@
|
||||
2009-08-05 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
|
||||
|
||||
* elf32-spu.h (spu_elf_params): Add member emit_fixups.
|
||||
(spu_elf_size_sections): Declare prototype.
|
||||
* elf32-spu.c (spu_link_hash_table): Add member sfixup.
|
||||
(FIXUP_RECORD_SIZE, FIXUP_GET, FIXUP_PUT): New macros.
|
||||
(spu_elf_emit_fixup): New function.
|
||||
(spu_elf_relocate_section): Emit fixup for each SPU_ADDR32.
|
||||
(spu_elf_size_sections): New function.
|
||||
|
||||
2009-08-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_stub_type): Add arm_stub_a8_veneer_lwm.
|
||||
|
135
bfd/elf32-spu.c
135
bfd/elf32-spu.c
@ -344,6 +344,9 @@ struct spu_link_hash_table
|
||||
/* Count of overlay stubs needed in non-overlay area. */
|
||||
unsigned int non_ovly_stub;
|
||||
|
||||
/* Pointer to the fixup section */
|
||||
asection *sfixup;
|
||||
|
||||
/* Set on error. */
|
||||
unsigned int stub_err : 1;
|
||||
};
|
||||
@ -558,6 +561,7 @@ get_sym_h (struct elf_link_hash_entry **hp,
|
||||
bfd_boolean
|
||||
spu_elf_create_sections (struct bfd_link_info *info)
|
||||
{
|
||||
struct spu_link_hash_table *htab = spu_hash_table (info);
|
||||
bfd *ibfd;
|
||||
|
||||
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||
@ -600,6 +604,19 @@ spu_elf_create_sections (struct bfd_link_info *info)
|
||||
s->contents = data;
|
||||
}
|
||||
|
||||
if (htab->params->emit_fixups)
|
||||
{
|
||||
asection *s;
|
||||
flagword flags;
|
||||
ibfd = info->input_bfds;
|
||||
flags = SEC_LOAD | SEC_ALLOC | SEC_READONLY | SEC_HAS_CONTENTS
|
||||
| SEC_IN_MEMORY;
|
||||
s = bfd_make_section_anyway_with_flags (ibfd, ".fixup", flags);
|
||||
if (s == NULL || !bfd_set_section_alignment (ibfd, s, 2))
|
||||
return FALSE;
|
||||
htab->sfixup = s;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -4718,6 +4735,48 @@ spu_elf_count_relocs (struct bfd_link_info *info, asection *sec)
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Functions for adding fixup records to .fixup */
|
||||
|
||||
#define FIXUP_RECORD_SIZE 4
|
||||
|
||||
#define FIXUP_PUT(output_bfd,htab,index,addr) \
|
||||
bfd_put_32 (output_bfd, addr, \
|
||||
htab->sfixup->contents + FIXUP_RECORD_SIZE * (index))
|
||||
#define FIXUP_GET(output_bfd,htab,index) \
|
||||
bfd_get_32 (output_bfd, \
|
||||
htab->sfixup->contents + FIXUP_RECORD_SIZE * (index))
|
||||
|
||||
/* Store OFFSET in .fixup. This assumes it will be called with an
|
||||
increasing OFFSET. When this OFFSET fits with the last base offset,
|
||||
it just sets a bit, otherwise it adds a new fixup record. */
|
||||
static void
|
||||
spu_elf_emit_fixup (bfd * output_bfd, struct bfd_link_info *info,
|
||||
bfd_vma offset)
|
||||
{
|
||||
struct spu_link_hash_table *htab = spu_hash_table (info);
|
||||
asection *sfixup = htab->sfixup;
|
||||
bfd_vma qaddr = offset & ~(bfd_vma) 15;
|
||||
bfd_vma bit = ((bfd_vma) 8) >> ((offset & 15) >> 2);
|
||||
if (sfixup->reloc_count == 0)
|
||||
{
|
||||
FIXUP_PUT (output_bfd, htab, 0, qaddr | bit);
|
||||
sfixup->reloc_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma base = FIXUP_GET (output_bfd, htab, sfixup->reloc_count - 1);
|
||||
if (qaddr != (base & ~(bfd_vma) 15))
|
||||
{
|
||||
if ((sfixup->reloc_count + 1) * FIXUP_RECORD_SIZE > sfixup->size)
|
||||
(*_bfd_error_handler) (_("fatal error while creating .fixup"));
|
||||
FIXUP_PUT (output_bfd, htab, sfixup->reloc_count, qaddr | bit);
|
||||
sfixup->reloc_count++;
|
||||
}
|
||||
else
|
||||
FIXUP_PUT (output_bfd, htab, sfixup->reloc_count - 1, base | bit);
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
|
||||
|
||||
static int
|
||||
@ -4910,6 +4969,16 @@ spu_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
if (htab->params->emit_fixups && !info->relocatable
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
&& r_type == R_SPU_ADDR32)
|
||||
{
|
||||
bfd_vma offset;
|
||||
offset = rel->r_offset + input_section->output_section->vma
|
||||
+ input_section->output_offset;
|
||||
spu_elf_emit_fixup (output_bfd, info, offset);
|
||||
}
|
||||
|
||||
if (unresolved_reloc)
|
||||
;
|
||||
else if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
|
||||
@ -5305,6 +5374,72 @@ spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
spu_elf_size_sections (bfd * output_bfd, struct bfd_link_info *info)
|
||||
{
|
||||
struct spu_link_hash_table *htab = spu_hash_table (info);
|
||||
if (htab->params->emit_fixups)
|
||||
{
|
||||
asection *sfixup = htab->sfixup;
|
||||
int fixup_count = 0;
|
||||
bfd *ibfd;
|
||||
size_t size;
|
||||
|
||||
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||
{
|
||||
asection *isec;
|
||||
|
||||
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
|
||||
continue;
|
||||
|
||||
/* Walk over each section attached to the input bfd. */
|
||||
for (isec = ibfd->sections; isec != NULL; isec = isec->next)
|
||||
{
|
||||
Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
|
||||
bfd_vma base_end;
|
||||
|
||||
/* If there aren't any relocs, then there's nothing more
|
||||
to do. */
|
||||
if ((isec->flags & SEC_RELOC) == 0
|
||||
|| isec->reloc_count == 0)
|
||||
continue;
|
||||
|
||||
/* Get the relocs. */
|
||||
internal_relocs =
|
||||
_bfd_elf_link_read_relocs (ibfd, isec, NULL, NULL,
|
||||
info->keep_memory);
|
||||
if (internal_relocs == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* 1 quadword can contain up to 4 R_SPU_ADDR32
|
||||
relocations. They are stored in a single word by
|
||||
saving the upper 28 bits of the address and setting the
|
||||
lower 4 bits to a bit mask of the words that have the
|
||||
relocation. BASE_END keeps track of the next quadword. */
|
||||
irela = internal_relocs;
|
||||
irelaend = irela + isec->reloc_count;
|
||||
base_end = 0;
|
||||
for (; irela < irelaend; irela++)
|
||||
if (ELF32_R_TYPE (irela->r_info) == R_SPU_ADDR32
|
||||
&& irela->r_offset >= base_end)
|
||||
{
|
||||
base_end = (irela->r_offset & ~(bfd_vma) 15) + 16;
|
||||
fixup_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We always have a NULL fixup as a sentinel */
|
||||
size = (fixup_count + 1) * FIXUP_RECORD_SIZE;
|
||||
if (!bfd_set_section_size (output_bfd, sfixup, size))
|
||||
return FALSE;
|
||||
sfixup->contents = (bfd_byte *) bfd_zalloc (info->input_bfds, size);
|
||||
if (sfixup->contents == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define TARGET_BIG_SYM bfd_elf32_spu_vec
|
||||
#define TARGET_BIG_NAME "elf32-spu"
|
||||
#define ELF_ARCH bfd_arch_spu
|
||||
|
@ -57,6 +57,9 @@ struct spu_elf_params
|
||||
/* Set if non-icache code should be allowed in icache lines. */
|
||||
unsigned int non_ia_text : 1;
|
||||
|
||||
/* Set when the .fixup section should be generated. */
|
||||
unsigned int emit_fixups : 1;
|
||||
|
||||
/* Range of valid addresses for loadable sections. */
|
||||
bfd_vma local_store_lo;
|
||||
bfd_vma local_store_hi;
|
||||
@ -114,6 +117,7 @@ extern void spu_elf_plugin (int);
|
||||
extern bfd_boolean spu_elf_open_builtin_lib (bfd **,
|
||||
const struct _ovl_stream *);
|
||||
extern bfd_boolean spu_elf_create_sections (struct bfd_link_info *);
|
||||
extern bfd_boolean spu_elf_size_sections (bfd *, struct bfd_link_info *);
|
||||
extern int spu_elf_find_overlays (struct bfd_link_info *);
|
||||
extern int spu_elf_size_stubs (struct bfd_link_info *);
|
||||
extern void spu_elf_place_overlay_data (struct bfd_link_info *);
|
||||
|
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
||||
2009-08-05 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
|
||||
|
||||
* emulparams/elf32_spu.sh (OTHER_READONLY_SECTIONS): Add .fixup
|
||||
section and __fixup_start symbol.
|
||||
* emultempl/spuelf.em (params): Initialize emit_fixups member.
|
||||
(spu_before_allocation): Call spu_elf_size_sections.
|
||||
(OPTION_SPU_EMIT_FIXUPS): Define.
|
||||
(PARSE_AND_LIST_LONGOPTS): Add --emit-fixups.
|
||||
(PARSE_AND_LIST_ARGS_CASES): Handle --emit-fixups.
|
||||
* ld.texinfo (--emit-fixups): Document.
|
||||
|
||||
2009-08-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR 10474
|
||||
|
@ -20,3 +20,8 @@ DATA_ADDR="ALIGN(${MAXPAGESIZE})"
|
||||
OTHER_BSS_SECTIONS=".toe ALIGN(128) : { *(.toe) } = 0"
|
||||
OTHER_SECTIONS=".note.spu_name 0 : { KEEP(*(.note.spu_name)) }
|
||||
._ea 0 : { KEEP(*(._ea)) KEEP(*(._ea.*)) }"
|
||||
OTHER_READONLY_SECTIONS="
|
||||
.fixup ${RELOCATING-0} : {
|
||||
PROVIDE (__fixup_start = .);
|
||||
KEEP(*(.fixup))
|
||||
}"
|
||||
|
@ -37,7 +37,7 @@ static struct spu_elf_params params =
|
||||
&spu_elf_load_ovl_mgr,
|
||||
&spu_elf_open_overlay_script,
|
||||
&spu_elf_relink,
|
||||
0, ovly_normal, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, ovly_normal, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0x3ffff,
|
||||
1, 0, 16, 0, 0, 2000
|
||||
};
|
||||
@ -316,6 +316,10 @@ spu_before_allocation (void)
|
||||
lang_reset_memory_regions ();
|
||||
}
|
||||
|
||||
if (is_spu_target ()
|
||||
&& !link_info.relocatable)
|
||||
spu_elf_size_sections (link_info.output_bfd, &link_info);
|
||||
|
||||
gld${EMULATION_NAME}_before_allocation ();
|
||||
}
|
||||
|
||||
@ -600,6 +604,7 @@ PARSE_AND_LIST_PROLOGUE='
|
||||
#define OPTION_SPU_RESERVED_SPACE (OPTION_SPU_FIXED_SPACE + 1)
|
||||
#define OPTION_SPU_EXTRA_STACK (OPTION_SPU_RESERVED_SPACE + 1)
|
||||
#define OPTION_SPU_NO_AUTO_OVERLAY (OPTION_SPU_EXTRA_STACK + 1)
|
||||
#define OPTION_SPU_EMIT_FIXUPS (OPTION_SPU_NO_AUTO_OVERLAY + 1)
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_LONGOPTS='
|
||||
@ -625,6 +630,7 @@ PARSE_AND_LIST_LONGOPTS='
|
||||
{ "reserved-space", required_argument, NULL, OPTION_SPU_RESERVED_SPACE },
|
||||
{ "extra-stack-space", required_argument, NULL, OPTION_SPU_EXTRA_STACK },
|
||||
{ "no-auto-overlay", optional_argument, NULL, OPTION_SPU_NO_AUTO_OVERLAY },
|
||||
{ "emit-fixups", optional_argument, NULL, OPTION_SPU_EMIT_FIXUPS },
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_OPTIONS='
|
||||
@ -812,6 +818,10 @@ PARSE_AND_LIST_ARGS_CASES='
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTION_SPU_EMIT_FIXUPS:
|
||||
params.emit_fixups = 1;
|
||||
break;
|
||||
'
|
||||
|
||||
LDEMUL_AFTER_OPEN=spu_after_open
|
||||
|
@ -1,3 +1,8 @@
|
||||
2009-08-05 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
|
||||
|
||||
* ld-spu/fixup.d: New.
|
||||
* ld-spu/fixup.s: New.
|
||||
|
||||
2009-08-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* ld-arm/cortex-a8-far-1.s: New.
|
||||
|
20
ld/testsuite/ld-spu/fixup.d
Normal file
20
ld/testsuite/ld-spu/fixup.d
Normal file
@ -0,0 +1,20 @@
|
||||
#source: fixup.s
|
||||
#ld: --emit-fixups
|
||||
#objdump: -s
|
||||
|
||||
.*elf32-spu
|
||||
|
||||
Contents of section .text:
|
||||
0000 00000000 ....
|
||||
Contents of section .fixup:
|
||||
0004 0000008b 00000091 000000c1 00000000 ................
|
||||
Contents of section .data:
|
||||
0080 000000d0 00000000 00000000 000000c0 ................
|
||||
0090 00000000 00000000 00000000 000000b0 ................
|
||||
00a0 00000001 00000000 00000000 00000000 ................
|
||||
00b0 00000002 00000000 00000000 00000000 ................
|
||||
00c0 00000000 00000000 00000000 00000080 ................
|
||||
Contents of section .note.spu_name:
|
||||
.*
|
||||
.*
|
||||
#pass
|
24
ld/testsuite/ld-spu/fixup.s
Normal file
24
ld/testsuite/ld-spu/fixup.s
Normal file
@ -0,0 +1,24 @@
|
||||
.global _end
|
||||
.global _start
|
||||
.global glob
|
||||
.global after
|
||||
.global before
|
||||
.weak undef
|
||||
|
||||
.section .text,"ax"
|
||||
_start:
|
||||
stop
|
||||
|
||||
|
||||
.data
|
||||
.p2align 4
|
||||
before:
|
||||
.long _end, 0, _start, after
|
||||
.long 0, 0, 0, glob
|
||||
loc:
|
||||
.long 1,0,0,0
|
||||
glob:
|
||||
.long 2,0,0,0
|
||||
after:
|
||||
.long 0, 0, 0, before
|
||||
|
Loading…
x
Reference in New Issue
Block a user