1#include <errno.h>2#include <stdarg.h>3#include <stdio.h>4#include <stdlib.h>5#include <string.h>67#include <scc/mach.h>89#include "ld.h"1011#define MAX_LIB_PATHS 121213int sflag; /* discard all the symbols */14int xflag; /* discard local symbols */15int Xflag; /* discard locals starting with 'L' */16int rflag; /* preserve relocation bits */17int dflag; /* define common even with rflag */18int gflag; /* preserve debug symbols */19int nmagic; /* nmagic output */2021char *filename, *membname;2223Section text = {.type = 'T'};24Section rodata = {.type = 'R'};25Section data = {.type = 'D'};26Section bss = {.type = 'B'};27Section debug = {.type = 'N'};2829char *libpaths[MAX_LIB_PATHS];3031char *output = "a.out", *entry = "start";32static int status;3334void35error(char *fmt, ...)36{37 va_list va;3839 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);4647 status = EXIT_FAILURE;48}4950static void51cleanup(void)52{53 if (status != EXIT_FAILURE)54 remove(output);55}5657/*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 sections61 * pass4: Create the temporary files per section62 * pass5: Create the temporary files per segment63 */64static void65ld(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}7778static void79usage(void)80{81 fputs("usage: ld [options] file ...\n", stderr);82 exit(EXIT_FAILURE);83}8485static void86Lpath(char *path)87{88 char **bp, **end;8990 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}99100char *101nextarg(char **argp, char ***argv)102{103 char *ap = *argp, **av = *argv;104105 if (ap[1]) {106 *argp += strlen(ap);107 return ap+1;108 }109110 if (av[1]) {111 *argv = ++av;112 return *av;113 }114115 usage();116}117118int119main(int argc, char *argv[])120{121 int files = 0;122 char *ap, **av;123124 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 }168169 if (!files)170 usage();171172 atexit(cleanup);173 ld(argc, argv);174175 return status;176}