Skip to content

Commit

Permalink
Output map file
Browse files Browse the repository at this point in the history
Fix #98
  • Loading branch information
tyfkda committed Nov 24, 2023
1 parent 93cd1c3 commit 8ad63be
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 4 deletions.
85 changes: 85 additions & 0 deletions src/ld/ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static const char kDefaultEntryName[] = "_start";
//

typedef struct {
const char *filename;
enum {
FK_ELFOBJ,
FK_ARCHIVE,
Expand Down Expand Up @@ -71,6 +72,7 @@ void ld_init(LinkEditor *ld, int nfiles) {
void ld_load(LinkEditor *ld, int i, const char *filename) {
char *ext = get_ext(filename);
File *file = &ld->files[i];
file->filename = filename;
if (strcasecmp(ext, "o") == 0) {
ElfObj *elfobj = malloc_or_die(sizeof(*elfobj));
elfobj_init(elfobj);
Expand Down Expand Up @@ -455,13 +457,72 @@ static bool output_exe(const char *ofn, uintptr_t entry_address) {
return true;
}

static void dump_map_elfobj(LinkEditor *ld, ElfObj *elfobj, File *file, ArContent *content, FILE *fp) {
const Name *name;
Elf64_Sym* sym;
for (int it = 0; (it = table_iterate(elfobj->symbol_table, it, &name, (void**)&sym)) != -1; ) {
if (sym->st_shndx == SHN_UNDEF)
continue;

uintptr_t address = 0;
switch (ELF64_ST_BIND(sym->st_info)) {
case STB_LOCAL:
{
const ElfSectionInfo *s = &elfobj->section_infos[sym->st_shndx];
address = s->progbits.address;
}
break;
case STB_GLOBAL:
{
ElfObj *telfobj;
const Elf64_Sym *tsym = ld_find_symbol(ld, name, &telfobj);
address = telfobj->section_infos[tsym->st_shndx].progbits.address + tsym->st_value;
}
break;
default: assert(false); break;
}
fprintf(fp, "%9lx: %.*s (%s", address, NAMES(name), file->filename);
if (content != NULL)
fprintf(fp, ", %s", content->name);
fprintf(fp, ")\n");
}
}

static void dump_map_file(LinkEditor *ld, FILE *fp) {
for (int i = 0; i < ld->nfiles; ++i) {
File *file = &ld->files[i];
switch (file->kind) {
case FK_ELFOBJ:
dump_map_elfobj(ld, file->elfobj, file, NULL, fp);
break;
case FK_ARCHIVE:
{
Archive *ar = file->archive;
for (int j = 0; j < ar->contents->len; j += 2) {
ArContent *content = ar->contents->data[j + 1];
dump_map_elfobj(ld, content->elfobj, file, content, fp);
}
}
break;
}
}
}

int main(int argc, char *argv[]) {
const char *ofn = NULL;
const char *entry = kDefaultEntryName;
const char *outmapfn = NULL;

enum {
OPT_HELP = 128,
OPT_VERSION,
OPT_OUTMAP,
};

static const struct option options[] = {
{"o", required_argument}, // Specify output filename
{"e", required_argument}, // Entry name
{"Map", required_argument, OPT_OUTMAP}, // Output map file
{"-version", no_argument, 'V'},
{NULL},
};
Expand All @@ -477,6 +538,9 @@ int main(int argc, char *argv[]) {
case 'e':
entry = optarg;
break;
case OPT_OUTMAP:
outmapfn = optarg;
break;
default:
fprintf(stderr, "Warning: unknown option: %s\n", argv[optind - 1]);
break;
Expand Down Expand Up @@ -515,6 +579,27 @@ int main(int argc, char *argv[]) {
uintptr_t entry_address = telfobj->section_infos[tsym->st_shndx].progbits.address + tsym->st_value;

result = output_exe(ofn, entry_address);

if (outmapfn != NULL && result) {
FILE *mapfp;
if (strcmp(outmapfn, "-") == 0) {
mapfp = stdout;
} else {
mapfp = fopen(outmapfn, "w");
if (mapfp == NULL)
perror("Failed to open map file");
}

fprintf(mapfp, "### Symbols\n");
fprintf(mapfp, "%9lx: (start address)\n", (long)LOAD_ADDRESS);
dump_map_file(ld, mapfp);

fprintf(mapfp, "\n### Entry point\n");
fprintf(mapfp, "%9lx: %.*s\n", entry_address, NAMES(entry_name));

if (mapfp != stdout)
fclose(mapfp);
}
}
return result ? 0 : 1;
}
14 changes: 10 additions & 4 deletions src/xcc/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ int main(int argc, char *argv[]) {
OPT_NOSTDINC,
OPT_ISYSTEM,
OPT_IDIRAFTER,
OPT_LINKOPTION,

OPT_ANSI,
OPT_STD,
Expand All @@ -337,6 +338,7 @@ int main(int argc, char *argv[]) {
{"nodefaultlibs", no_argument, OPT_NODEFAULTLIBS},
{"nostdlib", no_argument, OPT_NOSTDLIB},
{"nostdinc", no_argument, OPT_NOSTDINC},
{"Xlinker", required_argument, OPT_LINKOPTION},
{"-help", no_argument, OPT_HELP},
{"-version", no_argument, OPT_VERSION},

Expand Down Expand Up @@ -416,10 +418,11 @@ int main(int argc, char *argv[]) {
}
break;
case 'W':
vec_push(cc1_cmd, "-W");
vec_push(cc1_cmd, optarg);
if (strncmp(argv[optind - 1], "-Wl", 3) == 0) {
vec_push(linker_options, argv[optind - 1]);
if (strncmp(argv[optind - 1], "-Wl,", 4) == 0) {
vec_push(ld_cmd, argv[optind - 1] + 4);
} else {
vec_push(cc1_cmd, "-W");
vec_push(cc1_cmd, optarg);
}
break;
case OPT_NODEFAULTLIBS:
Expand All @@ -433,6 +436,9 @@ int main(int argc, char *argv[]) {
case OPT_NOSTDINC:
nostdinc = true;
break;
case OPT_LINKOPTION:
vec_push(ld_cmd, optarg);
break;
case 'f':
if (strncmp(optarg, "use-ld", 6) == 0) {
if (optarg[6] == '=') {
Expand Down

0 comments on commit 8ad63be

Please sign in to comment.