Initial revision
authorSteve Chamberlain <steve@cygnus>
Thu, 1 Aug 1991 23:29:03 +0000 (23:29 +0000)
committerSteve Chamberlain <steve@cygnus>
Thu, 1 Aug 1991 23:29:03 +0000 (23:29 +0000)
ld/ldindr.c [new file with mode: 0644]
ld/ldindr.h [new file with mode: 0644]
ld/ldwarn.c [new file with mode: 0644]

diff --git a/ld/ldindr.c b/ld/ldindr.c
new file mode 100644 (file)
index 0000000..8e19842
--- /dev/null
@@ -0,0 +1,58 @@
+/* ldindr.c
+   Handle indirect symbols.
+
+   BFD supplies symbols to be indirected with the BFD_INDIRECT bit
+   set. Whenever the linker gets one of these, it calls add_indirect
+   with the symbol. We create an entry into the ldsym hash table as if it
+   were a normal symbol, but with the SYM_INDIRECT bit set in the
+   flags.
+
+   When it comes time to tie up the symbols at a later date, the flag
+   will be seen and a call made to do the right thing (tm)
+
+*/
+
+
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "ld.h"
+#include "ldsym.h"
+
+extern ld_config_type config;
+void 
+DEFUN(add_indirect,(ptr),
+asymbol **ptr)
+{
+  if (config.relocateable_output == false) {
+    ldsym_type *sp = ldsym_get((*ptr)->name);
+    sp->flags |= SYM_INDIRECT;
+    sp->sdefs_chain = ptr;
+  }
+}
+
+
+
+void 
+DEFUN(do_indirect,(ptr),
+ldsym_type *ptr)
+{
+if (config.relocateable_output == false) {
+  /* Dig out the symbol were indirecting to. It's held in the value
+     field. 
+     */
+
+
+  CONST char *name = ((asymbol *)(*(ptr->sdefs_chain))->value)->name;
+
+  ldsym_type *new = ldsym_get(name);
+
+  /* We have to make a copy of the sdefs_chain item name, since
+     symbols will be clobbered on writing, and we want to write the
+     same string twice */
+
+
+  ptr->sdefs_chain[0][0] = new->sdefs_chain[0][0];
+  ptr->sdefs_chain[0][0].name = name;
+}
+}
diff --git a/ld/ldindr.h b/ld/ldindr.h
new file mode 100644 (file)
index 0000000..209c8cf
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+void EXFUN(do_indirect, (ldsym_type *));
+void EXFUN(add_indirect,(asymbol *));
diff --git a/ld/ldwarn.c b/ld/ldwarn.c
new file mode 100644 (file)
index 0000000..c22f36b
--- /dev/null
@@ -0,0 +1,72 @@
+#include "sysdep.h"
+#include "bfd.h"
+#include "ldsym.h"
+
+
+/* we keep all the warning symbols in a list, if we ever get a
+   warning, we'll search it the hard way. This won't be to bad since
+   warnings are infrequent, and never that many (true or false ?).
+
+*/
+
+typedef struct warning_list_struct {
+  struct warning_list_struct *next;
+  asymbol *sym;
+} warning_list_type;
+
+
+static warning_list_type *warning_list;
+
+
+
+/* This is a warning symbol, add the error text to a list we keep, and mark
+   the symbol referenced as requiring a warning */
+
+
+void 
+DEFUN(add_warning,(sym),
+      asymbol *sym)
+{
+  CONST    char *name = ((asymbol *)(sym->value))->name;
+  warning_list_type *new;
+
+  ldsym_type *lookup = ldsym_get(name);
+
+  lookup->flags |= SYM_WARNING;
+
+  new = (warning_list_type *)ldmalloc(sizeof(warning_list_type));
+  new->next = warning_list;
+  new->sym  = sym;
+  warning_list = new;
+}
+
+/* run through the list we kept, and find the warning associated with
+   this symbol */
+CONST char *
+DEFUN(fetch_warning,(sym),
+asymbol *sym)
+{
+  warning_list_type *ptr = warning_list;
+  while (ptr != (warning_list_type *)NULL) {
+    if (strcmp(((asymbol*)(ptr->sym->value))->name, sym->name) == 0) {
+      return ptr->sym->name;
+    }
+    ptr = ptr->next;
+  }
+  return "This is a warning without a message !";
+}
+
+
+void 
+DEFUN(produce_warnings,(lgs,it),
+      ldsym_type *lgs AND
+      asymbol *it)
+{
+  asymbol **ptr;
+  ptr  = lgs->srefs_chain;
+  while (ptr != (asymbol **)NULL) {
+    asymbol *ref = *ptr;
+    info("%B: %s\n", ref->the_bfd, fetch_warning(it));
+    ptr = (asymbol **)(ref->udata);
+  }
+}