RDOFF patch from Yuri Zaporogets:
authorH. Peter Anvin <hpa@zytor.com>
Sat, 4 May 2002 05:42:30 +0000 (05:42 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 4 May 2002 05:42:30 +0000 (05:42 +0000)
 - Panos Minos's LDRDF fix (correct export of relocation records);
 - Panos Minos's symtab.c verbose dump fix;
 - Librarian (rdflib) now puts a signature block when creating a library
   (instead of creating an empty file). In theory it doesn't break binary
   compatibility, but due to a bug in the original 'rdlib.c' you can't
   use old LDRDF with new libraries. Fix this bug as well.
 - Other minor changes in LDRDF.

rdoff/ldrdf.c
rdoff/rdflib.c
rdoff/rdlib.c
rdoff/rdoff.c
rdoff/rdoff.h
rdoff/symtab.c
rdoff/test/makelib.sh

index b7070fe..2226fef 100644 (file)
@@ -7,13 +7,9 @@
  */
 
 /*
- * TODO: actually get this new version working!
- * - finish off write_output()       - appears to be done
- * - implement library searching     - appears to be done
- *   - maybe we only want to do one pass, for performance reasons?
- *     this makes things a little harder, but unix 'ld' copes...
- * - implement command line options  - appears to be done
- * - improve symbol table implementation  - done, thanks to Graeme Defty
+ * TODO:
+ *   enhance search of required export symbols in libraries (now depends
+ *   on modules order in library)
  * - keep a cache of symbol names in each library module so
  *   we don't have to constantly recheck the file
  * - general performance improvements
  * BUGS & LIMITATIONS: this program doesn't support multiple code, data
  * or bss segments, therefore for 16 bit programs whose code, data or BSS
  * segment exceeds 64K in size, it will not work. This program probably
- * wont work if compiled by a 16 bit compiler. Try DJGPP if you're running
+ * won't work if compiled by a 16 bit compiler. Try DJGPP if you're running
  * under DOS. '#define STINGY_MEMORY' may help a little.
- *
- * TO FIX: enhance search of required export symbols in libraries (now depends
- * on modules order in library).
  */
 
 #include <stdio.h>
@@ -39,7 +32,7 @@
 #include "rdlib.h"
 #include "segtab.h"
 
-#define LDRDF_VERSION "1.03"
+#define LDRDF_VERSION "1.04"
 
 #define RDF_MAXSEGS 64
 /* #define STINGY_MEMORY */
@@ -104,35 +97,6 @@ char                        * libpath = NULL;
 /* error file */
 static FILE            * error_file;
 
-#ifdef _MULTBOOT_H
-
-/* loading address for multiboot header */
-unsigned               MBHloadAddr;
-
-/*
- * Tiny code that moves RDF loader to its working memory region:
- *     mov     esi,SOURCE_ADDR         ; BE xx xx xx xx
- *     mov     edi,DEST_ADDR           ; BF xx xx xx xx
- *     mov     esp,edi                 ; 89 FC
- *     push    edi                     ; 57
- *     mov     ecx,RDFLDR_LENGTH/4     ; B9 xx xx xx xx
- *     cld                             ; FC
- *     rep     movsd                   ; F3 A5
- *     ret                             ; C3
- */
-
-#define        RDFLDR_LENGTH   4096            /* Loader will be moved to unused */
-#define        RDFLDR_DESTLOC  0xBF000         /* video page                     */
-unsigned char RDFloaderMover[]={
-       0xBE, 0, 0, 0, 0, 0xBF, 0, 0xF0, 0xB, 0,
-       0x89, 0xFC, 0x57,
-       0xB9, 0, 4, 0, 0,
-       0xFC, 0xF3, 0xA5, 0xC3
-};
-               
-#endif
-
 /* the header of the output file, built up stage by stage */
 rdf_headerbuf          * newheader = NULL;
 
@@ -160,6 +124,29 @@ struct ldrdfoptions {
 
 int errorcount = 0;    /* determines main program exit status */
 
+/*
+ * Multiboot header support.
+ */
+/* loading address for multiboot header */
+unsigned               MBHloadAddr;
+
+#define        RDFLDR_LENGTH   4096            /* Loader size is 4K */
+#define        RDFLDR_DESTLOC  0x100000        /* and its absolute address */
+/*
+ * Tiny code that moves RDF setup code to its working memory region
+ */
+unsigned char trampoline_code[] = {
+       0xBE, 0, 0, 0, 0,               /* mov  esi,SOURCE_ADDR */
+       0xBF, 0, 0, 0, 0,               /* mov  edi,DEST_ADDR   */
+       0x89, 0xFA,                     /* mov  edx,edi         */
+       0xB9, 0, 4, 0, 0,               /* mov  ecx,RDFLDR_LENGTH/4 */
+       0xFC,                           /* cld                  */
+       0xF3, 0xA5,                     /* rep  movsd           */
+       0xFF, 0xE2                      /* jmp  edx             */
+};
+
 /* =========================================================================
  * Utility functions
  */
@@ -736,7 +723,7 @@ void write_output(const char * filename)
     
         hr = (rdfheaderrec *) malloc(sizeof(struct MultiBootHdrRec));
         hr->mbh.type = 9;
-        hr->mbh.reclen = sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE;
+        hr->mbh.reclen = sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE;
            
         hr->mbh.mb.Magic = MB_MAGIC;
         hr->mbh.mb.Flags = MB_FL_KLUDGE;
@@ -745,7 +732,7 @@ void write_output(const char * filename)
         hr->mbh.mb.LoadAddr = MBHloadAddr;
        hr->mbh.mb.Entry = MBHloadAddr+16+sizeof(struct tMultiBootHeader);
        
-       memcpy(hr->mbh.mover,RDFloaderMover,RDFLDRMOVER_SIZE);
+       memcpy(hr->mbh.trampoline,trampoline_code,TRAMPOLINESIZE);
            
         rdfaddheader(rdfheader,hr);
         free(hr);
@@ -931,8 +918,17 @@ void write_output(const char * filename)
                 * Otherwise, we need to output a new relocation record
                 * with the references updated segment and offset...
                 */
-               if (! isrelative 
-                   || cur->seginfo[localseg].dest_seg != seg)
+                
+               if (isrelative && cur->seginfo[localseg].dest_seg != seg)
+               {
+                   hr->r.segment = cur->seginfo[localseg].dest_seg+64;
+                   hr->r.offset += cur->seginfo[localseg].reloc;
+                   hr->r.refseg = seg;
+                   rdfaddheader(rdfheader, hr);
+                   break;
+               }
+                
+               if (! isrelative || cur->seginfo[localseg].dest_seg != seg)
                {
                    hr->r.segment = cur->seginfo[localseg].dest_seg;
                    hr->r.offset += cur->seginfo[localseg].reloc;
@@ -1094,11 +1090,14 @@ void write_output(const char * filename)
        struct MultiBootHdrRec *mbhrec = (struct MultiBootHdrRec *)(rdfheader->buf->buffer);
        unsigned l = membuflength(rdfheader->buf) + 14 + 
                     10*rdfheader->nsegments + rdfheader->seglength;
-       unsigned *ldraddr = (unsigned *)(mbhrec->mover+1);
+       unsigned *ldraddr = (unsigned *)(mbhrec->trampoline+1);
+       unsigned *ldrdest = (unsigned *)(mbhrec->trampoline+6);
 
        mbhrec->mb.LoadEndAddr = MBHloadAddr+l+10+RDFLDR_LENGTH; 
        mbhrec->mb.BSSendAddr = mbhrec->mb.LoadEndAddr;
+       
        *ldraddr = MBHloadAddr+l+10;
+       *ldrdest = RDFLDR_DESTLOC;
     }
     
     rdfwriteheader(f, rdfheader);
index c8bab74..1f19913 100644 (file)
@@ -3,7 +3,13 @@
 /*
  * an rdoff library is simply a sequence of RDOFF object files, each
  * preceded by the name of the module, an ASCII string of up to 255
- * characters, terminated by a zero. 
+ * characters, terminated by a zero.
+ *
+ * When a library is being created, special signature block is placed
+ * in the beginning of the file. It is a string 'RDLIB' followed by a
+ * version number, then long content size and a long time stamp.
+ * The module name of the signature block is '.sig'.
+ *
  *
  * There may be an optional directory placed on the end of the file.
  * The format of the directory will be 'RDLDD' followed by a version
  * directory, the format of which has not yet been designed.
  * The module name of the directory must be '.dir'. 
  *
- * All module names beginning with '.' are reserved
- * for possible future extensions. The linker ignores all such modules,
- * assuming they have the format of a six byte type & version identifier
- * followed by long content size, followed by data.
+ * All module names beginning with '.' are reserved for possible future
+ * extensions. The linker ignores all such modules, assuming they have
+ * the format of a six byte type & version identifier followed by long
+ * content size, followed by data.
  */
 
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 
 /* functions supported:
  *   create a library  (no extra operands required)
@@ -41,6 +48,9 @@ const char *usage =
    "    r - replace               (module-name filename)\n"
    "    d - delete                (module-name)\n"
    "    t - list\n";
+   
+/* Library signature */
+const char *rdl_signature = "RDLIB2", *sig_modname = ".sig";
 
 char **_argv;
 
@@ -114,10 +124,11 @@ long copylong(FILE *fp, FILE *fp2)
 
 int main(int argc, char **argv)
 {
-    FILE *fp, *fp2, *fptmp;
+    FILE *fp, *fp2 = NULL, *fptmp;
     char *p, buf[256], c;
     int i;
     long l;
+    time_t t;
     char tmptempl[L_tmpnam], rdbuf[10];
 
     _argv = argv;
@@ -137,6 +148,11 @@ int main(int argc, char **argv)
            perror("rdflib");
            exit(1);
        }
+       fwrite(sig_modname, 1, strlen(sig_modname)+1, fp);
+       fwrite(rdl_signature, 1, strlen(rdl_signature), fp);
+       l = sizeof(t = time(NULL));
+       fwrite(&l, sizeof(l), 1, fp);
+       fwrite(&t, 1, l, fp);
        fclose(fp);
        break;
 
index ed78a00..6eee5a9 100644 (file)
@@ -6,11 +6,13 @@
 #include "rdlib.h"
 
 /*
- * format of rdoff library files:
+ * format of RDOFF library files:
+ * optional signature ('.sig')
  * repeat
  *   null terminated module name (max 255 chars)
  *   RDOFF module
  * until eof
+ * optional directory ('.dir')
  */
 
 /*
@@ -54,26 +56,27 @@ int rdl_verify(const char * filename)
            i++;
        if (feof(fp)) break;
        
-       fread(buf, 6, 1, fp);
-       buf[6] = 0;
        if (buf[0] == '.') {
            /*
-            * a special module, eg a directory.
+            * A special module, eg a signature block or a directory.
             * Format of such a module is defined to be:
-            *   six char type identifier (which we've already read)
+            *   six char type identifier
             *   long count bytes content
             *   content
-            * so we can handle it uniformaly with RDOFF2 modules...
-            * do nothing here. :-)
+            * so we can handle it uniformaly with RDOFF2 modules.
             */
+            fread(buf, 6, 1, fp);
+            buf[6] = 0;
+            /* Currently, nothing useful to do with signature block.. */
+       } else {
+           fread(buf, 6, 1, fp);
+           buf[6] = 0;
+           if (strncmp(buf, "RDOFF", 5)) {
+               return rdl_error = lastresult = 2;
+           } else if (buf[5] != '2') {
+               return rdl_error = lastresult = 3;
+           }
        }
-       else if (strncmp(buf, "RDOFF", 5)) {
-           return rdl_error = lastresult = 2;
-       }
-       else if (buf[5] != '2') {
-           return rdl_error = lastresult = 3;
-       }
-
        fread(&length, 4, 1, fp);
        fseek(fp, length, SEEK_CUR); /* skip over the module */
     }
index 80b96cc..30d2c03 100644 (file)
@@ -481,7 +481,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
        
 #ifdef _MULTBOOT_H     
     case 9:                            /* MultiBoot header */
-       membufwrite(h->buf,&r->mbh.mb,sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE);
+       membufwrite(h->buf,&r->mbh.mb,sizeof(struct tMultiBootHeader)+TRAMPOLINESIZE);
        break ;
 #endif         
 
index 4a81017..e9b9594 100644 (file)
@@ -77,9 +77,11 @@ struct ModRec {
 #define SYM_FUNCTION   0x02
 #define SYM_GLOBAL     0x04
 
+/* Multiboot record */
+
 #ifdef _MULTBOOT_H
 
-#define        RDFLDRMOVER_SIZE 22
+#define TRAMPOLINESIZE 22
 
 struct MultiBootHdrRec {
   byte  type;           /* must be 9 */
@@ -88,9 +90,10 @@ struct MultiBootHdrRec {
   struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
 #else
   struct tMultiBootHeader mb;
-#endif  
-  byte mover[RDFLDRMOVER_SIZE];                        /* Mover of RDF loader */
+#endif
+  byte trampoline[TRAMPOLINESIZE];
 };
+
 #endif
 
 /* GenericRec - contains the type and length field, plus a 128 byte
index 8570f98..4999176 100644 (file)
@@ -117,10 +117,14 @@ symtabDump(void *stab, FILE* of)
         fprintf(of, " ... slot %d ...\n", i);
       }
       while(l) {
-        fprintf(of, "%-32s %s:%08lx (%ld)\n",l->ent.name,
-                SegNames[l->ent.segment],
-                l->ent.offset, l->ent.flags);
-        l = l->next;
+       if ((l->ent.segment) == -1) {
+           fprintf(of,"%-32s Unresolved reference\n",l->ent.name);
+       } else {                
+           fprintf(of, "%-32s %s:%08lx (%ld)\n",l->ent.name,
+           SegNames[l->ent.segment],
+           l->ent.offset, l->ent.flags);
+       }
+       l = l->next;
       }
    }
    fprintf(of, "........... end of Symbol table.\n");
index 91bffa5..520bb19 100644 (file)
@@ -1,5 +1,5 @@
 #! /bin/sh
+
 [ $1 ] || {
     echo "Usage: $0 <library name> <module> [...]"
     exit 1