scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  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
 13int 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 */
 20
 21char *filename, *membname;
 22
 23Section text = {.type = 'T'};
 24Section rodata = {.type = 'R'};
 25Section data = {.type = 'D'};
 26Section bss = {.type = 'B'};
 27Section debug = {.type = 'N'};
 28
 29char *libpaths[MAX_LIB_PATHS];
 30
 31char *output = "a.out", *entry = "start";
 32static int status;
 33
 34void
 35error(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
 50static void
 51cleanup(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 */
 64static void
 65ld(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
 78static void
 79usage(void)
 80{
 81	fputs("usage: ld [options] file ...\n", stderr);
 82	exit(EXIT_FAILURE);
 83}
 84
 85static void
 86Lpath(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
100char *
101nextarg(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
118int
119main(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}