* Support for SPARC STT_REGISTER
@ 1999-07-04 11:59 Jakub Jelinek
1999-07-06 18:47 ` Ian Lance Taylor
0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 1999-07-04 11:59 UTC (permalink / raw)
To: ian, rth; +Cc: binutils
Hi!
Sparcv9 ABI requires any object using %g2, %g3 registers and optionally also
%g6 and %g7 registers to announce this support by an STT_REGISTER symbol.
In assembler, the syntax looks like this:
.register %g2, #scratch
.register %g3, somesymbol
The first one bounds %g2 to symbol "" (st_name 0).
This information is then used in linking, where it is forbidden to link two
objects which both declare a particular register to a different symbol.
A shared object ought to have these symbols in the dynamic symbol section as
well, and .dynamic sections should contain DT_REGISTER to point into the
.dynsym to these declarations so that dynamic linker can check them quickly.
I have started writing support for all this, but am looking for opinions in
the middle of the implementation.
Basically it adds complexity not yet present in bfd elf linking code,
because
1) there maybe more symbol entries with the same name (one can have
%g2,%g3,%g6,%g7 all #scratch registers)
2) a STT_REGISTER is basically indexed by st_value (the register number),
not its name
3) for the .dynsym case the names should not be present in the .hash
I'd like to hear what you think how to support this. The patch below does
everything but the dynamic sections (but does not honour stripping of the
.symtab STT_REGISTER entries yet). As the symbols can have identical names,
I'm not storing them into the symbol hash table, but I wonder whether it
would be better to force them into the hash table eventhough they have
identical names as most of elflink.h just traverses those hash tables.
--- ./bfd/bfd-in2.h.jj Tue Jun 29 10:46:31 1999
+++ ./bfd/bfd-in2.h Wed Jun 30 12:37:16 1999
@@ -2312,6 +2312,9 @@ typedef struct symbol_cache_entry
others someday. */
#define BSF_OBJECT 0x10000
+ /* Processor specific symbol type. */
+#define BSF_PROC 0x20000
+
flagword flags;
/* A pointer to the section to which this symbol is
--- ./bfd/elf.c.jj Tue Jun 29 10:47:02 1999
+++ ./bfd/elf.c Wed Jun 30 15:00:22 1999
@@ -756,8 +756,24 @@ bfd_elf_print_symbol (abfd, filep, symbo
case bfd_print_symbol_all:
{
CONST char *section_name;
+ CONST char *name = NULL;
+ struct elf_backend_data *bed;
+
section_name = symbol->section ? symbol->section->name : "(*none*)";
- bfd_print_symbol_vandf ((PTR) file, symbol);
+
+ if (symbol->flags & BSF_PROC)
+ {
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_print_symbol_all)
+ name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
+ }
+
+ if (name == NULL)
+ {
+ name = symbol->name;
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ }
+
fprintf (file, " %s\t", section_name);
/* Print the "other" value for a symbol. For common symbols,
we've already printed the size; now print the alignment.
@@ -825,7 +841,7 @@ bfd_elf_print_symbol (abfd, filep, symbo
((unsigned int)
((elf_symbol_type *) symbol)->internal_elf_sym.st_other));
- fprintf (file, " %s", symbol->name);
+ fprintf (file, " %s", name);
}
break;
}
@@ -3982,6 +3998,25 @@ swap_out_syms (abfd, sttp, relocatable_p
}
type_ptr = elf_symbol_from (abfd, syms[idx]);
+
+ if ((flags & BSF_PROC) && type_ptr)
+ {
+ /* We don't know much about this symbol, so copy it
+ as is. */
+ unsigned long name = sym.st_name;
+ int bind = STB_LOCAL;
+
+ sym = type_ptr->internal_elf_sym;
+ sym.st_name = name;
+ if (flags & BSF_GLOBAL)
+ bind = STB_GLOBAL;
+ else if (flags & BSF_WEAK)
+ bind = STB_WEAK;
+ sym.st_info = ELF_ST_INFO (bind, ELF_ST_TYPE (sym.st_info));
+ bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ outbound_syms += bed->s->sizeof_sym;
+ continue;
+ }
if ((flags & BSF_SECTION_SYM) == 0
&& bfd_is_com_section (syms[idx]->section))
--- ./bfd/elfcode.h.jj Tue Jun 29 10:47:12 1999
+++ ./bfd/elfcode.h Wed Jun 30 15:02:48 1999
@@ -1137,6 +1137,13 @@ elf_slurp_symbol_table (abfd, symptrs, d
case STT_OBJECT:
sym->symbol.flags |= BSF_OBJECT;
break;
+ case STT_LOPROC:
+ case STT_LOPROC+1:
+ case STT_HIPROC:
+ sym->symbol.flags |= BSF_PROC;
+ if (ELF_ST_BIND (i_sym.st_info) == STB_GLOBAL)
+ sym->symbol.flags |= BSF_GLOBAL;
+ break;
}
if (dynamic)
--- ./bfd/elflink.h.jj Tue Jun 29 10:47:22 1999
+++ ./bfd/elflink.h Sat Jul 3 21:43:13 1999
@@ -4064,6 +4064,18 @@ elf_bfd_final_link (abfd, info)
if (eoinfo.failed)
return false;
+ /* If backend needs to output some symbols not present in the hash
+ table, do it now. */
+ if (bed->elf_backend_output_arch_syms)
+ {
+ if (! (*bed->elf_backend_output_arch_syms)
+ (info, (PTR) &finfo,
+ (boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *)))
+ elf_link_output_sym))
+ return false;
+ }
+
/* Flush all symbols to the file. */
if (! elf_link_flush_output_syms (&finfo))
return false;
--- ./bfd/elf-bfd.h.jj Tue Jun 29 10:46:50 1999
+++ ./bfd/elf-bfd.h Sat Jul 3 21:41:12 1999
@@ -517,6 +517,16 @@ struct elf_backend_data
void (*elf_backend_post_process_headers)
PARAMS ((bfd *, struct bfd_link_info *));
+ /* This function, if defined, prints a BSF_PROC symbol to file
+ and returns the name of the symbol to be printed. */
+ const char *(*elf_backend_print_symbol_all)
+ PARAMS ((bfd *, PTR, asymbol *));
+
+ boolean (*elf_backend_output_arch_syms)
+ PARAMS ((struct bfd_link_info *, PTR,
+ boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *))));
+
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
--- ./bfd/elfxx-target.h.jj Wed Jun 9 09:51:35 1999
+++ ./bfd/elfxx-target.h Sat Jul 3 21:07:17 1999
@@ -294,6 +294,12 @@ Foundation, Inc., 59 Temple Place - Suit
#ifndef elf_backend_post_process_headers
#define elf_backend_post_process_headers NULL
#endif
+#ifndef elf_backend_print_symbol_all
+#define elf_backend_print_symbol_all NULL
+#endif
+#ifndef elf_backend_output_arch_syms
+#define elf_backend_output_arch_syms NULL
+#endif
/* Previously, backends could only use SHT_REL or SHT_RELA relocation
sections, but not both. They defined USE_REL to indicate SHT_REL
@@ -366,6 +372,8 @@ static CONST struct elf_backend_data elf
elf_backend_gc_mark_hook,
elf_backend_gc_sweep_hook,
elf_backend_post_process_headers,
+ elf_backend_print_symbol_all,
+ elf_backend_output_arch_syms,
elf_backend_ecoff_debug_swap,
ELF_MACHINE_ALT1,
ELF_MACHINE_ALT2,
--- ./bfd/elf64-sparc.c.jj Tue Jun 29 10:47:08 1999
+++ ./bfd/elf64-sparc.c Sun Jul 4 17:28:42 1999
@@ -32,6 +32,9 @@ Foundation, Inc., 59 Temple Place - Suit
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
#define MINUS_ONE (~ (bfd_vma) 0)
+static struct bfd_link_hash_table * sparc64_elf_bfd_link_hash_table_create
+ PARAMS((bfd *));
+
static reloc_howto_type *sparc64_elf_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
static void sparc64_elf_info_to_howto
@@ -53,6 +56,9 @@ static boolean sparc64_elf_size_dynamic_
PARAMS((bfd *, struct bfd_link_info *));
static boolean sparc64_elf_adjust_dynindx
PARAMS((struct elf_link_hash_entry *, PTR));
+static boolean sparc64_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
static boolean sparc64_elf_merge_private_bfd_data
PARAMS ((bfd *, bfd *));
@@ -217,6 +223,52 @@ sparc64_elf_info_to_howto (abfd, cache_p
cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE (dst->r_info)];
}
\f
+/* Sparc64 ELF linker hash table. */
+
+struct sparc64_elf_app_reg
+{
+ unsigned char bind;
+ unsigned short shndx;
+ bfd *abfd;
+ char *name;
+};
+
+struct sparc64_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ struct sparc64_elf_app_reg app_regs [4];
+};
+
+/* Get the Sparc64 ELF linker hash table from a link_info structure. */
+
+#define sparc64_elf_hash_table(p) \
+ ((struct sparc64_elf_link_hash_table *) ((p)->hash))
+
+/* Create a Sparc64 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+sparc64_elf_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct sparc64_elf_link_hash_table *ret;
+
+ ret = ((struct sparc64_elf_link_hash_table *)
+ bfd_zalloc (abfd, sizeof (struct sparc64_elf_link_hash_table)));
+ if (ret == (struct sparc64_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+\f
/* Utility for performing the standard initial work of an instruction
relocation.
*PRELOCATION will contain the relocated item.
@@ -817,6 +869,148 @@ sparc64_elf_check_relocs (abfd, info, se
return true;
}
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it for STT_REGISTER symbols. */
+
+static boolean
+sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
+ {
+ int reg;
+ struct sparc64_elf_app_reg *p;
+
+ *flagsp |= BSF_PROC;
+ if (ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
+ *flagsp |= BSF_GLOBAL;
+
+ reg = (int)sym->st_value;
+ switch (reg & ~1)
+ {
+ case 2: reg -= 2; break;
+ case 6: reg -= 4; break;
+ default:
+ (*_bfd_error_handler)
+ (_("%s: Only registers %%g[2367] can be declared using STT_REGISTER"),
+ bfd_get_filename (abfd));
+ return false;
+ }
+
+ if (info->hash->creator != abfd->xvec)
+ {
+ *namep = NULL;
+ return true;
+ }
+
+ p = sparc64_elf_hash_table(info)->app_regs + reg;
+
+ if (p->name != NULL && strcmp (p->name, *namep))
+ {
+ (*_bfd_error_handler)
+ (_("Register %%g%d used incompatibly: "
+ "previously declared in %s to %s, in %s redefined to %s"),
+ (int)sym->st_value,
+ bfd_get_filename (p->abfd), *p->name ? p->name : "#scratch",
+ bfd_get_filename (abfd), **namep ? *namep : "#scratch");
+ return false;
+ }
+
+ if ((abfd->flags & DYNAMIC) != 0)
+ {
+ /* If STT_REGISTER comes from a dynamic object, don't put it into
+ the output bfd. The dynamic linker will recheck it. */
+ *namep = NULL;
+ return true;
+ }
+
+ if (p->name == NULL)
+ {
+ if (**namep)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, *namep, false, false, false);
+
+ if (h != NULL)
+ {
+ static char *stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
+ unsigned char type = h->type;
+
+ if (type > STT_FUNC) type = 0;
+ (*_bfd_error_handler)
+ (_("Symbol `%s' has differing types: "
+ "previously %s, REGISTER in %s"),
+ *namep, stt_types [type], bfd_get_filename (abfd));
+ return false;
+ }
+
+ p->name = bfd_hash_allocate (&info->hash->table,
+ strlen (*namep) + 1);
+ if (!p->name)
+ return false;
+
+ strcpy (p->name, *namep);
+ }
+ else
+ p->name = "";
+ p->bind = ELF_ST_BIND (sym->st_info);
+ p->abfd = abfd;
+ p->shndx = sym->st_shndx;
+ }
+ else
+ {
+ if (p->bind == STB_WEAK
+ && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
+ {
+ p->bind = STB_GLOBAL;
+ p->abfd = abfd;
+ }
+ }
+ *namep = NULL;
+ return true;
+ }
+ return true;
+}
+
+/* This function takes care of emmiting STT_REGISTER symbols
+ which we cannot easily keep in the symbol hash table. */
+static boolean
+sparc64_elf_output_arch_syms (info, finfo, func)
+ struct bfd_link_info *info;
+ PTR finfo;
+ boolean (*func) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *));
+{
+ int reg;
+ struct sparc64_elf_app_reg *app_regs =
+ sparc64_elf_hash_table(info)->app_regs;
+ Elf_Internal_Sym sym;
+
+ for (reg = 0; reg < 4; reg++)
+ if (app_regs [reg].name != NULL)
+ {
+ sym.st_value = reg < 2 ? reg + 2 : reg + 4;
+ sym.st_size = 0;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
+ sym.st_shndx = app_regs [reg].shndx;
+ if (! (*func) (finfo, app_regs [reg].name, &sym,
+ sym.st_shndx == SHN_ABS
+ ? bfd_abs_section_ptr : bfd_und_section_ptr))
+ return false;
+ }
+
+ return true;
+}
+
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
@@ -2210,7 +2404,34 @@ sparc64_elf_merge_private_bfd_data (ibfd
}
return true;
}
+\f
+/* Print a STT_REGISTER symbol to file FILE. */
+static const char *
+sparc64_elf_print_symbol_all (abfd, filep, symbol)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+{
+ FILE *file = (FILE *) filep;
+ int reg, type;
+
+ if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
+ != STT_REGISTER)
+ return NULL;
+
+ reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+ type = symbol->flags;
+ fprintf (file, "REG_%c%c%11s%c%c R", "GOLI" [reg / 8], '0' + (reg & 7), "",
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ');
+ if (symbol->name == NULL || symbol->name [0] == '\0')
+ return "#scratch";
+ else
+ return symbol->name;
+}
\f
/* Set the right machine number for a SPARC64 ELF file. */
@@ -2236,6 +2457,9 @@ sparc64_elf_object_p (abfd)
/* This is the value that we used before the ABI was released. */
#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
+#define bfd_elf64_bfd_link_hash_table_create \
+ sparc64_elf_bfd_link_hash_table_create
+
#define elf_info_to_howto \
sparc64_elf_info_to_howto
#define bfd_elf64_bfd_reloc_type_lookup \
@@ -2243,6 +2467,8 @@ sparc64_elf_object_p (abfd)
#define elf_backend_create_dynamic_sections \
_bfd_elf_create_dynamic_sections
+#define elf_backend_add_symbol_hook \
+ sparc64_elf_add_symbol_hook
#define elf_backend_check_relocs \
sparc64_elf_check_relocs
#define elf_backend_adjust_dynamic_symbol \
@@ -2255,6 +2481,10 @@ sparc64_elf_object_p (abfd)
sparc64_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
sparc64_elf_finish_dynamic_sections
+#define elf_backend_print_symbol_all \
+ sparc64_elf_print_symbol_all
+#define elf_backend_output_arch_syms \
+ sparc64_elf_output_arch_syms
#define bfd_elf64_bfd_merge_private_bfd_data \
sparc64_elf_merge_private_bfd_data
--- ./binutils/readelf.c.jj Tue Jun 29 10:48:20 1999
+++ ./binutils/readelf.c Fri Jul 2 15:44:56 1999
@@ -414,6 +414,8 @@ guess_is_rela (e_machine)
/* Targets that use RELA relocations. */
case EM_68K:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
case EM_SPARC:
case EM_PPC:
case EM_CYGNUS_V850:
@@ -1062,6 +1064,29 @@ get_machine_flags (e_flags, e_machine)
if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
strcat (buf, ", mips4");
break;
+
+ case EM_SPARCV9:
+ if (e_flags & EF_SPARC_32PLUS)
+ strcat (buf, ", v8+");
+
+ if (e_flags & EF_SPARC_SUN_US1)
+ strcat (buf, ", ultrasparc");
+
+ if (e_flags & EF_SPARC_HAL_R1)
+ strcat (buf, ", halr1");
+
+ if (e_flags & EF_SPARC_LEDATA)
+ strcat (buf, ", ledata");
+
+ if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
+ strcat (buf, ", tso");
+
+ if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
+ strcat (buf, ", pso");
+
+ if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
+ strcat (buf, ", rmo");
+ break;
}
}
@@ -3393,6 +3418,9 @@ get_symbol_type (type)
{
if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
return _("THUMB_FUNC");
+
+ if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
+ return _("REGISTER");
sprintf (buff, _("<processor specific>: %d"), type);
}
--- ./gas/config/tc-sparc.c.jj Tue Jun 29 10:49:38 1999
+++ ./gas/config/tc-sparc.c Sat Jul 3 18:31:35 1999
@@ -87,6 +87,10 @@ static int warn_on_bump;
architecture, issue a warning. */
static enum sparc_opcode_arch_val warn_after_architecture;
+/* Non-zero if as should generate error if an undeclared g[23] register
+ has been used in -64. */
+static int no_undeclared_regs;
+
/* Non-zero if we are generating PIC code. */
int sparc_pic_code;
@@ -97,6 +101,9 @@ extern int target_big_endian;
static int target_little_endian_data;
+/* Symbols for global registers on v9. */
+static symbolS *globals[8];
+
/* V9 and 86x have big and little endian data, but instructions are always big
endian. The sparclet has bi-endian support but both data and insns have
the same endianness. Global `target_big_endian' is used for data.
@@ -119,6 +126,7 @@ static void s_common PARAMS ((int));
static void s_empty PARAMS ((int));
static void s_uacons PARAMS ((int));
static void s_ncons PARAMS ((int));
+static void s_register PARAMS ((int));
const pseudo_typeS md_pseudo_table[] =
{
@@ -143,6 +151,7 @@ const pseudo_typeS md_pseudo_table[] =
{"2byte", s_uacons, 2},
{"4byte", s_uacons, 4},
{"8byte", s_uacons, 8},
+ {"register", s_register, 0},
#endif
{NULL, 0, 0},
};
@@ -400,6 +409,10 @@ struct option md_longopts[] = {
{"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
{"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
+#ifdef OBJ_ELF
+#define OPTION_NO_UNDECLARED_REGS (OPTION_MD_BASE + 12)
+ {"no-undeclared-regs", no_argument, NULL, OPTION_NO_UNDECLARED_REGS},
+#endif
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
@@ -549,6 +562,10 @@ md_parse_option (c, arg)
else
sparc_pic_code = 1;
break;
+
+ case OPTION_NO_UNDECLARED_REGS:
+ no_undeclared_regs = 1;
+ break;
#endif
default:
@@ -1865,6 +1882,11 @@ sparc_ip (str, pinsn)
goto error;
}
+ if ((mask & ~1) == 2 && sparc_arch_size == 64
+ && no_undeclared_regs && ! globals [mask])
+ as_bad (_("detected global register use not "
+ "covered by .register pseudo-op"));
+
/* Got the register, now figure out where
it goes in the opcode. */
switch (*args)
@@ -3677,6 +3699,87 @@ s_ncons (bytes)
{
cons (sparc_arch_size == 32 ? 4 : 8);
}
+
+#ifdef OBJ_ELF
+/* Handle the SPARC ELF .register pseudo-op. This sets the binding of a
+ global register.
+ The syntax is:
+
+ .register %g[2367],{#scratch|symbolname}
+ */
+
+static void
+s_register (ignore)
+ int ignore;
+{
+ char c;
+ int reg;
+ int flags;
+ const char *regname;
+
+ if (input_line_pointer[0] != '%'
+ || input_line_pointer[1] != 'g'
+ || ((input_line_pointer[2] & ~1) != '2'
+ && (input_line_pointer[2] & ~1) != '6')
+ || input_line_pointer[3] != ',')
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname}"));
+ reg = input_line_pointer[2] - '0';
+ input_line_pointer += 4;
+
+ if (*input_line_pointer == '#')
+ {
+ ++input_line_pointer;
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcmp (regname, "scratch"))
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname}"));
+ regname = "";
+ }
+ else
+ {
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ }
+ if (sparc_arch_size == 64)
+ {
+ if (globals [reg])
+ {
+ if (strcmp (S_GET_NAME (globals [reg]), regname))
+ as_bad (_("redefinition of global register"));
+ }
+ else
+ {
+ if (*regname)
+ {
+ if (symbol_find (regname))
+ as_bad (_("Register symbol %s already defined."), regname);
+ }
+ globals [reg] = symbol_make (regname);
+ flags = symbol_get_bfdsym (globals [reg])->flags;
+ flags |= BSF_PROC;
+ if (! *regname)
+ flags = flags & ~(BSF_GLOBAL|BSF_LOCAL|BSF_WEAK);
+ if (! (flags & (BSF_GLOBAL|BSF_LOCAL|BSF_WEAK)))
+ flags |= BSF_GLOBAL;
+ symbol_get_bfdsym (globals [reg])->flags = flags;
+ S_SET_VALUE (globals [reg], (valueT)reg);
+ S_SET_ALIGN (globals [reg], reg);
+ S_SET_SIZE (globals [reg], 0);
+ S_SET_SEGMENT (globals [reg], absolute_section);
+ S_SET_OTHER (globals [reg], 0);
+ elf_symbol (symbol_get_bfdsym (globals [reg]))
+ ->internal_elf_sym.st_info =
+ ELF_ST_INFO(STB_GLOBAL, STT_REGISTER);
+ elf_symbol (symbol_get_bfdsym (globals [reg]))
+ ->internal_elf_sym.st_shndx = SHN_UNDEF;
+ }
+ }
+
+ *input_line_pointer = c;
+
+ demand_empty_rest_of_line ();
+}
+#endif
/* If the --enforce-aligned-data option is used, we require .word,
et. al., to be aligned correctly. We do it by setting up an
--- ./gas/doc/c-sparc.texi.jj Mon May 3 09:28:45 1999
+++ ./gas/doc/c-sparc.texi Sat Jul 3 18:38:25 1999
@@ -145,11 +145,24 @@ syntax is different.
@item .half
This is functionally identical to @code{.short}.
+@cindex @code{nword} directive, SPARC
+@item .nword
+On the Sparc, the @code{.nword} directive produces native word sized value,
+ie. if assembling with -32 it is equivalent to @code{.word}, if assembling
+with -64 it is equivalent to @code{.xword}.
+
@cindex @code{proc} directive, SPARC
@item .proc
This directive is ignored. Any text following it on the same
line is also ignored.
+@cindex @code{register} directive, SPARC
+@item .register
+This directive declares use of a global application or system register.
+It must be followed by a register name %g2, %g3, %g6 or %g7, comma and
+the symbol name for that register or @code{#scratch} if it is a scratch
+register.
+
@cindex @code{reserve} directive, SPARC
@item .reserve
This must be followed by a symbol name, a positive number, and
@@ -176,4 +189,3 @@ instead of the 16 bit values it produces
On the Sparc V9 processor, the @code{.xword} directive produces
64 bit values.
@end table
-
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
UltraLinux | http://ultra.linux.cz/ | http://ultra.penguin.cz/
Linux version 2.2.10 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Support for SPARC STT_REGISTER
1999-07-04 11:59 Support for SPARC STT_REGISTER Jakub Jelinek
@ 1999-07-06 18:47 ` Ian Lance Taylor
1999-07-07 5:45 ` Jakub Jelinek
0 siblings, 1 reply; 4+ messages in thread
From: Ian Lance Taylor @ 1999-07-06 18:47 UTC (permalink / raw)
To: jj; +Cc: rth, binutils
Date: Sun, 4 Jul 1999 21:00:39 +0200
From: Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
Sparcv9 ABI requires any object using %g2, %g3 registers and optionally also
%g6 and %g7 registers to announce this support by an STT_REGISTER symbol.
In assembler, the syntax looks like this:
.register %g2, #scratch
.register %g3, somesymbol
The first one bounds %g2 to symbol "" (st_name 0).
This information is then used in linking, where it is forbidden to link two
objects which both declare a particular register to a different symbol.
A shared object ought to have these symbols in the dynamic symbol section as
well, and .dynamic sections should contain DT_REGISTER to point into the
.dynsym to these declarations so that dynamic linker can check them quickly.
I have started writing support for all this, but am looking for opinions in
the middle of the implementation.
Basically it adds complexity not yet present in bfd elf linking code,
because
1) there maybe more symbol entries with the same name (one can have
%g2,%g3,%g6,%g7 all #scratch registers)
2) a STT_REGISTER is basically indexed by st_value (the register number),
not its name
3) for the .dynsym case the names should not be present in the .hash
I'd like to hear what you think how to support this. The patch below does
everything but the dynamic sections (but does not honour stripping of the
.symtab STT_REGISTER entries yet). As the symbols can have identical names,
I'm not storing them into the symbol hash table, but I wonder whether it
would be better to force them into the hash table eventhough they have
identical names as most of elflink.h just traverses those hash tables.
What is the section of such a symbol?
You have added code to handle them specially in the linker hash table.
I don't think this is necessary. This is a case of linking symbols
with special semantics. You don't need to remove those symbols
entirely from the linking process; you just need to implement special
semantics for them. We already have a hook for that:
elf_add_symbol_hook. It can implement the special semantics for
STT_REGISTER symbols, and then adjust its arguments to invoke some
appropriately harmless set of standard semantics.
--- ./bfd/bfd-in2.h.jj Tue Jun 29 10:46:31 1999
+++ ./bfd/bfd-in2.h Wed Jun 30 12:37:16 1999
@@ -2312,6 +2312,9 @@ typedef struct symbol_cache_entry
+ /* Processor specific symbol type. */
+#define BSF_PROC 0x20000
+
I don't care for this. Changes to the generic ABI should ideally have
a generic meaning. This does not. I also don't see why it is
necessary to change the generic ABI in this manner, given the
existence of elf_symbol_type.
@@ -3982,6 +3998,25 @@ swap_out_syms (abfd, sttp, relocatable_p
}
type_ptr = elf_symbol_from (abfd, syms[idx]);
+
+ if ((flags & BSF_PROC) && type_ptr)
+ {
+ /* We don't know much about this symbol, so copy it
+ as is. */
+ unsigned long name = sym.st_name;
+ int bind = STB_LOCAL;
+
+ sym = type_ptr->internal_elf_sym;
+ sym.st_name = name;
+ if (flags & BSF_GLOBAL)
+ bind = STB_GLOBAL;
+ else if (flags & BSF_WEAK)
+ bind = STB_WEAK;
+ sym.st_info = ELF_ST_INFO (bind, ELF_ST_TYPE (sym.st_info));
+ bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ outbound_syms += bed->s->sizeof_sym;
+ continue;
+ }
if ((flags & BSF_SECTION_SYM) == 0
&& bfd_is_com_section (syms[idx]->section))
I think we should be able to more or less handle this case via
elf_backend_get_symbol_type.
--- ./bfd/elfcode.h.jj Tue Jun 29 10:47:12 1999
+++ ./bfd/elfcode.h Wed Jun 30 15:02:48 1999
@@ -1137,6 +1137,13 @@ elf_slurp_symbol_table (abfd, symptrs, d
case STT_OBJECT:
sym->symbol.flags |= BSF_OBJECT;
break;
+ case STT_LOPROC:
+ case STT_LOPROC+1:
+ case STT_HIPROC:
+ sym->symbol.flags |= BSF_PROC;
+ if (ELF_ST_BIND (i_sym.st_info) == STB_GLOBAL)
+ sym->symbol.flags |= BSF_GLOBAL;
+ break;
}
This is what elf_backend_symbol_processing is for.
--- ./bfd/elf-bfd.h.jj Tue Jun 29 10:46:50 1999
+++ ./bfd/elf-bfd.h Sat Jul 3 21:41:12 1999
@@ -517,6 +517,16 @@ struct elf_backend_data
+ boolean (*elf_backend_output_arch_syms)
+ PARAMS ((struct bfd_link_info *, PTR,
+ boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *))));
+
You are missing a comment here.
--- ./binutils/readelf.c.jj Tue Jun 29 10:48:20 1999
+++ ./binutils/readelf.c Fri Jul 2 15:44:56 1999
These patches seem to have a bunch of code that don't seem to have
anything to do with STT_REGISTER. Could you please submit that part
of them separately, so that we can get them in without getting tangled
up with extraneous issues? Thanks.
Ian
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Support for SPARC STT_REGISTER
1999-07-06 18:47 ` Ian Lance Taylor
@ 1999-07-07 5:45 ` Jakub Jelinek
1999-07-08 11:30 ` Richard Henderson
0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 1999-07-07 5:45 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: rth, binutils
(Updated patch attached below).
> What is the section of such a symbol?
ABI says:
st_name: Index into the string table of the name of the symbol, if 0, it is
a register used for scratch. st_name 0 implies STB_GLOBAL.
st_value: Register number (2, 3, 6, 7).
st_size = st_other = 0
st_info = ELF64_ST_INFO(bind, STT_REGISTER) where bind is usually
STB_GLOBAL, but can be STB_WEAK or STB_LOCAL.
st_shndx: SHN_ABS if this object initializes this register symbol (currently
unsupported in Solaris as as far as I can examine) or SHN_UNDEF otherwise.
Here is elfdump output how it looks like under Solaris:
ccc:~# elfdump t.so.1 # Shared library
ELF Header
ei_magic: { 0x7f, E, L, F }
ei_class: ELFCLASS64 ei_data: ELFDATA2MSB
e_machine: EM_SPARCV9 e_version: EV_CURRENT
e_type: ET_DYN
e_flags: [ EF_SPARCV9_TSO EF_SPARC_SUN_US1 ]
e_entry: 0x3c4 e_ehsize: 64 e_shstrndx: 10
e_shoff: 0x780 e_shentsize: 64 e_shnum: 11
e_phoff: 0x40 e_phentsize: 56 e_phnum: 3
...
Symbol Table: .dynsym
index value size type bind oth shndx name
[0] 0x000000000000 0x000000000000 NOTY LOCL 0 UNDEF
...
[10] 0x000000000000 0x000000000000 SECT LOCL 0 .shstrtab
[11] REG_G3 0x000000000000 REGI GLOB 0 UNDEF
[12] 0x000000100470 0x000000000000 OBJT GLOB 0 .bss _end
[13] 0x0000001003d0 0x000000000000 OBJT GLOB 0 .dynamic _DYNAMIC
[14] REG_G2 0x000000000000 REGI GLOB 0 UNDEF addrb
[15] 0x000000100470 0x000000000000 OBJT GLOB 0 .dynamic _edata
...
Symbol Table: .symtab
index value size type bind oth shndx name
[0] 0x000000000000 0x000000000000 NOTY LOCL 0 UNDEF
[1] 0x000000000000 0x000000000000 FILE LOCL 0 ABS t.so.1
...
[14] 0x0000000003c0 0x000000000000 NOTY LOCL 0 .text addr
[15] REG_G3 0x000000000000 REGI GLOB 0 UNDEF
[16] 0x000000100470 0x000000000000 OBJT GLOB 0 .bss _end
[17] 0x0000001003d0 0x000000000000 OBJT GLOB 0 .dynamic _DYNAMIC
[18] REG_G2 0x000000000000 REGI GLOB 0 UNDEF addrb
[19] 0x000000100470 0x000000000000 OBJT GLOB 0 .dynamic _edata
...
Dynamic Section: .dynamic
index tag value
[1] HASH 0xe8
[2] STRTAB 0x338
[3] STRSZ 0x85
[4] SYMTAB 0x170
[5] SYMENT 0x18
[6] FEATURE_1 0x1 [ PARINIT ]
[7] REGISTER 0xe
[8] REGISTER 0xb
ccc:~# elfdump t.o # Object file
ELF Header
ei_magic: { 0x7f, E, L, F }
ei_class: ELFCLASS64 ei_data: ELFDATA2MSB
e_machine: EM_SPARCV9 e_version: EV_CURRENT
e_type: ET_REL
e_flags: [ EF_SPARCV9_TSO EF_SPARC_SUN_US1 ]
e_entry: 0 e_ehsize: 64 e_shstrndx: 1
e_shoff: 0xc0 e_shentsize: 64 e_shnum: 5
e_phoff: 0 e_phentsize: 0 e_phnum: 0
...
Symbol Table: .symtab
index value size type bind oth shndx name
[0] 0x000000000000 0x000000000000 NOTY LOCL 0 UNDEF
[1] 0x000000000000 0x000000000000 SECT LOCL 0 .text
[2] REG_G2 0x000000000000 REGI GLOB 0 UNDEF address
>
> You have added code to handle them specially in the linker hash table.
> I don't think this is necessary. This is a case of linking symbols
> with special semantics. You don't need to remove those symbols
> entirely from the linking process; you just need to implement special
> semantics for them. We already have a hook for that:
> elf_add_symbol_hook. It can implement the special semantics for
> STT_REGISTER symbols, and then adjust its arguments to invoke some
> appropriately harmless set of standard semantics.
That's what I spoke about in the comment above the patch. I'd like to keep
it in the linker hash table, but hash table does not allow me to insert more
symbols with the same name, which I need in this case, because one can e.g.
declare
.register %g2, #scratch
.register %g3, #scratch
which means you'll have two symbols with empty name (which differ only by
st_value in the final output). I already use elf_add_symbol_hook in my
patch. I have to keep those symbols in my local structure anyway (because I
need to look up a STT_REGISTER symbol with a particular st_value, not name,
for the linking), so it was fairly easy to flush all those symbols out from
that table eventhough they don't live in the hash table. But if you allow
e.g. some function to insert a symbol into the hash table eventhough the
name is in there already, then they can live in the hash.
But it would probably need some hooks in output_extsym (especially because
of the SHN_UNDEF and STB_GLOBAL at the same time), so keeping it out of the
like it is done in many backends for some .dynsym entries seems cleaner to
me.
> --- ./bfd/bfd-in2.h.jj Tue Jun 29 10:46:31 1999
> +++ ./bfd/bfd-in2.h Wed Jun 30 12:37:16 1999
> @@ -2312,6 +2312,9 @@ typedef struct symbol_cache_entry
> + /* Processor specific symbol type. */
> +#define BSF_PROC 0x20000
> +
>
> I don't care for this. Changes to the generic ABI should ideally have
> a generic meaning. This does not. I also don't see why it is
> necessary to change the generic ABI in this manner, given the
> existence of elf_symbol_type.
Ok, I got rid of this. The new patch attached below.
It already creates the correct .dynsym entries and DT_SPARC_REGISTER
.dynamic entries pointing to it as ABI requires.
>
> These patches seem to have a bunch of code that don't seem to have
> anything to do with STT_REGISTER. Could you please submit that part
> of them separately, so that we can get them in without getting tangled
> up with extraneous issues? Thanks.
I have submitted that hunk two days ago in the OLO10 patch.
Anyway, here is the new patch, which I hope works as the ABI requires, at
least to the extent I have tested so far.
BTW: The change of DT_SPARC_REGISTER from 0x70000001 to 0x7000001 is not a
typo on my part, I suppose Sparc International made a typo in SYSV sparc64
ABI supplement but it got implemented like that into Solaris 7 linker :(, so
I guess we have to keep it compatible. It is outside of any processor
specific range, unfortunately.
1999-07-07 Jakub Jelinek <jj@ultra.linux.cz>
* bfd/elf-bfd.h (struct elf_backend_data): Add
print_symbol_all and output_arch_syms backend methods.
* bfd/elfxx-target.h: Likewise.
* bfd/elf64-sparc.c (sparc64_elf_bfd_link_hash_table_create,
sparc64_elf_add_symbol_hook, sparc64_elf_output_arch_syms,
sparc64_elf_get_symbol_type, sparc64_elf_symbol_processing): New
functions.
(sparc64_elf_size_dynamic_sections): Leave space for STT_REGISTER
symbols in .dynsym, add their names into .dynstr. Use generic
_bfd_elf_link_adjust_dynindx instead of sparc64_elf_adjust_dynindx).
(sparc64_elf_adjust_dynindx): Remove.
(sparc64_elf_finish_dynamic_sections): Output STT_REGISTER symbols
into .dynsym, fix up DT_SPARC_REGISTER pointers to them.
(sparc64_elf_print_symbol_all): New function.
* bfd/elf.c (bfd_elf_print_symbol): Allow special backend symbol
printing using the print_symbol_all hook.
* bfd/elflink.h (elf_bfd_final_link): Allow backend to emit some
global symbols which don't live in the symbol hash table.
* binutils/readelf.c (get_dynamic_type): Handle sparc
DT_SPARC_REGISTER printing.
* gas/config/tc-sparc.c (md_longopts): Add --no-undeclared-regs
option.
(sparc_ip): Warn if %g2 or %g3 register is used and not covered
by .register pseudo-op if -64 and --no-undeclared-regs.
(s_register, sparc_adjust_symtab): New functions.
* gas/config/tc-sparc.h (tc_adjust_symtab, sparc_adjust_symtab):
Declare sparc_adjust_symtab as tc_adjust_symtab.
* gas/doc/c-sparc.texi: Document .register and .nword pseudo-ops.
* include/elf/sparc.h: "Fix" DT_SPARC_REGISTER to match ABI and
Solaris linker.
--- ./bfd/elf-bfd.h.jj4 Tue Jun 29 10:46:50 1999
+++ ./bfd/elf-bfd.h Wed Jul 7 10:21:41 1999
@@ -517,6 +517,21 @@ struct elf_backend_data
void (*elf_backend_post_process_headers)
PARAMS ((bfd *, struct bfd_link_info *));
+ /* This function, if defined, prints a symbol to file and returns the
+ name of the symbol to be printed. It should return NULL to fall
+ back to default symbol printing. */
+ const char *(*elf_backend_print_symbol_all)
+ PARAMS ((bfd *, PTR, asymbol *));
+
+ /* This function, if defined, is called after all local symbols and
+ global symbols converted to locals are emited into the symtab
+ section. It allows the backend to emit special global symbols
+ not handled in the hash table. */
+ boolean (*elf_backend_output_arch_syms)
+ PARAMS ((struct bfd_link_info *, PTR,
+ boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *))));
+
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
--- ./bfd/elf64-sparc.c.jj4 Tue Jul 6 16:59:00 1999
+++ ./bfd/elf64-sparc.c Wed Jul 7 13:59:33 1999
@@ -32,6 +32,8 @@ Foundation, Inc., 59 Temple Place - Suit
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
#define MINUS_ONE (~ (bfd_vma) 0)
+static struct bfd_link_hash_table * sparc64_elf_bfd_link_hash_table_create
+ PARAMS((bfd *));
static reloc_howto_type *sparc64_elf_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
static void sparc64_elf_info_to_howto
@@ -51,8 +53,13 @@ static boolean sparc64_elf_adjust_dynami
PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
static boolean sparc64_elf_size_dynamic_sections
PARAMS((bfd *, struct bfd_link_info *));
-static boolean sparc64_elf_adjust_dynindx
- PARAMS((struct elf_link_hash_entry *, PTR));
+static int sparc64_elf_get_symbol_type
+ PARAMS (( Elf_Internal_Sym *, int));
+static boolean sparc64_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+static void sparc64_elf_symbol_processing
+ PARAMS ((bfd *, asymbol *));
static boolean sparc64_elf_merge_private_bfd_data
PARAMS ((bfd *, bfd *));
@@ -598,6 +605,54 @@ sparc64_elf_write_relocs (abfd, sec, dat
}
}
\f
+/* Sparc64 ELF linker hash table. */
+
+struct sparc64_elf_app_reg
+{
+ unsigned char bind;
+ unsigned short shndx;
+ bfd_size_type dynstr_index;
+ bfd *abfd;
+ char *name;
+};
+
+struct sparc64_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ struct sparc64_elf_app_reg app_regs [4];
+ int dynindx_reg_base;
+};
+
+/* Get the Sparc64 ELF linker hash table from a link_info structure. */
+
+#define sparc64_elf_hash_table(p) \
+ ((struct sparc64_elf_link_hash_table *) ((p)->hash))
+
+/* Create a Sparc64 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+sparc64_elf_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct sparc64_elf_link_hash_table *ret;
+
+ ret = ((struct sparc64_elf_link_hash_table *)
+ bfd_zalloc (abfd, sizeof (struct sparc64_elf_link_hash_table)));
+ if (ret == (struct sparc64_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+\f
/* Utility for performing the standard initial work of an instruction
relocation.
*PRELOCATION will contain the relocated item.
@@ -1198,6 +1253,202 @@ sparc64_elf_check_relocs (abfd, info, se
return true;
}
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it for STT_REGISTER symbols. */
+
+static boolean
+sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ static char *stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
+ {
+ int reg;
+ struct sparc64_elf_app_reg *p;
+
+ reg = (int)sym->st_value;
+ switch (reg & ~1)
+ {
+ case 2: reg -= 2; break;
+ case 6: reg -= 4; break;
+ default:
+ (*_bfd_error_handler)
+ (_("%s: Only registers %%g[2367] can be declared using STT_REGISTER"),
+ bfd_get_filename (abfd));
+ return false;
+ }
+
+ if (info->hash->creator != abfd->xvec
+ || (abfd->flags & DYNAMIC) != 0)
+ {
+ /* STT_REGISTER only works when linking an elf64_sparc object.
+ If STT_REGISTER comes from a dynamic object, don't put it into
+ the output bfd. The dynamic linker will recheck it. */
+ *namep = NULL;
+ return true;
+ }
+
+ p = sparc64_elf_hash_table(info)->app_regs + reg;
+
+ if (p->name != NULL && strcmp (p->name, *namep))
+ {
+ (*_bfd_error_handler)
+ (_("Register %%g%d used incompatibly: "
+ "previously declared in %s to %s, in %s redefined to %s"),
+ (int)sym->st_value,
+ bfd_get_filename (p->abfd), *p->name ? p->name : "#scratch",
+ bfd_get_filename (abfd), **namep ? *namep : "#scratch");
+ return false;
+ }
+
+ if (p->name == NULL)
+ {
+ if (**namep)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, *namep, false, false, false);
+
+ if (h != NULL)
+ {
+ unsigned char type = h->type;
+
+ if (type > STT_FUNC) type = 0;
+ (*_bfd_error_handler)
+ (_("Symbol `%s' has differing types: "
+ "previously %s, REGISTER in %s"),
+ *namep, stt_types [type], bfd_get_filename (abfd));
+ return false;
+ }
+
+ p->name = bfd_hash_allocate (&info->hash->table,
+ strlen (*namep) + 1);
+ if (!p->name)
+ return false;
+
+ strcpy (p->name, *namep);
+ }
+ else
+ p->name = "";
+ p->bind = ELF_ST_BIND (sym->st_info);
+ p->abfd = abfd;
+ p->shndx = sym->st_shndx;
+ }
+ else
+ {
+ if (p->bind == STB_WEAK
+ && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
+ {
+ p->bind = STB_GLOBAL;
+ p->abfd = abfd;
+ }
+ }
+ *namep = NULL;
+ return true;
+ }
+ else if (! *namep || ! **namep)
+ return true;
+ else
+ {
+ int i;
+ struct sparc64_elf_app_reg *p;
+
+ p = sparc64_elf_hash_table(info)->app_regs;
+ for (i = 0; i < 4; i++, p++)
+ if (p->name != NULL && ! strcmp (p->name, *namep))
+ {
+ unsigned char type = ELF_ST_TYPE (sym->st_info);
+
+ if (type > STT_FUNC) type = 0;
+ (*_bfd_error_handler)
+ (_("Symbol `%s' has differing types: "
+ "REGISTER in %s, %s in %s"),
+ *namep, bfd_get_filename (p->abfd), stt_types [type],
+ bfd_get_filename (abfd));
+ return false;
+ }
+ }
+ return true;
+}
+
+/* This function takes care of emmiting STT_REGISTER symbols
+ which we cannot easily keep in the symbol hash table. */
+
+static boolean
+sparc64_elf_output_arch_syms (info, finfo, func)
+ struct bfd_link_info *info;
+ PTR finfo;
+ boolean (*func) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *));
+{
+ int reg;
+ struct sparc64_elf_app_reg *app_regs =
+ sparc64_elf_hash_table(info)->app_regs;
+ Elf_Internal_Sym sym;
+
+ if (info->strip == strip_all)
+ return true;
+
+ for (reg = 0; reg < 4; reg++)
+ if (app_regs [reg].name != NULL)
+ {
+ if (info->strip == strip_some
+ && bfd_hash_lookup (info->keep_hash,
+ app_regs [reg].name,
+ false, false) == NULL)
+ continue;
+
+ sym.st_value = reg < 2 ? reg + 2 : reg + 4;
+ sym.st_size = 0;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
+ sym.st_shndx = app_regs [reg].shndx;
+ if (! (*func) (finfo, app_regs [reg].name, &sym,
+ sym.st_shndx == SHN_ABS
+ ? bfd_abs_section_ptr : bfd_und_section_ptr))
+ return false;
+ }
+
+ return true;
+}
+
+static int
+sparc64_elf_get_symbol_type (elf_sym, type)
+ Elf_Internal_Sym * elf_sym;
+ int type;
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
+ return STT_REGISTER;
+ else
+ return type;
+}
+
+/* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
+ even in SHN_UNDEF section. */
+
+static void
+sparc64_elf_symbol_processing (abfd, asym)
+ bfd *abfd;
+ asymbol *asym;
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ if (elfsym->internal_elf_sym.st_info
+ == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
+ {
+ asym->flags |= BSF_GLOBAL;
+ }
+}
+
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
@@ -1497,6 +1748,9 @@ sparc64_elf_size_dynamic_sections (outpu
must add the entries now so that we get the correct size for
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
+ int i, c;
+ struct sparc64_elf_app_reg * app_regs;
+
if (! info->shared)
{
if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
@@ -1525,6 +1779,44 @@ sparc64_elf_size_dynamic_sections (outpu
if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
return false;
}
+
+ /* Add dynamic STT_REGISTER symbols and corresponding DT_SPARC_REGISTER
+ entries if needed. */
+ app_regs = sparc64_elf_hash_table (info)->app_regs;
+ c = 0;
+ for (i = 0; i < 4; i++)
+ if (app_regs [i].name != NULL)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_SPARC_REGISTER, 0))
+ return false;
+ c++;
+ }
+
+ if (c)
+ {
+ struct bfd_strtab_hash *dynstr;
+
+ dynstr = elf_hash_table (info)->dynstr;
+ BFD_ASSERT (dynstr != NULL);
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_link_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+
+ for (i = 0; i < 4; i++)
+ if (app_regs [i].name != NULL
+ && *app_regs [i].name != '\0')
+ {
+ app_regs [i].dynstr_index =
+ _bfd_stringtab_add (dynstr, app_regs [i].name, true, false);
+ if (app_regs [i].dynstr_index == (bfd_size_type) -1)
+ return false;
+ }
+
+ /* The first symbol in .dynsym is a dummy. */
+ sparc64_elf_hash_table (info)->dynindx_reg_base = 1;
+ }
}
/* If we are generating a shared library, we generate a section
@@ -1552,29 +1844,15 @@ sparc64_elf_size_dynamic_sections (outpu
}
elf_link_hash_traverse (elf_hash_table (info),
- sparc64_elf_adjust_dynindx,
+ _bfd_elf_link_adjust_dynindx,
(PTR) &c);
elf_hash_table (info)->dynsymcount += c;
+ sparc64_elf_hash_table (info)->dynindx_reg_base += c;
}
return true;
}
-/* Increment the index of a dynamic symbol by a given amount. Called
- via elf_link_hash_traverse. */
-
-static boolean
-sparc64_elf_adjust_dynindx (h, cparg)
- struct elf_link_hash_entry *h;
- PTR cparg;
-{
- int *cp = (int *) cparg;
-
- if (h->dynindx != -1)
- h->dynindx += *cp;
- return true;
-}
-
\f
/* Relocate a SPARC64 ELF section. */
@@ -2398,6 +2676,7 @@ sparc64_elf_finish_dynamic_sections (out
bfd *dynobj;
asection *sdyn;
asection *sgot;
+ Elf64_External_Dyn *dt_register_dyn = NULL;
dynobj = elf_hash_table (info)->dynobj;
@@ -2426,6 +2705,10 @@ sparc64_elf_finish_dynamic_sections (out
case DT_PLTGOT: name = ".plt"; size = false; break;
case DT_PLTRELSZ: name = ".rela.plt"; size = true; break;
case DT_JMPREL: name = ".rela.plt"; size = false; break;
+ case DT_SPARC_REGISTER:
+ if (dt_register_dyn == NULL)
+ dt_register_dyn = dyncon;
+ /* fallthrough */
default: name = NULL; size = false; break;
}
@@ -2523,6 +2806,53 @@ sparc64_elf_finish_dynamic_sections (out
elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
}
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ int reg;
+ struct sparc64_elf_app_reg *app_regs =
+ sparc64_elf_hash_table(info)->app_regs;
+ asection *sdynsym;
+ Elf_Internal_Sym sym;
+ Elf_Internal_Dyn dyn;
+ int c = sparc64_elf_hash_table (info)->dynindx_reg_base;
+
+ /* Set up the STT_REGISTER dynamic symbols. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_other = 0;
+
+ for (reg = 0; reg < 4; reg++)
+ if (app_regs [reg].name != NULL)
+ {
+ sym.st_value = reg < 2 ? reg + 2 : reg + 4;
+ sym.st_size = 0;
+ sym.st_name = app_regs [reg].dynstr_index;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
+ sym.st_shndx = app_regs [reg].shndx;
+ bfd_elf64_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf64_External_Sym *)
+ sdynsym->contents)
+ + c));
+ if (dt_register_dyn == NULL)
+ return false;
+
+ bfd_elf64_swap_dyn_in (dynobj, dt_register_dyn, &dyn);
+
+ if (dyn.d_tag != DT_SPARC_REGISTER)
+ return false;
+
+ dyn.d_un.d_val = c;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dt_register_dyn);
+
+ ++dt_register_dyn;
+ ++c;
+ }
+ }
+
return true;
}
\f
@@ -2599,7 +2929,34 @@ sparc64_elf_merge_private_bfd_data (ibfd
}
return true;
}
+\f
+/* Print a STT_REGISTER symbol to file FILE. */
+static const char *
+sparc64_elf_print_symbol_all (abfd, filep, symbol)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+{
+ FILE *file = (FILE *) filep;
+ int reg, type;
+
+ if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
+ != STT_REGISTER)
+ return NULL;
+
+ reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+ type = symbol->flags;
+ fprintf (file, "REG_%c%c%11s%c%c R", "GOLI" [reg / 8], '0' + (reg & 7), "",
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ');
+ if (symbol->name == NULL || symbol->name [0] == '\0')
+ return "#scratch";
+ else
+ return symbol->name;
+}
\f
/* Set the right machine number for a SPARC64 ELF file. */
@@ -2653,6 +3010,9 @@ const struct elf_size_info sparc64_elf_s
/* This is the value that we used before the ABI was released. */
#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
+#define bfd_elf64_bfd_link_hash_table_create \
+ sparc64_elf_bfd_link_hash_table_create
+
#define elf_info_to_howto \
sparc64_elf_info_to_howto
#define bfd_elf64_get_reloc_upper_bound \
@@ -2666,6 +3026,12 @@ const struct elf_size_info sparc64_elf_s
#define elf_backend_create_dynamic_sections \
_bfd_elf_create_dynamic_sections
+#define elf_backend_add_symbol_hook \
+ sparc64_elf_add_symbol_hook
+#define elf_backend_get_symbol_type \
+ sparc64_elf_get_symbol_type
+#define elf_backend_symbol_processing \
+ sparc64_elf_symbol_processing
#define elf_backend_check_relocs \
sparc64_elf_check_relocs
#define elf_backend_adjust_dynamic_symbol \
@@ -2678,6 +3044,10 @@ const struct elf_size_info sparc64_elf_s
sparc64_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
sparc64_elf_finish_dynamic_sections
+#define elf_backend_print_symbol_all \
+ sparc64_elf_print_symbol_all
+#define elf_backend_output_arch_syms \
+ sparc64_elf_output_arch_syms
#define bfd_elf64_bfd_merge_private_bfd_data \
sparc64_elf_merge_private_bfd_data
--- ./bfd/elf.c.jj4 Tue Jun 29 10:47:02 1999
+++ ./bfd/elf.c Wed Jul 7 09:47:57 1999
@@ -756,8 +756,21 @@ bfd_elf_print_symbol (abfd, filep, symbo
case bfd_print_symbol_all:
{
CONST char *section_name;
+ CONST char *name = NULL;
+ struct elf_backend_data *bed;
+
section_name = symbol->section ? symbol->section->name : "(*none*)";
- bfd_print_symbol_vandf ((PTR) file, symbol);
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_print_symbol_all)
+ name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
+
+ if (name == NULL)
+ {
+ name = symbol->name;
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ }
+
fprintf (file, " %s\t", section_name);
/* Print the "other" value for a symbol. For common symbols,
we've already printed the size; now print the alignment.
@@ -825,7 +838,7 @@ bfd_elf_print_symbol (abfd, filep, symbo
((unsigned int)
((elf_symbol_type *) symbol)->internal_elf_sym.st_other));
- fprintf (file, " %s", symbol->name);
+ fprintf (file, " %s", name);
}
break;
}
--- ./bfd/elflink.h.jj4 Tue Jun 29 10:47:22 1999
+++ ./bfd/elflink.h Sat Jul 3 21:43:13 1999
@@ -4064,6 +4064,18 @@ elf_bfd_final_link (abfd, info)
if (eoinfo.failed)
return false;
+ /* If backend needs to output some symbols not present in the hash
+ table, do it now. */
+ if (bed->elf_backend_output_arch_syms)
+ {
+ if (! (*bed->elf_backend_output_arch_syms)
+ (info, (PTR) &finfo,
+ (boolean (*) PARAMS ((PTR, const char *,
+ Elf_Internal_Sym *, asection *)))
+ elf_link_output_sym))
+ return false;
+ }
+
/* Flush all symbols to the file. */
if (! elf_link_flush_output_syms (&finfo))
return false;
--- ./bfd/elfxx-target.h.jj4 Wed Jun 9 09:51:35 1999
+++ ./bfd/elfxx-target.h Sat Jul 3 21:07:17 1999
@@ -294,6 +294,12 @@ Foundation, Inc., 59 Temple Place - Suit
#ifndef elf_backend_post_process_headers
#define elf_backend_post_process_headers NULL
#endif
+#ifndef elf_backend_print_symbol_all
+#define elf_backend_print_symbol_all NULL
+#endif
+#ifndef elf_backend_output_arch_syms
+#define elf_backend_output_arch_syms NULL
+#endif
/* Previously, backends could only use SHT_REL or SHT_RELA relocation
sections, but not both. They defined USE_REL to indicate SHT_REL
@@ -366,6 +372,8 @@ static CONST struct elf_backend_data elf
elf_backend_gc_mark_hook,
elf_backend_gc_sweep_hook,
elf_backend_post_process_headers,
+ elf_backend_print_symbol_all,
+ elf_backend_output_arch_syms,
elf_backend_ecoff_debug_swap,
ELF_MACHINE_ALT1,
ELF_MACHINE_ALT2,
--- ./binutils/readelf.c.jj4 Mon Jul 5 14:55:30 1999
+++ ./binutils/readelf.c Wed Jul 7 12:16:31 1999
@@ -899,6 +899,10 @@ get_dynamic_type (type)
}
else if ((type >= DT_LOOS) && (type <= DT_HIOS))
sprintf (buff, _("Operating System specific: %lx"), type);
+ else if (type == DT_SPARC_REGISTER
+ && elf_header.e_machine == EM_SPARCV9)
+ /* Why this allocation could not go into the LOPROC-HIPROC area? */
+ return "SPARC_REGISTER";
else
sprintf (buff, _("<unknown>: %lx"), type);
--- ./gas/config/tc-sparc.c.jj4 Wed Jul 7 09:41:46 1999
+++ ./gas/config/tc-sparc.c Wed Jul 7 13:36:13 1999
@@ -87,6 +87,10 @@ static int warn_on_bump;
architecture, issue a warning. */
static enum sparc_opcode_arch_val warn_after_architecture;
+/* Non-zero if as should generate error if an undeclared g[23] register
+ has been used in -64. */
+static int no_undeclared_regs;
+
/* Non-zero if we are generating PIC code. */
int sparc_pic_code;
@@ -97,6 +101,9 @@ extern int target_big_endian;
static int target_little_endian_data;
+/* Symbols for global registers on v9. */
+static symbolS *globals[8];
+
/* V9 and 86x have big and little endian data, but instructions are always big
endian. The sparclet has bi-endian support but both data and insns have
the same endianness. Global `target_big_endian' is used for data.
@@ -119,6 +126,7 @@ static void s_common PARAMS ((int));
static void s_empty PARAMS ((int));
static void s_uacons PARAMS ((int));
static void s_ncons PARAMS ((int));
+static void s_register PARAMS ((int));
const pseudo_typeS md_pseudo_table[] =
{
@@ -143,6 +151,7 @@ const pseudo_typeS md_pseudo_table[] =
{"2byte", s_uacons, 2},
{"4byte", s_uacons, 4},
{"8byte", s_uacons, 8},
+ {"register", s_register, 0},
#endif
{NULL, 0, 0},
};
@@ -400,6 +409,10 @@ struct option md_longopts[] = {
{"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
{"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
+#ifdef OBJ_ELF
+#define OPTION_NO_UNDECLARED_REGS (OPTION_MD_BASE + 12)
+ {"no-undeclared-regs", no_argument, NULL, OPTION_NO_UNDECLARED_REGS},
+#endif
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
@@ -549,6 +562,10 @@ md_parse_option (c, arg)
else
sparc_pic_code = 1;
break;
+
+ case OPTION_NO_UNDECLARED_REGS:
+ no_undeclared_regs = 1;
+ break;
#endif
default:
@@ -1865,6 +1882,11 @@ sparc_ip (str, pinsn)
goto error;
}
+ if ((mask & ~1) == 2 && sparc_arch_size == 64
+ && no_undeclared_regs && ! globals [mask])
+ as_bad (_("detected global register use not "
+ "covered by .register pseudo-op"));
+
/* Got the register, now figure out where
it goes in the opcode. */
switch (*args)
@@ -3706,6 +3728,112 @@ s_ncons (bytes)
{
cons (sparc_arch_size == 32 ? 4 : 8);
}
+
+#ifdef OBJ_ELF
+/* Handle the SPARC ELF .register pseudo-op. This sets the binding of a
+ global register.
+ The syntax is:
+
+ .register %g[2367],{#scratch|symbolname}
+ */
+
+static void
+s_register (ignore)
+ int ignore;
+{
+ char c;
+ int reg;
+ int flags;
+ const char *regname;
+
+ if (input_line_pointer[0] != '%'
+ || input_line_pointer[1] != 'g'
+ || ((input_line_pointer[2] & ~1) != '2'
+ && (input_line_pointer[2] & ~1) != '6')
+ || input_line_pointer[3] != ',')
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname}"));
+ reg = input_line_pointer[2] - '0';
+ input_line_pointer += 4;
+
+ if (*input_line_pointer == '#')
+ {
+ ++input_line_pointer;
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcmp (regname, "scratch"))
+ as_bad (_("register syntax is .register %%g[2367],{#scratch|symbolname}"));
+ regname = "";
+ }
+ else
+ {
+ regname = input_line_pointer;
+ c = get_symbol_end ();
+ }
+ if (sparc_arch_size == 64)
+ {
+ if (globals [reg])
+ {
+ if (strcmp (S_GET_NAME (globals [reg]), regname))
+ as_bad (_("redefinition of global register"));
+ }
+ else
+ {
+ if (*regname)
+ {
+ if (symbol_find (regname))
+ as_bad (_("Register symbol %s already defined."), regname);
+ }
+ globals [reg] = symbol_make (regname);
+ flags = symbol_get_bfdsym (globals [reg])->flags;
+ if (! *regname)
+ flags = flags & ~(BSF_GLOBAL|BSF_LOCAL|BSF_WEAK);
+ if (! (flags & (BSF_GLOBAL|BSF_LOCAL|BSF_WEAK)))
+ flags |= BSF_GLOBAL;
+ symbol_get_bfdsym (globals [reg])->flags = flags;
+ S_SET_VALUE (globals [reg], (valueT)reg);
+ S_SET_ALIGN (globals [reg], reg);
+ S_SET_SIZE (globals [reg], 0);
+ /* Although we actually want undefined_section here,
+ we have to use absolute_section, because otherwise
+ generic as code will make it a COM section.
+ We fix this up in sparc_adjust_symtab. */
+ S_SET_SEGMENT (globals [reg], absolute_section);
+ S_SET_OTHER (globals [reg], 0);
+ elf_symbol (symbol_get_bfdsym (globals [reg]))
+ ->internal_elf_sym.st_info =
+ ELF_ST_INFO(STB_GLOBAL, STT_REGISTER);
+ elf_symbol (symbol_get_bfdsym (globals [reg]))
+ ->internal_elf_sym.st_shndx = SHN_UNDEF;
+ }
+ }
+
+ *input_line_pointer = c;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Adjust the symbol table. We set undefined sections for STT_REGISTER
+ symbols which need it. */
+
+void
+sparc_adjust_symtab ()
+{
+ symbolS *sym;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ELF_ST_TYPE (elf_symbol (symbol_get_bfdsym (sym))
+ ->internal_elf_sym.st_info) != STT_REGISTER)
+ continue;
+
+ if (ELF_ST_TYPE (elf_symbol (symbol_get_bfdsym (sym))
+ ->internal_elf_sym.st_shndx != SHN_UNDEF))
+ continue;
+
+ S_SET_SEGMENT (sym, undefined_section);
+ }
+}
+#endif
/* If the --enforce-aligned-data option is used, we require .word,
et. al., to be aligned correctly. We do it by setting up an
--- ./gas/config/tc-sparc.h.jj4 Mon Jul 5 14:15:17 1999
+++ ./gas/config/tc-sparc.h Wed Jul 7 13:35:50 1999
@@ -134,6 +134,10 @@ extern int elf32_sparc_force_relocation
== S_GET_SEGMENT ((FIX)->fx_addsy))) \
|| strchr (S_GET_NAME ((FIX)->fx_addsy), '\001') != NULL \
|| strchr (S_GET_NAME ((FIX)->fx_addsy), '\002') != NULL))
+
+/* Finish up the entire symtab. */
+#define tc_adjust_symtab() sparc_adjust_symtab ()
+extern void sparc_adjust_symtab PARAMS ((void));
#endif
#ifdef OBJ_AOUT
--- ./gas/doc/c-sparc.texi.jj4 Mon May 3 09:28:45 1999
+++ ./gas/doc/c-sparc.texi Sat Jul 3 18:38:25 1999
@@ -145,11 +145,24 @@ syntax is different.
@item .half
This is functionally identical to @code{.short}.
+@cindex @code{nword} directive, SPARC
+@item .nword
+On the Sparc, the @code{.nword} directive produces native word sized value,
+ie. if assembling with -32 it is equivalent to @code{.word}, if assembling
+with -64 it is equivalent to @code{.xword}.
+
@cindex @code{proc} directive, SPARC
@item .proc
This directive is ignored. Any text following it on the same
line is also ignored.
+@cindex @code{register} directive, SPARC
+@item .register
+This directive declares use of a global application or system register.
+It must be followed by a register name %g2, %g3, %g6 or %g7, comma and
+the symbol name for that register or @code{#scratch} if it is a scratch
+register.
+
@cindex @code{reserve} directive, SPARC
@item .reserve
This must be followed by a symbol name, a positive number, and
@@ -176,4 +189,3 @@ instead of the 16 bit values it produces
On the Sparc V9 processor, the @code{.xword} directive produces
64 bit values.
@end table
-
--- ./include/elf/sparc.h.jj4 Mon Jul 5 14:44:35 1999
+++ ./include/elf/sparc.h Wed Jul 7 12:08:04 1999
@@ -143,7 +143,7 @@ END_RELOC_NUMBERS
#define ELF64_R_TYPE_INFO(data, type) (((((bfd_vma) (data)) & 0xffffff) << 8) \
+ (bfd_vma) (type))
-#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_REGISTER 0x07000001
/*
* FIXME: NOT ABI -- GET RID OF THIS
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
UltraLinux | http://ultra.linux.cz/ | http://ultra.penguin.cz/
Linux version 2.3.9 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Support for SPARC STT_REGISTER
1999-07-07 5:45 ` Jakub Jelinek
@ 1999-07-08 11:30 ` Richard Henderson
0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 1999-07-08 11:30 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Ian Lance Taylor, binutils
On Wed, Jul 07, 1999 at 02:45:30PM +0200, Jakub Jelinek wrote:
> Anyway, here is the new patch, which I hope works as the ABI requires, at
> least to the extent I have tested so far.
Ian, you started revewing this. May I assume you'll finish?
I think it's ok. Kinda gross, having to do those sorts of
things with the symbols, but the problem is kinda gross too
so I don't think there's a way around it.
> BTW: The change of DT_SPARC_REGISTER from 0x70000001 to 0x7000001 is not a
> typo on my part, I suppose Sparc International made a typo in SYSV sparc64
> ABI supplement but it got implemented like that into Solaris 7 linker :(, so
> I guess we have to keep it compatible.
Jakub, did you contact Steve Chessin about this? Surely we
can get them to ack the bug and patch the linker.
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~1999-07-08 11:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-04 11:59 Support for SPARC STT_REGISTER Jakub Jelinek
1999-07-06 18:47 ` Ian Lance Taylor
1999-07-07 5:45 ` Jakub Jelinek
1999-07-08 11:30 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).