clarify error message (nobody understood the old one)
[unix-history] / usr / src / usr.bin / ld / ld.c
index 223f5ea..db2207d 100644 (file)
@@ -1,6 +1,13 @@
-/*     @(#)ld.c        6.2 (Berkeley) %G%
+/*-
+ * This code is derived from software copyrighted by the Free Software
+ * Foundation.
+ *
+ * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
+ */
 
 
-Modified for Berkeley Unix by Donn Seeley, donn@okeeffe.berkeley.edu  */
+#ifndef lint
+static char sccsid[] = "@(#)ld.c       6.10 (Berkeley) %G%";
+#endif /* not lint */
 
 /* Linker `ld' for GNU
    Copyright (C) 1988 Free Software Foundation, Inc.
 
 /* Linker `ld' for GNU
    Copyright (C) 1988 Free Software Foundation, Inc.
@@ -68,13 +75,6 @@ char *progname;
 #define DEFAULT_MAGIC ZMAGIC
 #endif
 
 #define DEFAULT_MAGIC ZMAGIC
 #endif
 
-/* Ordinary 4.3bsd lacks these macros in a.out.h.  */
-
-#define N_TXTADDR(X) 0
-#define N_DATADDR(x) \
-    (((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
-    : (page_size+((N_TXTADDR(x)+(x).a_text-1) & ~(page_size-1))))
-
 #ifdef hp300
 #define        INITIALIZE_HEADER       outheader.a_mid = MID_HP300
 #endif
 #ifdef hp300
 #define        INITIALIZE_HEADER       outheader.a_mid = MID_HP300
 #endif
@@ -982,6 +982,7 @@ decode_command (argc, argv)
 {
   register int i;
   register struct file_entry *p;
 {
   register int i;
   register struct file_entry *p;
+  char *cp;
 
   number_of_files = 0;
   output_filename = "a.out";
 
   number_of_files = 0;
   output_filename = "a.out";
@@ -1045,7 +1046,15 @@ decode_command (argc, argv)
            }
          if (argv[i][1] == 'l')
            {
            }
          if (argv[i][1] == 'l')
            {
-             p->filename = concat ("lib", string, ".a");
+             if (cp = rindex(string, '/'))
+               {
+                 *cp++ = '\0';
+                 cp = concat (string, "/lib", cp);
+                 p->filename = concat (cp, ".a", "");
+               }
+             else
+               p->filename = concat ("lib", string, ".a");
+
              p->local_sym_name = concat ("-l", string, "");
              p->search_dirs_flag = 1;
              p++;
              p->local_sym_name = concat ("-l", string, "");
              p->search_dirs_flag = 1;
              p++;
@@ -2059,7 +2068,7 @@ symdef_library (desc, entry, member_length)
 
   if (length_of_strings < 0
       || number_of_symdefs * sizeof (struct symdef) + length_of_strings
 
   if (length_of_strings < 0
       || number_of_symdefs * sizeof (struct symdef) + length_of_strings
-         + 2 * sizeof (int) != member_length)
+         + 2 * sizeof (int) > member_length)
     fatal_with_file ("malformatted __.SYMDEF in ", entry);
 
   sym_name_base = sizeof (int) + (char *) (symdef_base + number_of_symdefs);
     fatal_with_file ("malformatted __.SYMDEF in ", entry);
 
   sym_name_base = sizeof (int) + (char *) (symdef_base + number_of_symdefs);
@@ -2336,11 +2345,7 @@ digest_symbols ()
   /* If necessary, pad text section to full page in the file.
      Include the padding in the text segment size.  */
 
   /* If necessary, pad text section to full page in the file.
      Include the padding in the text segment size.  */
 
-#ifdef NMAGIC
-  if (magic == ZMAGIC || magic == NMAGIC)
-#else
   if (magic == ZMAGIC)
   if (magic == ZMAGIC)
-#endif
     {
       int text_end = text_size + N_TXTOFF (outheader);
       text_pad = ((text_end + page_size - 1) & (- page_size)) - text_end;
     {
       int text_end = text_size + N_TXTOFF (outheader);
       text_pad = ((text_end + page_size - 1) & (- page_size)) - text_end;
@@ -3686,22 +3691,71 @@ perform_relocation (data, pc_relocation, data_size, reloc_info, reloc_size, entr
          break;
 
        case 1:
          break;
 
        case 1:
-         if (RELOC_MEMORY_SUB_P(p))
-           relocation -= mask & *(short *) (data + addr);
-         else if (RELOC_MEMORY_ADD_P(p))
-           relocation += mask & *(short *) (data + addr);
-         *(short *) (data + addr) &= ~mask;
-         *(short *) (data + addr) |= relocation;
+#ifdef tahoe
+         if (((int) data + addr & 1) == 0)
+           {
+#endif
+             if (RELOC_MEMORY_SUB_P(p))
+               relocation -= mask & *(short *) (data + addr);
+             else if (RELOC_MEMORY_ADD_P(p))
+               relocation += mask & *(short *) (data + addr);
+             *(short *) (data + addr) &= ~mask;
+             *(short *) (data + addr) |= relocation;
+#ifdef tahoe
+           }
+         /*
+          * The CCI Power 6 (aka Tahoe) architecture has byte-aligned
+          * instruction operands but requires data accesses to be aligned.
+          * Brain-damage...
+          */
+         else
+           {
+             unsigned char *da = (unsigned char *) (data + addr);
+             unsigned short s = da[0] << 8 | da[1];
+
+             if (RELOC_MEMORY_SUB_P(p))
+               relocation -= mask & s;
+             else if (RELOC_MEMORY_ADD_P(p))
+               relocation += mask & s;
+             s &= ~mask;
+             s |= relocation;
+             da[0] = s >> 8;
+             da[1] = s;
+           }
+#endif
          break;
 
        case 2:
 #ifndef _CROSS_TARGET_ARCH
          break;
 
        case 2:
 #ifndef _CROSS_TARGET_ARCH
-         if (RELOC_MEMORY_SUB_P(p))
-           relocation -= mask & *(long *) (data + addr);
-         else if (RELOC_MEMORY_ADD_P(p))
-           relocation += mask & *(long *) (data + addr);
-         *(long *) (data + addr) &= ~mask;
-         *(long *) (data + addr) |= relocation;
+#ifdef tahoe
+         if (((int) data + addr & 3) == 0)
+           {
+#endif
+             if (RELOC_MEMORY_SUB_P(p))
+               relocation -= mask & *(long *) (data + addr);
+             else if (RELOC_MEMORY_ADD_P(p))
+               relocation += mask & *(long *) (data + addr);
+             *(long *) (data + addr) &= ~mask;
+             *(long *) (data + addr) |= relocation;
+#ifdef tahoe
+           }
+         else
+           {
+             unsigned char *da = (unsigned char *) (data + addr);
+             unsigned long l = da[0] << 24 | da[1] << 16 | da[2] << 8 | da[3];
+
+             if (RELOC_MEMORY_SUB_P(p))
+               relocation -= mask & l;
+             else if (RELOC_MEMORY_ADD_P(p))
+               relocation += mask & l;
+             l &= ~mask;
+             l |= relocation;
+             da[0] = l >> 24;
+             da[1] = l >> 16;
+             da[2] = l >> 8;
+             da[3] = l;
+           }
+#endif
 #else
        /* Handle long word alignment requirements of SPARC architecture */
        /* WARNING:  This fix makes an assumption on byte ordering */
 #else
        /* Handle long word alignment requirements of SPARC architecture */
        /* WARNING:  This fix makes an assumption on byte ordering */
@@ -4085,7 +4139,7 @@ write_syms ()
            if (nl.n_type == (N_INDR | N_EXT))
              {
                struct nlist xtra_ref;
            if (nl.n_type == (N_INDR | N_EXT))
              {
                struct nlist xtra_ref;
-               xtra_ref.n_type == N_EXT | N_UNDF;
+               xtra_ref.n_type = N_EXT | N_UNDF;
                xtra_ref.n_un.n_strx
                  = assign_string_table_index (((symbol *) sp->value)->name);
                xtra_ref.n_other = 0;
                xtra_ref.n_un.n_strx
                  = assign_string_table_index (((symbol *) sp->value)->name);
                xtra_ref.n_other = 0;
@@ -4155,7 +4209,7 @@ write_file_syms (entry, syms_written_addr)
     {
       struct nlist nl;
 
     {
       struct nlist nl;
 
-      nl.n_type = N_TEXT;
+      nl.n_type = N_FN | N_EXT;
       nl.n_un.n_strx = assign_string_table_index (entry->local_sym_name);
       nl.n_value = entry->text_start_address;
       nl.n_desc = 0;
       nl.n_un.n_strx = assign_string_table_index (entry->local_sym_name);
       nl.n_value = entry->text_start_address;
       nl.n_desc = 0;
@@ -4624,7 +4678,7 @@ getpagesize ()
 
 #endif
 
 
 #endif
 
-#if TARGET == SUN4
+#if defined(sun) && (TARGET == SUN4)
 
 /* Don't use local pagesize to build for Sparc.  */
 
 
 /* Don't use local pagesize to build for Sparc.  */