main.c (2862B)
1 #include <errno.h> 2 #include <stdarg.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include <scc/mach.h> 8 9 #include "ld.h" 10 11 #define MAX_LIB_PATHS 12 12 13 int sflag; /* discard all the symbols */ 14 int xflag; /* discard local symbols */ 15 int Xflag; /* discard locals starting with 'L' */ 16 int rflag; /* preserve relocation bits */ 17 int dflag; /* define common even with rflag */ 18 int gflag; /* preserve debug symbols */ 19 int nmagic; /* nmagic output */ 20 21 char *filename, *membname; 22 23 Segment text = {.type = 'T'}; 24 Segment rodata = {.type = 'R'}; 25 Segment data = {.type = 'D'}; 26 Segment bss = {.type = 'B'}; 27 Segment debug = {.type = 'N'}; 28 29 char *libpaths[MAX_LIB_PATHS]; 30 31 char *output = "a.out", *entry = "start"; 32 static int status; 33 34 void 35 error(char *fmt, ...) 36 { 37 va_list va; 38 39 va_start(va, fmt); 40 fprintf(stderr, "ld: %s: ", filename); 41 if (membname) 42 fprintf(stderr, "%s: ", membname); 43 vfprintf(stderr, fmt, va); 44 putc('\n', stderr); 45 va_end(va); 46 47 status = EXIT_FAILURE; 48 } 49 50 static void 51 cleanup(void) 52 { 53 if (status != EXIT_FAILURE) 54 remove(output); 55 } 56 57 /* 58 * pass1: Get the list of object files that are going to be linked. 59 * pass2: Calculate the size of every segment. 60 * pass3: Rebase all symbols in sections 61 * pass4: Create the temporary files per section 62 * pass5: Create the temporary files per segment 63 */ 64 static void 65 ld(int argc, char*argv[]) 66 { 67 pass1(argc, argv); 68 pass2(argc, argv); 69 /* 70 pass3(argc, argv); 71 pass4(argc, argv); 72 pass5(argc, argv); 73 */ 74 debugsym(); 75 debugsec(); 76 } 77 78 static void 79 usage(void) 80 { 81 fputs("usage: ld [options] file ...\n", stderr); 82 exit(EXIT_FAILURE); 83 } 84 85 static void 86 Lpath(char *path) 87 { 88 char **bp, **end; 89 90 end = &libpaths[MAX_LIB_PATHS]; 91 for (bp = libpaths; bp < end && *bp; ++bp) 92 ; 93 if (bp == end) { 94 fputs("ld: too many -L options\n", stderr); 95 exit(1); 96 } 97 *bp = path; 98 } 99 100 char * 101 nextarg(char **argp, char ***argv) 102 { 103 char *ap = *argp, **av = *argv; 104 105 if (ap[1]) { 106 *argp += strlen(ap); 107 return ap+1; 108 } 109 110 if (av[1]) { 111 *argv = ++av; 112 return *av; 113 } 114 115 usage(); 116 } 117 118 int 119 main(int argc, char *argv[]) 120 { 121 int files = 0; 122 char *ap, **av; 123 124 for (av = argv+1; *av; ++av) { 125 if (av[0][0] != '-') { 126 files = 1; 127 continue; 128 } 129 for (ap = &av[0][1]; *ap; ++ap) { 130 switch (*ap) { 131 case 's': 132 sflag = 1; 133 break; 134 case 'x': 135 xflag = 1; 136 break; 137 case 'X': 138 Xflag = 1; 139 break; 140 case 'i': 141 case 'r': 142 rflag = 1; 143 break; 144 case 'd': 145 dflag = 1; 146 break; 147 case 'n': 148 nmagic = 1; 149 break; 150 case 'l': 151 case 'u': 152 nextarg(&ap, &av); 153 break; 154 case 'L': 155 Lpath(nextarg(&ap, &av)); 156 break; 157 case 'o': 158 output = nextarg(&ap, &av); 159 break; 160 case 'e': 161 entry = nextarg(&ap, &av); 162 break; 163 default: 164 usage(); 165 } 166 } 167 } 168 169 if (!files) 170 usage(); 171 172 atexit(cleanup); 173 ld(argc, argv); 174 175 return status; 176 }