mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
* config/tc-dvp.h (ELF_TC_SPECIAL_SECTIONS): Add .vuoverlay_table.
(dvp_frob_file): Declare. (tc_frob_file): Define. (VUOVERLAY_SECTION_PREFIX,VUOVERLAY_TABLE_SECTION_NAME): New macros. * config/tc-dvp.c (VUOVERLAY_START_PREFIX): New macro. (vuoverlay_section_name,create_vuoverlay_section): New functions. (vuoverlay_section,vuoverlay_table_section): New static globals. (ovlysym_table): New static global. (md_begin): Create .vuoverlay_table section. (assemble_vif): Call create_vuoverlay_section for each mpg. (dvp_frob_label): Record vu labels in ovlysym_table for later movement from absolute section to their overlay section. (dvp_frob_file): New function. (md_apply_fix3): For 8/16/32/64 bit relocs, only process if fx_done.
This commit is contained in:
@ -1,3 +1,22 @@
|
||||
start-sanitize-sky
|
||||
Thu May 28 16:23:08 1998 Doug Evans <devans@canuck.cygnus.com>
|
||||
|
||||
* config/tc-dvp.h (ELF_TC_SPECIAL_SECTIONS): Add .vuoverlay_table.
|
||||
(dvp_frob_file): Declare.
|
||||
(tc_frob_file): Define.
|
||||
(VUOVERLAY_SECTION_PREFIX,VUOVERLAY_TABLE_SECTION_NAME): New macros.
|
||||
* config/tc-dvp.c (VUOVERLAY_START_PREFIX): New macro.
|
||||
(vuoverlay_section_name,create_vuoverlay_section): New functions.
|
||||
(vuoverlay_section,vuoverlay_table_section): New static globals.
|
||||
(ovlysym_table): New static global.
|
||||
(md_begin): Create .vuoverlay_table section.
|
||||
(assemble_vif): Call create_vuoverlay_section for each mpg.
|
||||
(dvp_frob_label): Record vu labels in ovlysym_table for later
|
||||
movement from absolute section to their overlay section.
|
||||
(dvp_frob_file): New function.
|
||||
(md_apply_fix3): For 8/16/32/64 bit relocs, only process if fx_done.
|
||||
|
||||
end-sanitize-sky
|
||||
Wed May 27 11:16:25 1998 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* read.c (s_org): Call md_flush_pending_output if it is defined.
|
||||
|
@ -52,11 +52,16 @@
|
||||
Note that symbols that begin with '$' are local symbols
|
||||
on mips targets, so we can't begin it with '$'. */
|
||||
#define VU_LABEL_PREFIX "_$"
|
||||
/* Prefix for symbols at start of vu overlays, in r5900 space. */
|
||||
#define VUOVERLAY_START_PREFIX "__start_"
|
||||
|
||||
static long parse_float PARAMS ((char **, const char **));
|
||||
static symbolS * create_label PARAMS ((const char *, const char *));
|
||||
static symbolS * create_colon_label PARAMS ((int, const char *, const char *));
|
||||
static char * unique_name PARAMS ((const char *));
|
||||
static char * vuoverlay_section_name PARAMS ((offsetT));
|
||||
static void create_vuoverlay_section PARAMS ((const char *, offsetT,
|
||||
symbolS *, symbolS *));
|
||||
static symbolS * compute_mpgloc PARAMS ((symbolS *, symbolS *, symbolS *));
|
||||
static int compute_nloop PARAMS ((gif_type, int, int));
|
||||
static void check_nloop PARAMS ((gif_type, int, int, int,
|
||||
@ -152,9 +157,28 @@ static symbolS *vif_data_start;
|
||||
/* Label at end of insn's data. */
|
||||
static symbolS *vif_data_end;
|
||||
|
||||
/* Special symbol $.mpgloc. The value is in bytes. */
|
||||
/* Special symbol $.mpgloc. The value is in bytes.
|
||||
This value is kept absolute, for simplicity. */
|
||||
static symbolS *mpgloc_sym;
|
||||
|
||||
/* Handle of the current .vuoverlay.foo section. */
|
||||
static segT vuoverlay_section;
|
||||
|
||||
/* The .overlay section is a table mapping lma's to vma's. */
|
||||
static segT vuoverlay_table_section;
|
||||
|
||||
/* Table to map vu space labels to their overlay sections.
|
||||
Labels in vu space are first put in the ABS section to simplify
|
||||
PC relative branch calculations (s1 - s2 isn't supported if they're
|
||||
in different sections). Before the file is written out the labels
|
||||
are moved to their overlay section. */
|
||||
typedef struct ovlysym {
|
||||
struct ovlysym *next;
|
||||
segT sec;
|
||||
symbolS *sym;
|
||||
} ovlysymS;
|
||||
static ovlysymS *ovlysym_table;
|
||||
|
||||
/* GIF insn support. */
|
||||
/* Type of insn. */
|
||||
static int gif_insn_type;
|
||||
@ -287,9 +311,18 @@ md_begin ()
|
||||
/* Disable automatic mpg insertion. */
|
||||
vu_count = -1;
|
||||
|
||||
/* Create special symbols. */
|
||||
/* Initialize $.mpgloc. */
|
||||
mpgloc_sym = expr_build_uconstant (0);
|
||||
|
||||
/* Create the vu overlay table section. */
|
||||
{
|
||||
/* Must preserve the current seg/subseg. It is the initial one. */
|
||||
segT orig_seg = now_seg;
|
||||
subsegT orig_subseg = now_subseg;
|
||||
vuoverlay_table_section = subseg_new (VUOVERLAY_TABLE_SECTION_NAME, 0);
|
||||
subseg_set (orig_seg, orig_subseg);
|
||||
}
|
||||
|
||||
/* Set the type of the output file to r5900. */
|
||||
bfd_set_arch_mach (stdoutput, bfd_arch_mips, 5900);
|
||||
}
|
||||
@ -628,21 +661,25 @@ assemble_vif (str)
|
||||
|
||||
/* Put a symbol at the start of data. The relaxation code uses
|
||||
this to figure out how many bytes to insert. $.mpgloc
|
||||
calculations also use it. */
|
||||
vif_data_start = create_colon_label (STO_DVP_VU, LOCAL_LABEL_PREFIX,
|
||||
unique_name ("mpg"));
|
||||
calculations use it. The disassembler uses it. The overlay
|
||||
tracking table uses it. */
|
||||
{
|
||||
int mpgloc = vif_get_mpgloc ();
|
||||
offsetT addr = mpgloc * 8;
|
||||
const char * section_name = vuoverlay_section_name (addr);
|
||||
vif_data_start = create_colon_label (STO_DVP_VU,
|
||||
VUOVERLAY_START_PREFIX,
|
||||
section_name);
|
||||
insn_frag->fr_symbol = vif_data_start;
|
||||
|
||||
/* Get the value of mpgloc. If it wasn't '*'
|
||||
then update $.mpgloc. */
|
||||
{
|
||||
int mpgloc = vif_get_mpgloc ();
|
||||
/* FIXME: Need to handle `*' case as well. */
|
||||
if (mpgloc != -1)
|
||||
{
|
||||
mpgloc_sym->sy_value.X_op = O_constant;
|
||||
/* The value is recorded in bytes. */
|
||||
mpgloc_sym->sy_value.X_add_number = mpgloc * 8;
|
||||
mpgloc_sym->sy_value.X_unsigned = 1;
|
||||
create_vuoverlay_section (section_name, addr,
|
||||
vif_data_start, vif_data_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1150,16 +1187,9 @@ assemble_one_insn (cpu, opcode, operand_table, init_fixup_count, fixup_offset,
|
||||
if (!(operand->flags & DVP_OPERAND_SUFFIX))
|
||||
as_fatal ("internal error: bad opcode table, missing suffix flag");
|
||||
|
||||
/* If we're at a space in the input string, we want to skip the
|
||||
remaining suffixes. There may be some fake ones though, so
|
||||
just go on to try the next one. */
|
||||
if (*str == ' ')
|
||||
{
|
||||
++syn;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Parse the suffix. */
|
||||
/* Parse the suffix. If we're at a space in the input string
|
||||
there are no more suffixes. Suffix parse routines must be
|
||||
prepared to deal with this. */
|
||||
errmsg = NULL;
|
||||
suf_value = (*operand->parse) (opcode, operand, mods, &str,
|
||||
&errmsg);
|
||||
@ -1495,10 +1525,23 @@ dvp_frob_label (sym)
|
||||
/* Check for recursive invocation creating the _$name. */
|
||||
&& strncmp (name, VU_LABEL_PREFIX, sizeof (VU_LABEL_PREFIX) - 1) != 0)
|
||||
{
|
||||
/* Move this symbol to vu space. */
|
||||
/* Move this symbol to the vu overlay. */
|
||||
symbolS * cur_mpgloc = compute_mpgloc (mpgloc_sym, vif_data_start,
|
||||
expr_build_dot ());
|
||||
#if 0 /* Don't do this now, leave in ABS and then move to overlay
|
||||
section before file is written. */
|
||||
S_SET_SEGMENT (sym, vuoverlay_section);
|
||||
#else
|
||||
/* Record the overlay section this symbol is in. */
|
||||
{
|
||||
ovlysymS *p = (ovlysymS *) xmalloc (sizeof (ovlysymS));
|
||||
p->next = ovlysym_table;
|
||||
p->sec = vuoverlay_section;
|
||||
p->sym = sym;
|
||||
ovlysym_table = p;
|
||||
}
|
||||
S_SET_SEGMENT (sym, expr_section);
|
||||
#endif
|
||||
sym->sy_value = cur_mpgloc->sy_value;
|
||||
sym->sy_frag = &zero_address_frag;
|
||||
|
||||
@ -1506,6 +1549,24 @@ dvp_frob_label (sym)
|
||||
create_colon_label (STO_DVP_VU, VU_LABEL_PREFIX, name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move vu space symbols into their overlay sections.
|
||||
Called via tc_frob_file. */
|
||||
|
||||
void
|
||||
dvp_frob_file ()
|
||||
{
|
||||
ovlysymS *p;
|
||||
|
||||
for (p = ovlysym_table; p; p = p->next)
|
||||
{
|
||||
/* See the comment near tc_frob_file in write.c.
|
||||
We are responsible for updating sym->bsym->value. */
|
||||
S_SET_SEGMENT (p->sym, p->sec);
|
||||
/* Adjust for the section's vma. */
|
||||
p->sym->bsym->value -= bfd_get_section_vma (stdoutput, p->sec);
|
||||
}
|
||||
}
|
||||
|
||||
/* mpg/direct alignment is handled via relaxation */
|
||||
|
||||
@ -1885,8 +1946,10 @@ md_apply_fix3 (fixP, valueP, seg)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (fixP->fx_done)
|
||||
{
|
||||
/* We're finished with this fixup. Install it because
|
||||
bfd_install_relocation won't be called to do it. */
|
||||
switch (fixP->fx_r_type)
|
||||
{
|
||||
case BFD_RELOC_8:
|
||||
@ -1902,7 +1965,13 @@ md_apply_fix3 (fixP, valueP, seg)
|
||||
as_fatal ("internal error: unexpected fixup");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bfd_install_relocation will be called to finish things up. */
|
||||
}
|
||||
|
||||
/* Tuck `value' away for use by tc_gen_reloc.
|
||||
See the comment describing fx_addnumber in write.h. */
|
||||
fixP->fx_addnumber = value;
|
||||
|
||||
return 1;
|
||||
@ -2169,6 +2238,99 @@ unique_name (prefix)
|
||||
++counter;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* VU support. */
|
||||
|
||||
/* Return the name of the overlay section.
|
||||
It must be unique among all overlays in the executable. */
|
||||
|
||||
static char *
|
||||
vuoverlay_section_name (addr)
|
||||
offsetT addr;
|
||||
{
|
||||
char *section_name;
|
||||
char *file;
|
||||
unsigned int lineno;
|
||||
unsigned int fileno;
|
||||
/* One mpg may actually result in several, counter keeps track of this. */
|
||||
static int counter;
|
||||
|
||||
as_where (&file, &lineno);
|
||||
for (fileno = 0; *file; ++file)
|
||||
fileno = (fileno << 1) + *file;
|
||||
asprintf (§ion_name, "%s0x%x.%u.%u.%d", VUOVERLAY_SECTION_PREFIX,
|
||||
(int) addr, fileno, lineno, counter);
|
||||
++counter;
|
||||
return section_name;
|
||||
}
|
||||
|
||||
/* Create a shadow section for VU code that starts at ADDR in vu space.
|
||||
START_LABEL and END_LABEL, if non-NULL, are symbols marking the start and
|
||||
end of the section. If NULL, no overlay tracking information is output. */
|
||||
|
||||
static void
|
||||
create_vuoverlay_section (section_name, addr, start_label, end_label)
|
||||
const char *section_name;
|
||||
offsetT addr;
|
||||
symbolS *start_label, *end_label;
|
||||
{
|
||||
/* Must preserve the current seg/subseg. */
|
||||
segT orig_seg = now_seg;
|
||||
subsegT orig_subseg = now_subseg;
|
||||
|
||||
/* Create and get handle of .vuoverlay section. All vu symbols go here.
|
||||
The section name must be unique in the entire executable.
|
||||
We achieve this by encoding the source file name and file number. Ick.
|
||||
??? A cleaner way would be if mpg took a new argument that named the
|
||||
overlay. */
|
||||
vuoverlay_section = subseg_new (section_name, 0);
|
||||
bfd_set_section_flags (stdoutput, vuoverlay_section, 0);
|
||||
/* There's no point in setting the section vma as we can't get the linker
|
||||
to preserve it. But what the heck ... It might be useful to the
|
||||
objdump user. */
|
||||
bfd_set_section_vma (stdoutput, vuoverlay_section, addr);
|
||||
/* The size of the section won't be known until we see the .endmpg,
|
||||
but we can compute it from the start and end labels. */
|
||||
/* FIXME: This causes the section to occupy space in the file. */
|
||||
if (start_label)
|
||||
frag_var (rs_space, 1, 1, (relax_substateT) 0,
|
||||
expr_build_binary (O_subtract, end_label, start_label),
|
||||
(offsetT) 0, (char *) 0);
|
||||
#if 0
|
||||
/* Create a symbol marking the start of the section. */
|
||||
begin_label = create_colon_label (STO_DVP_VU, "__start_", section_name);
|
||||
#endif
|
||||
|
||||
/* Initialize $.mpgloc. */
|
||||
mpgloc_sym = expr_build_uconstant (addr);
|
||||
|
||||
#if 0 /* $.mpgloc is kept in the ABS section. */
|
||||
S_SET_SEGMENT (mpgloc_sym, vuoverlay_section);
|
||||
#endif
|
||||
|
||||
/* Add an entry to the vu overlay table. */
|
||||
if (start_label)
|
||||
{
|
||||
/* FIXME: should be a service routine to do these. */
|
||||
expressionS exp;
|
||||
|
||||
subseg_set (vuoverlay_table_section, 0);
|
||||
|
||||
/* The section's lma. */
|
||||
exp.X_op = O_symbol;
|
||||
exp.X_add_symbol = start_label;
|
||||
exp.X_add_number = 0;
|
||||
emit_expr (&exp, 8);
|
||||
|
||||
/* The section's vma. */
|
||||
exp.X_op = O_constant;
|
||||
exp.X_add_number = addr;
|
||||
emit_expr (&exp, 8);
|
||||
}
|
||||
|
||||
/* Restore the original seg/subseg. */
|
||||
subseg_set (orig_seg, orig_subseg);
|
||||
}
|
||||
|
||||
/* Compute a value for $.mpgloc given a symbol at the start of a chunk
|
||||
of code, the $.mpgloc value for the start, and a symbol at the end
|
||||
@ -2971,8 +3133,12 @@ s_state (state)
|
||||
in use versions of these. Also need to worry about which section
|
||||
the .vu is issued in. On the other hand, ".vu" isn't intended
|
||||
to be supported everywhere. */
|
||||
mpgloc_sym = expr_build_uconstant (0);
|
||||
vif_data_start = expr_build_dot ();
|
||||
#if 0
|
||||
create_vuoverlay_section (vuoverlay_section_name (0), 0, NULL, NULL);
|
||||
#else
|
||||
mpgloc_sym = expr_build_uconstant (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
set_asm_state (state);
|
||||
|
@ -45,28 +45,54 @@
|
||||
/* We don't need to handle .word strangely. */
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
#define md_convert_frag(b,s,f) {as_fatal ("dvp convert_frag\n");}
|
||||
#define md_estimate_size_before_relax(f,s) \
|
||||
(as_fatal("estimate_size_before_relax called"),1)
|
||||
/* Handle mpg/direct alignment requirements with relaxation. */
|
||||
extern long dvp_relax_frag PARAMS ((fragS *, long));
|
||||
#define md_relax_frag(fragP,stretch) dvp_relax_frag ((fragP), (stretch))
|
||||
|
||||
#define MD_APPLY_FIX3
|
||||
|
||||
/* Ensure insns at labels have their mach type properly recorded. */
|
||||
int force_mach_label PARAMS ((void));
|
||||
#define TC_START_LABEL(ch, ptr) (ch == ':' && force_mach_label ())
|
||||
|
||||
#define TC_HANDLES_FX_DONE
|
||||
|
||||
/* Record user specified val, for cases where we can't compute the actual
|
||||
value until the end of assembly. */
|
||||
#define TC_FIX_TYPE \
|
||||
struct { \
|
||||
int type; /* gif_type, or vif type */ \
|
||||
int nregs; /* for gif insns only */ \
|
||||
short wl; short cl; /* for unpack only */ \
|
||||
int user_value; \
|
||||
}
|
||||
/* Code to initialize it. */
|
||||
#define TC_INIT_FIX_DATA(fixP) \
|
||||
do { memset (&fixP->tc_fix_data, 0, sizeof (fixP->tc_fix_data)); } while (0)
|
||||
|
||||
/* Called after parsing a file. */
|
||||
extern void dvp_parse_done PARAMS ((void));
|
||||
#define md_after_pass_hook() dvp_after_pass_hook ()
|
||||
|
||||
/* Called for each label. */
|
||||
extern void dvp_frob_label PARAMS ((struct symbol *));
|
||||
#define tc_frob_label(sym) dvp_frob_label (sym)
|
||||
|
||||
/* Called just before writing the file out. */
|
||||
extern void dvp_frob_file PARAMS ((void));
|
||||
#define tc_frob_file() dvp_frob_file ()
|
||||
|
||||
/* Default section names. */
|
||||
#define TEXT_SECTION_NAME ".vutext"
|
||||
#define DATA_SECTION_NAME ".vudata"
|
||||
#define BSS_SECTION_NAME ".vubss"
|
||||
|
||||
/* Other special section names. */
|
||||
#define VUOVERLAY_SECTION_PREFIX ".vuoverlay."
|
||||
#define VUOVERLAY_TABLE_SECTION_NAME ".vuoverlay_table"
|
||||
|
||||
#define ELF_TC_SPECIAL_SECTIONS \
|
||||
{ ".vubss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, \
|
||||
{ ".vudata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
|
||||
{ ".vutext", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
|
||||
|
||||
{ ".vutext", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, \
|
||||
{ ".vuoverlay_table", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
|
||||
|
Reference in New Issue
Block a user