feat(tools): fas2sym: .sym file are now usable with gdb
This commit is contained in:
parent
34025f7766
commit
62127fc4fd
7 changed files with 104 additions and 13 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include "fas2sym.h"
|
#include "fas2sym.h"
|
||||||
|
|
||||||
enum sections {
|
enum sections {
|
||||||
SEC_NULL = 0,
|
SEC_NULL = 0,
|
||||||
|
SEC_TEXT,
|
||||||
SEC_SHSTRTAB,
|
SEC_SHSTRTAB,
|
||||||
SEC_STRTAB,
|
SEC_STRTAB,
|
||||||
SEC_SYMTAB,
|
SEC_SYMTAB,
|
||||||
|
|
@ -17,20 +19,25 @@ static Elf32_Ehdr elf_ehdr = {
|
||||||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
|
ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
},
|
},
|
||||||
ET_REL, EM_386, EV_CURRENT, 0, 0, 0, 0,
|
ET_DYN, EM_386, EV_CURRENT, 0, 0, 0, 0,
|
||||||
sizeof(Elf32_Ehdr), sizeof(Elf32_Phdr), 0,
|
sizeof(Elf32_Ehdr), sizeof(Elf32_Phdr), 0,
|
||||||
sizeof(Elf32_Shdr), SEC_END, SEC_SHSTRTAB
|
sizeof(Elf32_Shdr), SEC_END, SEC_SHSTRTAB
|
||||||
};
|
};
|
||||||
|
|
||||||
static Elf32_Shdr elf_shdrs[SEC_END] = {
|
static Elf32_Shdr elf_shdrs[SEC_END] = {
|
||||||
{ 0, SHT_NULL, 0, 0, 0, 0, SHN_UNDEF, 0, 0, 0 },
|
{ 0, SHT_NULL, 0, 0, 0, 0, SHN_UNDEF, 0, 0, 0 },
|
||||||
|
/* .text */
|
||||||
|
{
|
||||||
|
1, SHT_NOBITS, SHF_ALLOC | SHF_EXECINSTR,
|
||||||
|
0, 0, 0, SHN_UNDEF, 0, 1, 0
|
||||||
|
},
|
||||||
/* .shstrtab */
|
/* .shstrtab */
|
||||||
{ 1, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
{ 7, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
||||||
/* .strtab */
|
/* .strtab */
|
||||||
{ 11, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
{ 17, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
||||||
/* .symtab */
|
/* .symtab */
|
||||||
{
|
{
|
||||||
19, SHT_SYMTAB, 0, 0, 0, 0,
|
25, SHT_SYMTAB, 0, 0, 0, 0,
|
||||||
SEC_STRTAB, 0, 4, sizeof(Elf32_Sym)
|
SEC_STRTAB, 0, 4, sizeof(Elf32_Sym)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -42,7 +49,7 @@ static struct buffer elf_symtab = { 0, 0, NULL };
|
||||||
static int
|
static int
|
||||||
elf_shstrtab_init(void)
|
elf_shstrtab_init(void)
|
||||||
{
|
{
|
||||||
const uint8_t initial[] = "\0.shstrtab\0.strtab\0.symtab\0";
|
const uint8_t initial[] = "\0.text\0.shstrtab\0.strtab\0.symtab\0";
|
||||||
|
|
||||||
return (buffer_put(&elf_shstrtab, initial, sizeof(initial), NULL));
|
return (buffer_put(&elf_shstrtab, initial, sizeof(initial), NULL));
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +107,8 @@ elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size,
|
||||||
msg_verbose(2, "add symbol: %s",
|
msg_verbose(2, "add symbol: %s",
|
||||||
(char *)(elf_strtab.data + name_off));
|
(char *)(elf_strtab.data + name_off));
|
||||||
|
|
||||||
|
elf_shdrs[SEC_SYMTAB].sh_info += 1;
|
||||||
|
|
||||||
return (buffer_put(&elf_symtab, (uint8_t *)&sym,
|
return (buffer_put(&elf_symtab, (uint8_t *)&sym,
|
||||||
sizeof(Elf32_Sym), NULL));
|
sizeof(Elf32_Sym), NULL));
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +155,55 @@ elf_compute_section_offsets(void)
|
||||||
elf_shdrs[SEC_SYMTAB].sh_size = elf_symtab.cnt;
|
elf_shdrs[SEC_SYMTAB].sh_size = elf_symtab.cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf_resolve_symbols(void)
|
||||||
|
{
|
||||||
|
Elf32_Sym *syms;
|
||||||
|
char *strtab;
|
||||||
|
size_t idx;
|
||||||
|
size_t symcnt;
|
||||||
|
uint32_t begin = 0;
|
||||||
|
uint32_t end = 0;
|
||||||
|
|
||||||
|
if (text_begin == NULL || text_end == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
syms = (Elf32_Sym *)elf_symtab.data;
|
||||||
|
strtab = (char *)elf_strtab.data;
|
||||||
|
symcnt = (elf_symtab.cnt / sizeof(Elf32_Sym));
|
||||||
|
|
||||||
|
for (idx = 0; idx < symcnt; idx++)
|
||||||
|
{
|
||||||
|
if (strcmp(strtab + syms[idx].st_name, text_begin) == 0)
|
||||||
|
{
|
||||||
|
begin = syms[idx].st_value;
|
||||||
|
msg_verbose(1, "Sym %s: %X\n", text_begin, begin);
|
||||||
|
}
|
||||||
|
else if (strcmp(strtab + syms[idx].st_name, text_end) == 0)
|
||||||
|
{
|
||||||
|
end = syms[idx].st_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (begin != 0 && end != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elf_shdrs[SEC_TEXT].sh_addr = begin;
|
||||||
|
elf_shdrs[SEC_TEXT].sh_size = end - begin;
|
||||||
|
|
||||||
|
for (idx = 0; idx < symcnt; idx++)
|
||||||
|
{
|
||||||
|
if (syms[idx].st_value >= begin && syms[idx].st_value <= end)
|
||||||
|
{
|
||||||
|
syms[idx].st_shndx = SEC_TEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
elf_write(const char *file)
|
elf_write(const char *file)
|
||||||
{
|
{
|
||||||
|
|
@ -167,6 +225,8 @@ elf_write(const char *file)
|
||||||
elf_ehdr.e_shoff += elf_shstrtab.cnt + elf_strtab.cnt;
|
elf_ehdr.e_shoff += elf_shstrtab.cnt + elf_strtab.cnt;
|
||||||
elf_ehdr.e_shoff += elf_symtab.cnt;
|
elf_ehdr.e_shoff += elf_symtab.cnt;
|
||||||
|
|
||||||
|
elf_resolve_symbols();
|
||||||
|
|
||||||
if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1)
|
if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1)
|
||||||
{
|
{
|
||||||
msg_errx("%s: An error occurred while writting elf header", file);
|
msg_errx("%s: An error occurred while writting elf header", file);
|
||||||
|
|
@ -193,7 +253,7 @@ elf_write(const char *file)
|
||||||
/* section headers */
|
/* section headers */
|
||||||
elf_compute_section_offsets();
|
elf_compute_section_offsets();
|
||||||
/* XXX: fix me */
|
/* XXX: fix me */
|
||||||
elf_shdrs[SEC_SYMTAB].sh_info = 0; /* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/
|
elf_shdrs[SEC_SYMTAB].sh_info += 1;/*= 0; *//* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/
|
||||||
|
|
||||||
if (fwrite(elf_shdrs, sizeof(Elf32_Shdr), SEC_END, fp) != SEC_END)
|
if (fwrite(elf_shdrs, sizeof(Elf32_Shdr), SEC_END, fp) != SEC_END)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,9 @@ fas_export_symbol_name(uint32_t name_off)
|
||||||
return (0); /* anonymous symbol */
|
return (0); /* anonymous symbol */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name_off & (1<<31)) /* if in fas strtab */
|
if (name_off & (1u<<31)) /* if in fas strtab */
|
||||||
{
|
{
|
||||||
ptr = fas_strtab + (name_off & ~(1<<31)); /* XXX */
|
ptr = fas_strtab + (name_off & ~(1u<<31)); /* XXX */
|
||||||
}
|
}
|
||||||
else /* otherwhise it's in psrc */
|
else /* otherwhise it's in psrc */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ int elf_write(const char *file);
|
||||||
void elf_cleanup(void);
|
void elf_cleanup(void);
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
|
extern const char *text_begin;
|
||||||
|
extern const char *text_end;
|
||||||
|
|
||||||
void msg_err(const char *fmt, ...);
|
void msg_err(const char *fmt, ...);
|
||||||
void msg_errx(const char *fmt, ...);
|
void msg_errx(const char *fmt, ...);
|
||||||
void msg_verbose(int level, const char *fmt, ...);
|
void msg_verbose(int level, const char *fmt, ...);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
static const char *prg_name;
|
static const char *prg_name;
|
||||||
static const char *outfile = "out.sym";
|
static const char *outfile = "out.sym";
|
||||||
static int verbose = 0;
|
static int verbose = 0;
|
||||||
|
const char *text_begin = NULL;
|
||||||
|
const char *text_end = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
msg_err_common(const char *fmt, va_list ap)
|
msg_err_common(const char *fmt, va_list ap)
|
||||||
|
|
@ -77,6 +79,15 @@ usage(int retval)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Usage: %s [-o OUTPUT] file\n", prg_name);
|
printf("Usage: %s [-o OUTPUT] file\n", prg_name);
|
||||||
|
printf("OPTIONS:\n");
|
||||||
|
printf(" -o OUTPUT Set output file (default: %s)\n",
|
||||||
|
outfile);
|
||||||
|
printf(" -t begin,end XXXX (addr or symbol)\n");
|
||||||
|
/*
|
||||||
|
* -t start,end (text)
|
||||||
|
* -b start,end (bss)
|
||||||
|
* -d start,end (data)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(retval);
|
exit(retval);
|
||||||
|
|
@ -95,10 +106,11 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int status;
|
int status;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
prg_name = basename(argv[0]);
|
prg_name = basename(argv[0]);
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "hvVo:")) != -1)
|
while ((c = getopt(argc, argv, "hvVo:t:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
@ -114,6 +126,19 @@ main(int argc, char **argv)
|
||||||
case 'o':
|
case 'o':
|
||||||
outfile = optarg;
|
outfile = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
tmp = strchr(optarg, ',');
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
*tmp = '\0';
|
||||||
|
text_begin = optarg;
|
||||||
|
text_end = tmp + 1;
|
||||||
|
|
||||||
|
msg_verbose(2, ".text: %s, %s", text_begin, text_end);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(EXIT_FAILURE);
|
usage(EXIT_FAILURE);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ print_symbol_section(uint8_t type, uint32_t rel)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rel & (1<<31))
|
if (rel & (1u<<31))
|
||||||
{
|
{
|
||||||
printf("UND ");
|
printf("UND ");
|
||||||
}
|
}
|
||||||
|
|
@ -204,9 +204,9 @@ print_symbol_name(uint32_t off)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (off & (1<<31))
|
if (off & (1u<<31))
|
||||||
{
|
{
|
||||||
printf("%s", strtab + (off & ~(1<<31)));
|
printf("%s", strtab + (off & ~(1u<<31)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -230,6 +230,7 @@ print_symbols(void)
|
||||||
printf("%-4" PRIu8 " ", symtab[idx].size);
|
printf("%-4" PRIu8 " ", symtab[idx].size);
|
||||||
print_symbol_section(symtab[idx].type, symtab[idx].reloc);
|
print_symbol_section(symtab[idx].type, symtab[idx].reloc);
|
||||||
print_symbol_name(symtab[idx].name_off);
|
print_symbol_name(symtab[idx].name_off);
|
||||||
|
/*printf(" %" PRIx8, symtab[idx].flags); */
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ SRCS = kernel.asm \
|
||||||
bio.inc \
|
bio.inc \
|
||||||
$(ASMINCS)
|
$(ASMINCS)
|
||||||
|
|
||||||
|
FAS2SYMFLAGS = -t kmain,kend
|
||||||
|
|
||||||
.PHONY: const.inc
|
.PHONY: const.inc
|
||||||
const.inc: const.inc.in
|
const.inc: const.inc.in
|
||||||
@$(VERSION_SH)
|
@$(VERSION_SH)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ $(KERNEL).sys $(KERNEL).fas &: $(SRCS)
|
||||||
|
|
||||||
$(KERNEL).sym: $(KERNEL).fas
|
$(KERNEL).sym: $(KERNEL).fas
|
||||||
$(MSG_CREATE)
|
$(MSG_CREATE)
|
||||||
@$(FAS2SYM) -o $@ $<
|
@$(FAS2SYM) $(FAS2SYMFLAGS) -o $@ $<
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: $(DESTDIR)/$(KERNEL).sys $(SYMSDIR)/$(KERNEL).sym
|
install: $(DESTDIR)/$(KERNEL).sys $(SYMSDIR)/$(KERNEL).sym
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue