+ while (fgets(linkCommand, PATH_MAX, linkCommandsFile)) {
+ linkCommand[strlen(linkCommand)-1]='\0';
+
+ // skip empty lines
+ if (!*linkCommand) {
+ continue;
+ }
+
+ //puts (linkCommand);
+ if (*linkCommand=='-') {
+ switch (linkCommand[1])
+ {
+ case 'm':
+ // probably -muxi, ignore for now
+ break;
+ case 'e':
+ // -e, always in the last line, ignore for now
+ break;
+ case 'b':
+ {
+ // a segment start address like: "-b XSEG = 0x4000"
+ int s;
+ char *seg=strtok(&linkCommand[3], " \t");
+ for (s=0; s<MAX_SEGMENTS; s++) {
+ if (strcmp(segments[s].name, seg)==0) {
+ strtok(NULL, " \t"); // skip the '='
+ if (sscanf(strtok(NULL, " \t"), "%x",
+ &segments[s].start)!=1) {
+ syntaxError(linkCommand);
+ }
+ break;
+ }
+ }
+ if (s==MAX_SEGMENTS) {
+ syntaxError(linkCommand);
+ }
+ }
+ break;
+ case 'k':
+ // a lib path like: "-k /usr/local/share/sdcc/lib/xa51"; one/line
+ libraryPaths[nlibPaths++]=strdup(&linkCommand[3]);
+ break;
+ case 'l':
+ // a lib file like: "-l libsdcc"; one/line
+ libraryFiles[nlibFiles++]=strdup(&linkCommand[3]);
+ break;
+ default:
+ syntaxError(linkCommand);
+ }
+ } else {
+ // not a switch, must be an inputfile; one/line
+ readModule(linkCommand, 0);
+ // the first one defines the output name
+ if (!outFileName[0]) {
+ strncpy(outFileName, linkCommand,
+ strlen(linkCommand)-4);
+ sprintf(mapFileName, "%s.map", outFileName);
+ strcat(outFileName, ".hex");
+ if ((mapOut=fopen(mapFileName, "w"))==NULL) {
+ perror(mapFileName);
+ }
+ }
+ }
+ }
+
+ // add the segment symbols
+ currentSegment=findSegmentByName("XINIT");
+ addToDefs("s_XINIT", 0, 0);
+ addToDefs("l_XINIT", segments[XINIT]._size, 1);
+ currentSegment=findSegmentByName("XISEG");
+ addToDefs("s_XISEG", 0, 0);
+ addToDefs("l_XISEG", segments[XISEG]._size, 1);
+
+ // mark the resolved references
+ resolve();
+
+ // now do something EXTREMELY SLOW AND INEFFICIENT :)
+ while ((unresolved=relocate())) {
+ if (!scanLibraries(unresolved)) {
+ struct REFERENCE *reference;
+ resolve();
+ for (reference=references; reference; reference=reference->next) {
+ if (!reference->resolved) {
+ fprintf (stderr, "*** unresolved symbol %s in %s:%d\n",
+ reference->name, reference->module->name,
+ reference->lineno);
+ fatalErrors++;
+ }
+ }
+ break;
+ }
+ }
+
+ if (unresolved==0) {
+ writeModule(outFileName);
+ }
+
+ // the modules
+ fprintf (mapOut, "Modules:\n");
+ for (module=modules; module; module=module->next) {
+ fprintf (mapOut, "\t%s\n", module->name);
+ for (s=0; s<MAX_SEGMENTS; s++) {
+ if (module->size[s]) {
+ fprintf (mapOut, "\t\t%s:0x%04x-0x%04x\n", segments[s].name,
+ module->offset[s]+segments[s].start,
+ module->offset[s]+segments[s].start+module->size[s]);
+ }
+ }
+ }
+
+ // the segments
+ fprintf (mapOut, "\nSegments:\n");
+ for (s=1; s<MAX_SEGMENTS; s++) {
+ if (segments[s]._size) {
+ fprintf (mapOut, "\t%s start 0x%04x size 0x%04x %d symbols\n",
+ segments[s].name, segments[s].start,
+ segments[s]._size,
+ segments[s].hasSymbols);
+ }
+ }
+
+ // the symbols
+ fprintf (mapOut, "\nSymbols:\n");
+ for (symbol=symbols; symbol; symbol=symbol->next) {
+ fprintf (mapOut, "%s\t%s %s0x%04x %s\n", symbol->name,
+ symbol->segment->name,
+ symbol->absolute ? "= " : "",
+ symbol->address, symbol->module->name);
+ }
+
+ fclose(mapOut);
+ return fatalErrors? 1 : 0;