Update rdoff
authorFrank Kotler <fbkotler@users.sourceforge.net>
Fri, 12 Dec 2003 06:18:07 +0000 (06:18 +0000)
committerFrank Kotler <fbkotler@users.sourceforge.net>
Fri, 12 Dec 2003 06:18:07 +0000 (06:18 +0000)
doc/nasmdoc.src
output/outrdf2.c
rdoff/doc/rdoff.texi
rdoff/ldrdf.c
rdoff/rdfdump.c
rdoff/rdflib.c
rdoff/rdfload.c
rdoff/rdoff.c
rdoff/rdoff.h

index a1253bf..0c61fc1 100644 (file)
@@ -119,6 +119,7 @@ in \c{elf}
 \IR{elf shared libraries} ELF, shared libraries
 \IR{executable and linkable format} Executable and Linkable Format
 \IR{extern, obj extensions to} \c{EXTERN}, \c{obj} extensions to
+\IR{extern, rdf extensions to} \c{EXTERN}, \c{rdf} extensions to
 \IR{freebsd} FreeBSD
 \IR{freelink} FreeLink
 \IR{functions, c calling convention} functions, C calling convention
@@ -4543,6 +4544,25 @@ or \i\c{object} to the directive:
 \c     global  kernel_ticks:export data
 
 
+\S{rdfimpt} \c{rdf} Extensions to the \c{EXTERN} directive\I{EXTERN,
+rdf extensions to}
+
+By default the \c{EXTERN} directive in \c{RDOFF} declares a "pure external" 
+symbol (i.e. the static linker will complain if such a symbol is not resolved).
+To declare an "imported" symbol, which must be resolved later during a dynamic
+linking phase, \c{RDOFF} offers an additional \c{import} modifier. As in
+\c{GLOBAL}, you can also specify whether an imported symbol is a procedure
+(function) or data object. For example:
+
+\c     library $libc
+\c     extern  _open:import
+\c     extern  _printf:import proc
+\c     extern  _errno:import data
+
+Here the directive \c{LIBRARY} is also included, which gives the dynamic linker
+a hint as to where to find requested symbols.
+
+
 \H{dbgfmt} \i\c{dbg}: Debugging Format
 
 The \c{dbg} output format is not built into NASM in the default
index 1dfef93..931f872 100644 (file)
@@ -70,6 +70,7 @@ struct RelocRec {
 struct ImportRec {
   byte         type;           /* must be 2, or 7 for FAR import */
   byte reclen;         /* equals 3+label length */
+  byte  flags;         /* SYM_* flags (see below) */
   int16        segment;        /* segment number allocated to the label for reloc
                         * records - label is assumed to be at offset zero
                         * in this segment, so linker must fix up with offset
@@ -109,9 +110,10 @@ struct CommonRec {
 };
 
 /* Flags for ExportRec */
-#define SYM_DATA       0x01
-#define SYM_FUNCTION   0x02
-#define SYM_GLOBAL     0x04
+#define SYM_DATA       1
+#define SYM_FUNCTION   2
+#define SYM_GLOBAL     4
+#define SYM_IMPORT     8
 
 #define COUNT_SEGTYPES 9
 
@@ -124,7 +126,7 @@ static int segmenttypenumbers[COUNT_SEGTYPES] = {
   0, 1, 1, 2, 3, 4, 5, 6, 7
 };
 
-/* code for managing buffers needed to seperate code and data into individual
+/* code for managing buffers needed to separate code and data into individual
  * sections until they are ready to be written to the file.
  * We'd better hope that it all fits in memory else we're buggered... */
 
@@ -332,6 +334,7 @@ static void write_import_rec(struct ImportRec *r)
 
   saa_wbytes(header,&r->type,1);
   saa_wbytes(header,&r->reclen,1);
+  saa_wbytes(header,&r->flags,1);
   b = buf; WRITESHORT(b,r->segment);
   saa_wbytes(header,buf,2);
   saa_wbytes(header,r->label,strlen(r->label) + 1);
@@ -389,7 +392,7 @@ static void rdf2_deflabel(char *name, long segment, long offset,
   struct CommonRec ci;
   static int farsym = 0;
   static int i;
-  byte export_flags = 0;
+  byte symflags = 0;
 
   if (is_global == 2) {
     /* Common variable */
@@ -425,7 +428,11 @@ static void rdf2_deflabel(char *name, long segment, long offset,
     
     if (!nasm_strnicmp(special, "export", 6)) {
       special += 6;
-      export_flags |= SYM_GLOBAL;  
+      symflags |= SYM_GLOBAL;  
+    }
+    else if (!nasm_strnicmp(special, "import", 6)) {
+      special += 6;
+      symflags |= SYM_IMPORT;
     }
 
     if (*special) {
@@ -438,11 +445,11 @@ static void rdf2_deflabel(char *name, long segment, long offset,
       }
       else if (!nasm_stricmp(special, "proc") || 
                !nasm_stricmp(special, "function")) {
-        export_flags |= SYM_FUNCTION;  
+        symflags |= SYM_FUNCTION;  
       }
       else if (!nasm_stricmp(special, "data") ||
                !nasm_stricmp(special, "object")) {
-        export_flags |= SYM_DATA;
+        symflags |= SYM_DATA;
       }
       else
         error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
@@ -458,18 +465,20 @@ static void rdf2_deflabel(char *name, long segment, long offset,
     if (segments[i].segnumber == segment>>1) break;
   }
   if (i >= nsegments) {   /* EXTERN declaration */
-    if (farsym)
-      ri.type = RDFREC_FARIMPORT;
-    else
-      ri.type = RDFREC_IMPORT;
+    ri.type = farsym ? RDFREC_FARIMPORT : RDFREC_IMPORT;
+    if (symflags & SYM_GLOBAL)
+      error(ERR_NONFATAL, "symbol type conflict - EXTERN cannot be EXPORT");
+    ri.flags = symflags;
     ri.segment = segment;
     strncpy(ri.label,name,32);
     ri.label[32] = 0;
-    ri.reclen = 3 + strlen(ri.label);
+    ri.reclen = 4 + strlen(ri.label);
     write_import_rec(&ri);
   } else if (is_global) {
     r.type = RDFREC_GLOBAL;
-    r.flags = export_flags;
+    if (symflags & SYM_IMPORT)
+      error(ERR_NONFATAL, "symbol type conflict - GLOBAL cannot be IMPORT");
+    r.flags = symflags;
     r.segment = segment;
     r.offset = offset;
     strncpy(r.label,name,32);
index 8d3c1f3..c958cc3 100644 (file)
@@ -12,7 +12,7 @@
 @end titlepage
 
 @ifinfo
-Copyright @copyright{} 2002 Netwide Assembler Project.
+Copyright @copyright{} 2002-2003 Netwide Assembler Project.
 Written by Yuri Zaporogets @email{yuriz@@ukr.net}
 Based on various sources and notes written by Julian Hall @email{jules@@dsf.org.uk}
 Distributed under GNU documentation license.
@@ -81,7 +81,7 @@ by a section header.
 @subsection Relocation records
 
 @node Import
-@subsection Declaring external symbols
+@subsection Declaring external and imported symbols
 
 @node Export
 @subsection Declaring public and exported symbols
index 26c991e..f2ac92a 100644 (file)
@@ -1,9 +1,12 @@
-/* ldrdf.c      RDOFF Object File linker/loader main program
+/*
+ * ldrdf.c - RDOFF Object File linker/loader main program.
+ *
+ * Copyright (c) 1996,99 Julian Hall. All rights reserved.
+ * Copyright (c) 2000-2003 RET & COM Research.
  *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
+ * This file is distributed under the terms and conditions of the
+ * GNU Lesser Public License (LGPL), version 2.1.
+ * See http://www.gnu.org/copyleft/lgpl.html for details.
  */
 
 /*
@@ -31,7 +34,7 @@
 #include "rdlib.h"
 #include "segtab.h"
 
-#define LDRDF_VERSION "1.05"
+#define LDRDF_VERSION "1.07"
 
 #define RDF_MAXSEGS 64
 /* #define STINGY_MEMORY */
@@ -114,7 +117,7 @@ long                        bss_length;
 struct ldrdfoptions {
     int                verbose;
     int                align;
-    int                warnUnresolved;
+    int                dynalink;
     int                strip;
     int         respfile;
     int         stderr_redir;
@@ -129,13 +132,11 @@ int errorcount = 0;       /* determines main program exit status */
  * Utility functions
  */
 
-
 /*
  * initsegments()
  *
  * sets up segments 0, 1, and 2, the initial code data and bss segments
  */
-
 void initsegments()
 {
     nsegs = 3;
@@ -154,6 +155,7 @@ void initsegments()
     bss_length = 0;
 }
 
+
 /*
  * loadmodule
  *
@@ -161,34 +163,27 @@ void initsegments()
  * each segment it contains (including determining destination segments and
  * relocation factors for segments that        are kept).
  */
-
 void loadmodule(const char * filename)
 {
     if (options.verbose)
        printf("loading `%s'\n", filename);
 
     /* allocate a new module entry on the end of the modules list */
-    if (!modules)
-    {
+    if (!modules) {
        modules = malloc (sizeof(*modules));
        lastmodule = modules;
-    }
-    else
-    {
+    } else {
        lastmodule->next = malloc (sizeof(*modules));
        lastmodule = lastmodule->next;
     }
 
-    if ( ! lastmodule)
-    {
+    if (!lastmodule) {
        fprintf(stderr, "ldrdf: out of memory\n");
        exit(1);
     }
 
     /* open the file using 'rdfopen', which returns nonzero on error */
-
-    if (rdfopen(&lastmodule->f, filename) != 0)
-    {
+    if (rdfopen(&lastmodule->f, filename) != 0) {
        rdfperror("ldrdf", filename);
        exit(1);
     }
@@ -198,13 +193,13 @@ void loadmodule(const char * filename)
      * it contains, and what we should do with them (determine relocation
      * factor if we decide to keep them)
      */
-
     lastmodule->header = NULL;
     lastmodule->name = strdup(filename);
     lastmodule->next = NULL;
 
     processmodule(filename, lastmodule);
 }
+
        
 /*
  * processmodule()
@@ -215,7 +210,6 @@ void loadmodule(const char * filename)
  * (b) is fairly easy, because we're now keeping track of how big each
  * segment in our output file is...
  */
-
 void processmodule(const char * filename, struct modulenode * mod)
 {
     struct segconfig sconf;
@@ -315,35 +309,35 @@ void processmodule(const char * filename, struct modulenode * mod)
            case RDFREC_IMPORT:         /* imported symbol */
            case RDFREC_FARIMPORT:
                /* Define with seg = -1 */
-           symtab_add(hr->i.label, -1, 0);
-           break;
+               symtab_add(hr->i.label, -1, 0);
+               break;
 
            case RDFREC_GLOBAL: {       /* exported symbol */
-            int destseg;
-            long destreloc;
+               int destseg;
+               long destreloc;
 
                if (hr->e.segment == 2) {
                    bss_was_referenced = 1;
-               destreloc = bss_length;
-               if (destreloc % options.align != 0)
-                  destreloc +=  options.align - (destreloc % options.align);
-               destseg = 2;
+                   destreloc = bss_length;
+                   if (destreloc % options.align != 0)
+                       destreloc +=  options.align - (destreloc % options.align);
+                   destseg = 2;
                 } else {
-               if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
-                  continue;
-               destreloc = mod->seginfo[(int)hr->e.segment].reloc;
-             }
-           symtab_add(hr->e.label, destseg, destreloc + hr->e.offset);
-           break;
-           }
+                   if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
+                       continue;
+                   destreloc = mod->seginfo[(int)hr->e.segment].reloc;
+                }
+               symtab_add(hr->e.label, destseg, destreloc + hr->e.offset);
+               break;
+           }
 
            case RDFREC_BSS:            /* BSS reservation */
-           /*
-            * first, amalgamate all BSS reservations in this module
-            * into one, because we allow this in the output format.
-            */
-           bssamount += hr->b.amount;
-           break;
+               /*
+                * first, amalgamate all BSS reservations in this module
+                * into one, because we allow this in the output format.
+                */
+               bssamount += hr->b.amount;
+               break;
 
            case RDFREC_COMMON: {       /* Common variable */
                symtabEnt *ste = symtabFind(symtab, hr->c.label);
@@ -366,7 +360,7 @@ void processmodule(const char * filename, struct modulenode * mod)
            }
        }
     }
-
+    
     if (bssamount != 0 || bss_was_referenced) {
        /*
         * handle the BSS segment - first pad the existing bss length
@@ -375,7 +369,7 @@ void processmodule(const char * filename, struct modulenode * mod)
         * bss_length.
         */
        if (bss_length % options.align != 0)
-           bss_length +=  options.align - (bss_length % options.align);
+           bss_length += options.align - (bss_length % options.align);
     
        mod->bss_reloc = bss_length;
        if (options.verbose > 1) {
@@ -400,18 +394,18 @@ void processmodule(const char * filename, struct modulenode * mod)
 
 
 /*
- * Look in the list for module by its name.
+ * Return 1 if a given module is in the list, 0 otherwise.
  */
 int lookformodule(const char *name)
- {
-  struct modulenode *curr=modules;
+{
+    struct modulenode *curr = modules;
 
-  while(curr) {
-   if (!strcmp(name,curr->name)) return 1;
-   curr = curr->next;
-  }
-  return 0;
- }
+    while(curr) {
+       if (!strcmp(name, curr->name)) return 1;
+       curr = curr->next;
+    }
+    return 0;
+}
 
 
 /*
@@ -446,6 +440,7 @@ int findsegment(int16 type,int16 reserved)
     return allocnewseg(type,reserved);
 }
 
+
 /*
  * symtab_add()
  *
@@ -463,7 +458,6 @@ int findsegment(int16 type,int16 reserved)
  * routine won't change a previously existing symbol. It will change
  * to segment = -2 only if the segment was previously < 0.
  */
-
 void symtab_add(const char * symbol, int segment, long offset)
 {
     symtabEnt * ste;
@@ -515,7 +509,6 @@ void symtab_add(const char * symbol, int segment, long offset)
  * are assumed to have -1:0 associated. Returns 1 if the symbol was
  * successfully located.
  */
-
 int symtab_get(const char * symbol, int * segment, long * offset)
 {
     symtabEnt * ste = symtabFind(symtab, symbol);
@@ -532,13 +525,13 @@ int symtab_get(const char * symbol, int * segment, long * offset)
     }
 }
 
+
 /*
  * add_library()
  *
  * checks that a library can be opened and is in the correct format,
  * then adds it to the linked list of libraries.
  */
-
 void add_library(const char * name)
 {
     if (rdl_verify(name)) {
@@ -571,6 +564,7 @@ void add_library(const char * name)
     }
 }
 
+
 /*
  * search_libraries()
  *
@@ -581,7 +575,6 @@ void add_library(const char * name)
  * returns 1 if any extra library modules are included, indicating that
  * another pass through the library list should be made (possibly).
  */
-
 int search_libraries()
 {
     struct librarynode * cur;
@@ -634,13 +627,13 @@ int search_libraries()
                     * otherwise the symbol is just public. Find it in
                     * the symbol table. If the symbol isn't defined, we
                     * aren't interested, so go on to the next.
-                * If it is defined as anything but -1, we're also not
-                * interested. But if it is defined as -1, insert this
-                * module into the list of modules to use, and go
-                * immediately on to the next module...
-                */
+                    * If it is defined as anything but -1, we're also not
+                    * interested. But if it is defined as -1, insert this
+                    * module into the list of modules to use, and go
+                    * immediately on to the next module...
+                    */
                    if (!symtab_get(hr->e.label, &segment, &offset) || segment != -1)
-                   continue;    
+                       continue;    
                }
                
                doneanything = 1;
@@ -664,10 +657,10 @@ int search_libraries()
                break;
            }
            if (!keepfile) {
-              free(f.name);
-              f.name = NULL;
-              f.fp = NULL;
-             }
+               free(f.name);
+               f.name = NULL;
+               f.fp = NULL;
+            }
        }
        if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
            rdl_perror("ldrdf", cur->name);
@@ -682,6 +675,7 @@ int search_libraries()
     return doneanything;
 }
 
+
 /*
  * write_output()
  *
@@ -719,10 +713,10 @@ void write_output(const char * filename)
      */
     if (generic_rec_file) {
        FILE *ff;
-    
+       
        if (options.verbose)
            printf("\nadding generic record from binary file %s\n", generic_rec_file);
-       
+    
         hr = (rdfheaderrec *) malloc(sizeof(struct GenericRec));
        if ((ff = fopen(generic_rec_file, "r")) == NULL) {
            fprintf(stderr, "ldrdf: couldn't open %s for input\n", generic_rec_file);
@@ -734,10 +728,10 @@ void write_output(const char * filename)
            fprintf (error_file, "warning: maximum generic record size is %d, rest of file ignored\n", sizeof(hr->g.data));
        }
        fclose(ff);
-           
+       
         hr->g.type = 0;
         hr->g.reclen = i;
-        rdfaddheader(rdfheader,hr);
+       rdfaddheader(rdfheader, hr);
         free(hr);
     }
 
@@ -941,17 +935,10 @@ void write_output(const char * filename)
                 */
                se = symtabFind(symtab, hr->i.label);
                if (!se || se->segment == -1) {
-                   if (options.warnUnresolved) {
-                       switch (options.warnUnresolved) {
-                           case 1:
-                               fprintf(error_file, "warning");
-                               break;
-                           case 2:
-                               fprintf(error_file, "error");
-                               errorcount++;
-                       }
-                       fprintf(error_file, ": unresolved reference to `%s'"
+                   if (!options.dynalink && !(hr->i.flags & SYM_IMPORT)) {
+                       fprintf(error_file, "error: unresolved reference to `%s'"
                                " in module `%s'\n", hr->i.label, cur->name);
+                       errorcount++;
                    }
                    /*
                     * we need to allocate a segment number for this
@@ -984,7 +971,6 @@ void write_output(const char * filename)
                }
 
                add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
-               
                break;
 
            case RDFREC_GLOBAL:         /* export symbol */
@@ -1023,7 +1009,7 @@ void write_output(const char * filename)
                  * Insert module name record if export symbols
                  * are not stripped.
                  * If module name begins with '$' - insert it anyway.
-                 */
+                 */              
                if (options.strip && hr->m.modname[0] != '$') break;
                rdfaddheader(rdfheader, hr);
                break;
@@ -1144,10 +1130,10 @@ void usage()
            "   ldrdf [options] object modules ... [-llibrary ...]\n"
            "   ldrdf -r\n"
            "options:\n"
-           "   -v[=n]          increases verbosity by 1, or sets it to n\n"
-           "   -a nn           sets segment alignment value (default 16)\n"
-           "   -s              strips exported symbols\n"
-           "   -x              warn about unresolved symbols\n"
+           "   -v[=n]          increase verbosity by 1, or set it to n\n"
+           "   -a nn           set segment alignment value (default 16)\n"
+           "   -s              strip public symbols\n"
+           "   -dy             Unix-style dynamic linking\n"
            "   -o name         write output in file 'name'\n"
            "   -j path         specify objects search path\n"
            "   -L path         specify libraries search path\n"
@@ -1163,7 +1149,7 @@ int main(int argc, char ** argv)
 
     options.verbose = 0;
     options.align = 16;
-    options.warnUnresolved = 0;
+    options.dynalink = 0;
     options.strip = 0;
 
     error_file = stderr;
@@ -1201,10 +1187,8 @@ int main(int argc, char ** argv)
        case 's':
            options.strip = 1;
            break;
-       case 'x':
-           options.warnUnresolved = 1;
-           if (argv[0][2]=='e')
-               options.warnUnresolved++;
+       case 'd':
+           if (argv[0][2] == 'y') options.dynalink = 1;
            break;
        case 'o':
            outname = argv[1];
@@ -1212,40 +1196,40 @@ int main(int argc, char ** argv)
            break;
        case 'j':
            if (!objpath) {
-              options.objpath = 1;
-             objpath = argv[1];
-             argv++, argc--;
-             break;
+               options.objpath = 1;
+               objpath = argv[1];
+               argv++, argc--;
+               break;
             } else {
-             fprintf(stderr,"ldrdf: more than one objects search path specified\n");
-             exit(1);
+               fprintf(stderr,"ldrdf: more than one objects search path specified\n");
+               exit(1);
             }
        case 'L':
            if (!libpath) {
-              options.libpath = 1;
-             libpath = argv[1];
-             argv++, argc--;
-             break;
+               options.libpath = 1;
+               libpath = argv[1];
+               argv++, argc--;
+               break;
             } else {
-             fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
-             exit(1);
+               fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
+               exit(1);
             }
        case '@': {
-             int i=0;
-             char buf[256];
-             FILE *f;
+           int i=0;
+           char buf[256];
+           FILE *f;
 
-              options.respfile = 1;
-             if (argv[1] != NULL) f = fopen(argv[1],"r");
+            options.respfile = 1;
+           if (argv[1] != NULL) f = fopen(argv[1],"r");
            else {
                fprintf(stderr,"ldrdf: no response file name specified\n");
                exit(1);
-              }
+           }
 
            if (f == NULL) {
                fprintf(stderr,"ldrdf: unable to open response file\n");
                exit(1);
-              }
+           }
            
            argv++, argc--;
            while (fgets(buf, sizeof(buf), f) != NULL) {
@@ -1253,14 +1237,14 @@ int main(int argc, char ** argv)
                if (buf[0]=='\n') continue;
                if ((p = strchr(buf,'\n')) != NULL) *p = '\0';
                if (i >= 128) {
-                 fprintf(stderr,"ldrdf: too many input files\n");
-                 exit(1);
-                }
-               *(respstrings+i) = newstr(buf);
+                   fprintf(stderr,"ldrdf: too many input files\n");
+                   exit(1);
+               }
+               *(respstrings + i) = newstr(buf);
                argc++, i++;
-              }
+           }
             break;
-        }
+       }
        case '2':
             options.stderr_redir = 1;
            error_file = stdout;
@@ -1268,7 +1252,7 @@ int main(int argc, char ** argv)
        case 'g':
            generic_rec_file = argv[1];
            argv++, argc--;
-               break;    
+           break;
        default:
            usage();
        }
@@ -1281,14 +1265,12 @@ int main(int argc, char ** argv)
        printf("    output name: `%s'\n", outname);
        if (options.strip)
            printf("    strip symbols\n");
-       if (options.warnUnresolved == 1)
-           printf("    warn about unresolved symbols\n");
-       if (options.warnUnresolved == 2)
-           printf("    error if unresolved symbols\n");    
+       if (options.dynalink)
+           printf("    Unix-style dynamic linking\n");
         if (options.objpath)
-            printf("    objects search path: %s\n",objpath);
+            printf("    objects search path: %s\n", objpath);
         if (options.libpath)
-            printf("    libraries search path: %s\n",libpath);
+            printf("    libraries search path: %s\n", libpath);
        printf("\n");
     }
 
@@ -1303,14 +1285,16 @@ int main(int argc, char ** argv)
     while (argc) {
        if (!*argv) argv = respstrings;
        if (!*argv) break;
-       if (!strncmp(*argv, "-l", 2)) /* library */
-         {
-         if(libpath) add_library(newstrcat(libpath,*argv + 2));
-          else add_library(*argv + 2);
-         }
-       else {
-           if(objpath) loadmodule(newstrcat(objpath,*argv));
-           else loadmodule(*argv);
+       if (!strncmp(*argv, "-l", 2)) {
+           if(libpath && (*argv[2] != '/'))
+               add_library(newstrcat(libpath,*argv + 2));
+            else
+               add_library(*argv + 2);
+        } else {
+           if(objpath && (*argv[0] != '/'))
+               loadmodule(newstrcat(objpath, *argv));
+           else
+               loadmodule(*argv);
            moduleloaded = 1;
        }
        argv++, argc--;
index d8690d2..09f2d80 100644 (file)
@@ -10,8 +10,9 @@
 
 FILE *infile;
 
-long translatelong(long in) {          /* translate from little endian to
-                                          local representation */
+/* Translate from little endian to local representation */
+long translatelong(long in)
+{
   long r;
   unsigned char *i;
 
@@ -24,7 +25,8 @@ long translatelong(long in) {         /* translate from little endian to
   return r;
 }
   
-int16 translateshort(int16 in) {
+int16 translateshort(int16 in)
+{
   int r;
   unsigned char *i;
 
@@ -37,16 +39,16 @@ int16 translateshort(int16 in) {
 void print_header(long length, int rdf_version)
 {
     char buf[129],t,l,s,flags;
-  unsigned char reclen;
-  long o,ll;
-  int16 rs;
-
-  while (length > 0) {
-    fread(&t,1,1,infile);
-    if (rdf_version >= 2) {
-       fread(&reclen,1,1,infile);
-    }
-    switch(t) {
+    unsigned char reclen;
+    long o,ll;
+    int16 rs;
+
+    while (length > 0) {
+       fread(&t,1,1,infile);
+       if (rdf_version >= 2) {
+           fread(&reclen,1,1,infile);
+       }
+       switch(t) {
            case RDFREC_GENERIC:                /* generic record */
                printf("  generic record (length=%d)\n", (int)reclen);
                fseek(infile, reclen, SEEK_CUR);
@@ -54,90 +56,92 @@ void print_header(long length, int rdf_version)
     
            case RDFREC_RELOC:                  /* relocation record */
            case RDFREC_SEGRELOC:               /* segment relocation */
-      fread(&s,1,1,infile);
-      fread(&o,4,1,infile);
-      fread(&l,1,1,infile);
-      fread(&rs,2,1,infile);
-      printf("  %s: location (%04x:%08lx), length %d, "
-            "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
-            (int)s,translatelong(o),(int)l,
-            translateshort(rs));
-      if (rdf_version >= 2 && reclen != 8)
-         printf("    warning: reclen != 8\n");
-      if (rdf_version == 1) length -= 9;
-      if (rdf_version == 1 && t == 6)
-         printf("    warning: seg relocation not supported in RDOFF1\n");
-      break;
+               fread(&s,1,1,infile);
+               fread(&o,4,1,infile);
+               fread(&l,1,1,infile);
+               fread(&rs,2,1,infile);
+               printf("  %s: location (%04x:%08lx), length %d, "
+                       "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation",
+                       (int)s,translatelong(o),(int)l,
+                       translateshort(rs));
+               if (rdf_version >= 2 && reclen != 8)
+                   printf("    warning: reclen != 8\n");
+               if (rdf_version == 1) length -= 9;
+               if (rdf_version == 1 && t == 6)
+                   printf("    warning: seg relocation not supported in RDOFF1\n");
+               break;
       
            case RDFREC_IMPORT:                 /* import record */
            case RDFREC_FARIMPORT:              /* import far symbol */
-      fread(&rs,2,1,infile);
-      ll = 0;
-
-      if (rdf_version == 1) {
-         do {
-             fread(&buf[ll],1,1,infile);
-         } while (buf[ll++]);
+               fread(&flags, 1, 1, infile);
+               fread(&rs, 2, 1, infile);
+               ll = 0;
+
+               if (rdf_version == 1) {
+                   do {
+                       fread(&buf[ll], 1, 1, infile);
+                   } while (buf[ll++]);
                } else {
-         for (;ll < reclen - 2; ll++)
-             fread(&buf[ll],1,1,infile);
-      }
-
-      printf("  %simport: segment %04x = %s\n",t == 7 ? "far " : "",
-            translateshort(rs),buf);
-      if (rdf_version == 1) length -= ll + 3;
-      if (rdf_version == 1 && t == 7)
-         printf ("    warning: far import not supported in RDOFF1\n");
-      break;
+                   for (;ll < reclen - 3; ll++)
+                       fread(&buf[ll], 1, 1, infile);
+               }
+
+               if (t == 7)
+                   printf("far ");
+               printf((flags & SYM_IMPORT) ? "  import" : "  extern");
+               if (flags & SYM_FUNCTION) printf(" proc");
+               if (flags & SYM_DATA) printf(" data");
+               printf(": segment %04x = %s\n", translateshort(rs), buf);
+               if (rdf_version == 1) length -= ll + 3;
+               if (rdf_version == 1 && t == 7)
+                   printf ("    warning: far import not supported in RDOFF1\n");
+               break;
       
            case RDFREC_GLOBAL:                 /* export record */
-      fread(&flags,1,1,infile);
-      fread(&s,1,1,infile);
-      fread(&o,4,1,infile);
-      ll = 0;
-
-      if (rdf_version == 1) {
-         do {
-             fread(&buf[ll],1,1,infile);
-         } while (buf[ll++]);
+               fread(&flags, 1, 1, infile);
+               fread(&s, 1, 1, infile);
+               fread(&o, 4, 1, infile);
+               ll = 0;
+
+               if (rdf_version == 1) {
+                   do {
+                       fread(&buf[ll], 1, 1, infile);
+                   } while (buf[ll++]);
                } else {
-         for (; ll < reclen - 6; ll ++)
-             fread(&buf[ll],1,1,infile);
-      }
-      if (flags & SYM_GLOBAL)
-        printf("  export");
-      else
-        printf("  global");
-      if (flags & SYM_FUNCTION) printf(" proc");
-      if (flags & SYM_DATA) printf(" data");
-      printf(": (%04x:%08lx) = %s\n",(int)s,translatelong(o),buf);
-      if (rdf_version == 1) length -= ll + 6;
-      break;
+               for (; ll < reclen - 6; ll ++)
+                   fread(&buf[ll], 1, 1, infile);
+               }
+               printf((flags & SYM_GLOBAL) ? "  export" : "  public");
+               if (flags & SYM_FUNCTION) printf(" proc");
+               if (flags & SYM_DATA) printf(" data");
+               printf(": (%04x:%08lx) = %s\n", (int)s, translatelong(o), buf);
+               if (rdf_version == 1) length -= ll + 6;
+               break;
       
            case RDFREC_DLL:                    /* DLL and Module records */
            case RDFREC_MODNAME:
-      ll = 0;
-
-      if (rdf_version == 1) {
-         do {
-             fread(&buf[ll],1,1,infile);
-         } while (buf[ll++]);
+               ll = 0;
+               if (rdf_version == 1) {
+                   do {
+                       fread(&buf[ll],1,1,infile);
+                   } while (buf[ll++]);
                } else {
-         for (; ll < reclen; ll++)
-             fread(&buf[ll],1,1,infile);
-      }
-      if (t==4) printf("  dll: %s\n",buf);
-      else printf("  module: %s\n",buf);
-      if (rdf_version == 1) length -= ll + 1;
-      break;
+                   for (; ll < reclen; ll++)
+                       fread(&buf[ll], 1, 1, infile);
+               }
+               if (t==4) printf("  dll: %s\n",buf);
+               else printf("  module: %s\n",buf);
+               if (rdf_version == 1)
+                   length -= ll + 1;
+               break;
                
            case RDFREC_BSS:                    /* BSS reservation */
-      fread(&ll,4,1,infile);
-      printf("  bss reservation: %08lx bytes\n",translatelong(ll));
-      if (rdf_version == 1) length -= 5;
-      if (rdf_version > 1 && reclen != 4)
-         printf("    warning: reclen != 4\n");
-      break;
+               fread(&ll,4,1,infile);
+               printf("  bss reservation: %08lx bytes\n",translatelong(ll));
+               if (rdf_version == 1) length -= 5;
+               if (rdf_version > 1 && reclen != 4)
+                   printf("    warning: reclen != 4\n");
+               break;
       
            case RDFREC_COMMON: {
                unsigned short seg, align;
@@ -150,19 +154,19 @@ void print_header(long length, int rdf_version)
                        fread(buf+ll, 1, 1, infile);
                printf("  common: segment %04x = %s, %ld:%d\n", translateshort(seg),
                       buf, translatelong(size), translateshort(align));
-      break;  
+               break;  
            }
 
-    default:
+           default:
                printf("  unrecognized record (type %d", (int)t);
-      if (rdf_version > 1) {
-       printf(", length %d",(int)reclen);
-       fseek(infile,reclen,SEEK_CUR);
+               if (rdf_version > 1) {
+                   printf(", length %d",(int)reclen);
+                   fseek(infile,reclen,SEEK_CUR);
                } else length --;
-      printf(")\n");
+           printf(")\n");
+       }
+       if (rdf_version != 1) length -= 2 + reclen;
     }
-    if (rdf_version != 1) length -= 2 + reclen;
-  }
 }
 
 char * knowntypes[8] = {"NULL", "text", "data", "object comment",
@@ -192,7 +196,9 @@ int main(int argc,char **argv) {
   long headerlength = 0;
   long objectlength = 0;
 
-  puts("RDOFF Dump utility v2.1\n(c) Copyright 1996,99,2000 Julian R Hall, Yuri M Zaporogets");
+  puts("RDOFF Dump utility v2.2\n"\
+       "Copyright (c) 1996,99 Julian R Hall\n"
+       "Copyright (c) 2000-2002 RET & COM Research.");
 
   if (argc < 2) {
     fputs("Usage: rdfdump [-v] <filename>\n",stderr);
index 1ed22d4..41f92d2 100644 (file)
@@ -25,9 +25,9 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#include <unistd.h>
 #include <time.h>
 
 /* functions supported:
index 6928ca2..4737282 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
 
 #include "rdfload.h"
 #include "symtab.h"
index 43e3d65..504d842 100644 (file)
@@ -377,6 +377,7 @@ rdfheaderrec *rdfgetheaderrec(rdffile *f)
 
   case RDFREC_IMPORT:          /* Imported symbol record */
   case RDFREC_FARIMPORT:
+    RI8(r.i.flags);
     RI16(r.i.segment);
     RS(r.i.label,32);
     break;
@@ -464,6 +465,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r)
 
     case RDFREC_IMPORT:                                /* import */
     case RDFREC_FARIMPORT:
+       membufwrite(h->buf,&r->i.flags,1);
        membufwrite(h->buf,&r->i.segment,-2);
        membufwrite(h->buf,&r->i.label,strlen(r->i.label) + 1);
        break ;
index ee00c34..c6957dc 100644 (file)
@@ -47,6 +47,7 @@ struct RelocRec {
 struct ImportRec {
   byte  type;           /* must be 2 */
   byte reclen;         /* content length */
+  byte  flags;         /* SYM_* flags (see below) */
   int16 segment;        /* segment number allocated to the label for reloc
                            records - label is assumed to be at offset zero
                            in this segment, so linker must fix up with offset
@@ -92,9 +93,10 @@ struct CommonRec {
 };
 
 /* Flags for ExportRec */
-#define SYM_DATA       0x01
-#define SYM_FUNCTION   0x02
-#define SYM_GLOBAL     0x04
+#define SYM_DATA       1
+#define SYM_FUNCTION   2
+#define SYM_GLOBAL     4
+#define SYM_IMPORT     8
 
 /* 
  * GenericRec - contains the type and length field, plus a 128 byte