# HG changeset patch
# User lost
# Date 1237664865 0
# Node ID b89adfb0d17452a01f8212d2c08366004616623c
# Parent 220a760ec654d8bf3864c9a0cc0d6d5b1c34a3a5
Added support for outputting a linkmap
diff -r 220a760ec654 -r b89adfb0d174 ChangeLog
--- a/ChangeLog Sat Mar 21 17:39:45 2009 +0000
+++ b/ChangeLog Sat Mar 21 19:47:45 2009 +0000
@@ -16,6 +16,7 @@
[*] added library search path (-L) and library specification (-l) to LWLINK
[*] added ability to specify section base addresses on the command line to
LWLINK (they get prepended to the built in link script)
+[*] added ability to output a "linkmap" to lwlink (--map, -m)
[b] arranged for output files for lwasm/lwlink to be removed if the assembly
or linking fails
[ ] DECB output of LWLINK now collapses contiguous output blocks into single
diff -r 220a760ec654 -r b89adfb0d174 lwlink/Makefile.am
--- a/lwlink/Makefile.am Sat Mar 21 17:39:45 2009 +0000
+++ b/lwlink/Makefile.am Sat Mar 21 19:47:45 2009 +0000
@@ -1,4 +1,4 @@
bin_PROGRAMS = lwlink lwobjdump
-lwlink_SOURCES = main.c lwlink.c util.c readfiles.c expr.c script.c link.c output.c
+lwlink_SOURCES = main.c lwlink.c util.c readfiles.c expr.c script.c link.c output.c map.c
lwobjdump_SOURCES = objdump.c util.c
EXTRA_DIST = lwlink.h util.h expr.h
diff -r 220a760ec654 -r b89adfb0d174 lwlink/lwlink.c
--- a/lwlink/lwlink.c Sat Mar 21 17:39:45 2009 +0000
+++ b/lwlink/lwlink.c Sat Mar 21 19:47:45 2009 +0000
@@ -41,6 +41,7 @@
char *outfile = NULL;
char *scriptfile = NULL;
int symerr = 0;
+char *map_file = NULL;
fileinfo_t **inputfiles = NULL;
int ninputfiles = 0;
diff -r 220a760ec654 -r b89adfb0d174 lwlink/lwlink.h
--- a/lwlink/lwlink.h Sat Mar 21 17:39:45 2009 +0000
+++ b/lwlink/lwlink.h Sat Mar 21 19:47:45 2009 +0000
@@ -110,6 +110,8 @@
extern int symerr;
+extern char *map_file;
+
#define __lwlink_E__ extern
#else
#define __lwlink_E__
diff -r 220a760ec654 -r b89adfb0d174 lwlink/main.c
--- a/lwlink/main.c Sat Mar 21 17:39:45 2009 +0000
+++ b/lwlink/main.c Sat Mar 21 19:47:45 2009 +0000
@@ -96,7 +96,11 @@
case 0x100:
add_section_base(arg);
break;
-
+
+ case 'm':
+ map_file = arg;
+ break;
+
case ARGP_KEY_ARG:
add_input_file(arg);
break;
@@ -127,6 +131,8 @@
"Add DIR to the library search path" },
{ "section-base", 0x100, "SECT=BASE", 0,
"Load section SECT at BASE" },
+ { "map", 'm', "FILE", 0,
+ "Output informaiton about the link" },
{ 0 }
};
@@ -143,6 +149,7 @@
extern void resolve_sections(void);
extern void resolve_references(void);
extern void do_output(void);
+extern void display_map(void);
// main function; parse command line, set up assembler state, and run the
// assembler on the first file
@@ -171,6 +178,10 @@
// do the actual output
do_output();
-
+
+ // display/output the link map
+ if (map_file)
+ display_map();
+
exit(0);
}
diff -r 220a760ec654 -r b89adfb0d174 lwlink/map.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlink/map.c Sat Mar 21 19:47:45 2009 +0000
@@ -0,0 +1,117 @@
+/*
+map.c
+Copyright © 2009 William Astle
+
+This file is part of LWLINK.
+
+LWLINK is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+
+
+Output information about the linking process
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+
+#include "lwlink.h"
+#include "util.h"
+
+struct symliste
+{
+ char *name;
+ char *fn;
+ int addr;
+ int ext;
+ struct symliste *next;
+};
+
+void display_map(void)
+{
+ FILE *of;
+ int sn;
+ int std = 0;
+ struct symliste *slist = NULL;
+ struct symliste *ce, *pe, *ne;
+ symtab_t *sym;
+ int i;
+
+ if (!strcmp(map_file, "-"))
+ {
+ std = 1;
+ of = stdout;
+ }
+ else
+ {
+ of = fopen(map_file, "w");
+ if (!of)
+ {
+ fprintf(stderr, "Cannot open map file - using stdout\n");
+ std = 1;
+ of = stdout;
+ }
+ }
+
+ // display section list
+ for (sn = 0; sn < nsects; sn++)
+ {
+ fprintf(of, "Section: %s (%s) load at %04X, length %04X\n",
+ sectlist[sn].ptr -> name,
+ sectlist[sn].ptr -> file -> filename,
+ sectlist[sn].ptr -> loadaddress,
+ sectlist[sn].ptr -> codesize
+ );
+ }
+
+ // generate a sorted list of symbols and display it
+ for (sn = 0; sn < nsects; sn++)
+ {
+ for (sym = sectlist[sn].ptr -> localsyms; sym; sym = sym -> next)
+ {
+ for (pe = NULL, ce = slist; ce; ce = ce -> next)
+ {
+ i = strcmp(ce -> name, sym -> sym);
+ if (i == 0)
+ {
+ i = strcmp(ce -> fn, sectlist[sn].ptr -> file -> filename);
+ }
+ if (i > 0)
+ break;
+ pe = ce;
+ }
+ ne = lw_malloc(sizeof(struct symliste));
+ ne -> ext = 0;
+ ne -> addr = sym -> offset + sectlist[sn].ptr -> loadaddress;
+ ne -> next = ce;
+ ne -> name = sym -> sym;
+ ne -> fn = sectlist[sn].ptr -> file -> filename;
+ if (pe)
+ pe -> next = ne;
+ else
+ slist = ne;
+ }
+ }
+
+ for (ce = slist; ce; ce = ce -> next)
+ {
+ fprintf(of, "Symbol: %s (%s) = %04X\n", ce -> name, ce -> fn, ce -> addr);
+ }
+
+ if (!std)
+ fclose(of);
+}