scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 3fdc234cabe3103af7b43e3459a5e2c14260d545
parent ee66e1b7156dbeae6df2a950b0aa832b1c7211b0
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  9 Aug 2019 23:31:07 +0100

[ld] Make undef() private

Undef() was public only because we had to parse the options
in main, but the actions were totally private to the 1st pass.
This patch makes pass1 to rescan the arguments to locate
the options that are interesting for it, and giving a positional
value to -u. -U was evaluated before scanning any file, but ater
this change it is evaluated just where it is found.

Diffstat:
Msrc/cmd/ld/ld.h | 6------
Msrc/cmd/ld/main.c | 68+++++++++++++++++++++++++++++++++++---------------------------------
Msrc/cmd/ld/pass1.c | 66++++++++++++++++++++++++++++++++++++++++++++++++------------------
3 files changed, 83 insertions(+), 57 deletions(-)

diff --git a/src/cmd/ld/ld.h b/src/cmd/ld/ld.h @@ -5,11 +5,6 @@ typedef struct objlst Objlst; typedef struct symbol Symbol; typedef struct section Section; -enum { - OUTLIB, - INLIB, -}; - struct section { char *name; unsigned long base; @@ -36,7 +31,6 @@ struct symbol { /* passes */ extern void pass1(int argc, char *argv[]); -extern Symbol *undef(char *name); extern void pass2(int argc, char *argv[]); extern void pass3(int argc, char *argv[]); extern void pass4(int argc, char *argv[]); diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c @@ -92,16 +92,15 @@ Lpath(char *path) int main(int argc, char *argv[]) { - char *cp, **p; - - for (--argc; *++argv; --argc) { - if (argv[0][0] != '-' || argv[0][1] == 'l') - break; - if (argv[0][1] == '-') { - --argc, ++argv; - break; + int files = 0; + char *cp, *arg, **ap; + + for (ap = argv+1; *ap; ++ap) { + if (ap[0][0] != '-') { + files = 1; + continue; } - for (cp = &argv[0][1]; *cp; ++cp) { + for (cp = &ap[0][1]; *cp; ++cp) { switch (*cp) { case 's': sflag = 1; @@ -122,47 +121,50 @@ main(int argc, char *argv[]) case 'n': /* TODO */ break; - case 'L': - if (argc == 0) - goto usage; - ++argv, --argc; - Lpath(*argv); - break; case 'u': - if (argc == 0) + case 'l': + arg = (cp[1]) ? cp+1 : *++ap; + if (!arg) goto usage; - ++argv, --argc; - undef(*argv); - break; + goto next_arg; + case 'L': + arg = (cp[1]) ? cp+1 : *++ap; + if (!arg) + goto usage; + Lpath(arg); + goto next_arg; case 'o': - if (argc == 0) + arg = (cp[1]) ? cp+1 : *++ap; + if (!arg) goto usage; - ++argv, --argc; - output = *argv; - break; + output = arg; + goto next_arg; case 'e': - if (argc == 0) + arg = (cp[1]) ? cp+1 : *++ap; + if (!arg) goto usage; - ++argv, --argc; - entry = *argv; - break; + entry = arg; + goto next_arg; case 'D': - if (argc == 0) + arg = (cp[1]) ? cp+1 : *++ap; + if (!arg) goto usage; - ++argv, --argc; - Dflag = *argv; - break; + Dflag = arg; + goto next_arg; default: usage: usage(); } } + + next_arg: + continue; } - if (argc == 0) + if (!files) usage(); - atexit(cleanup); + atexit(cleanup); ld(argc, argv); return status; diff --git a/src/cmd/ld/pass1.c b/src/cmd/ld/pass1.c @@ -10,6 +10,11 @@ #include "ld.h" +enum { + OUTLIB, + INLIB, +}; + static int bintype = -1; static Symbol refhead = { .next = &refhead, @@ -42,7 +47,7 @@ define(Objsym *osym, Obj *obj) return sym; } -Symbol * +static Symbol * undef(char *name) { Symbol *sym = install(name); @@ -176,9 +181,10 @@ newobject(FILE *fp, int type, int inlib) /* * we add the object to the list of objects - * if we are not in a library without index, - * or in that case if the library defines - * some symbol needed. + * if we are in an object file. If we are in + * a library (without index) then we check + * if the object defines some symbol in the + * undefined list. */ if (!inlib || defasym(obj)) { addobj(obj, fp); @@ -203,8 +209,7 @@ addlib(FILE *fp) return; } - for (added = 1; moreundef() && added; ) { - added = 0; + for (added = 0; moreundef(); added = 0) { for (dp = def; dp; dp = dp->next) { sym = lookup(dp->name); if (!sym || sym->def) @@ -228,6 +233,8 @@ addlib(FILE *fp) newobject(fp, t, OUTLIB); added = 1; } + if (!added) + break; } clean: free(def); @@ -319,26 +326,49 @@ openfile(char *name, char *buffer) return NULL; } +static void +load(char *name) +{ + int t; + FILE *fp; + char buff[FILENAME_MAX]; + + if ((fp = openfile(name, buff)) == NULL) + return; + + if ((t = objtype(fp, NULL)) != -1) + newobject(fp, t, OUTLIB); + else if (archive(fp)) + newlibrary(fp); + else + error("bad format"); +} + /* * Get the list of object files that are going to be linked */ void pass1(int argc, char *argv[]) { - int t; - FILE *fp; - char buff[FILENAME_MAX]; + char **ap, *cp, *arg; - for ( ; *argv; ++argv) { - if ((fp = openfile(*argv, buff)) == NULL) + for (ap = argv+1; *ap; ++ap) { + if (ap[0][0] != '-') { + load(*ap); continue; - - if ((t = objtype(fp, NULL)) != -1) - newobject(fp, t, OUTLIB); - else if (archive(fp)) - newlibrary(fp); - else - error("bad format"); + } + for (cp = &ap[0][1]; *cp; ++cp) { + switch (*cp) { + case 'l': + arg = (cp[1]) ? cp+1 : *++ap; + load(arg); + continue; + case 'u': + arg = (cp[1]) ? cp+1 : *++ap; + undef(arg); + continue; + } + } } if (moreundef()) {