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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
#include "fas2sym.h"
|
||||
|
||||
enum sections {
|
||||
SEC_NULL = 0,
|
||||
SEC_TEXT,
|
||||
SEC_SHSTRTAB,
|
||||
SEC_STRTAB,
|
||||
SEC_SYMTAB,
|
||||
|
|
@ -17,20 +19,25 @@ static Elf32_Ehdr elf_ehdr = {
|
|||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
|
||||
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_Shdr), SEC_END, SEC_SHSTRTAB
|
||||
};
|
||||
|
||||
static Elf32_Shdr elf_shdrs[SEC_END] = {
|
||||
{ 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 */
|
||||
{ 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 */
|
||||
{ 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 */
|
||||
{
|
||||
19, SHT_SYMTAB, 0, 0, 0, 0,
|
||||
25, SHT_SYMTAB, 0, 0, 0, 0,
|
||||
SEC_STRTAB, 0, 4, sizeof(Elf32_Sym)
|
||||
}
|
||||
};
|
||||
|
|
@ -42,7 +49,7 @@ static struct buffer elf_symtab = { 0, 0, NULL };
|
|||
static int
|
||||
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));
|
||||
}
|
||||
|
|
@ -100,6 +107,8 @@ elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size,
|
|||
msg_verbose(2, "add symbol: %s",
|
||||
(char *)(elf_strtab.data + name_off));
|
||||
|
||||
elf_shdrs[SEC_SYMTAB].sh_info += 1;
|
||||
|
||||
return (buffer_put(&elf_symtab, (uint8_t *)&sym,
|
||||
sizeof(Elf32_Sym), NULL));
|
||||
}
|
||||
|
|
@ -146,6 +155,55 @@ elf_compute_section_offsets(void)
|
|||
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
|
||||
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_symtab.cnt;
|
||||
|
||||
elf_resolve_symbols();
|
||||
|
||||
if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1)
|
||||
{
|
||||
msg_errx("%s: An error occurred while writting elf header", file);
|
||||
|
|
@ -193,7 +253,7 @@ elf_write(const char *file)
|
|||
/* section headers */
|
||||
elf_compute_section_offsets();
|
||||
/* 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -131,9 +131,9 @@ fas_export_symbol_name(uint32_t name_off)
|
|||
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 */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ int elf_write(const char *file);
|
|||
void elf_cleanup(void);
|
||||
|
||||
/* main.c */
|
||||
extern const char *text_begin;
|
||||
extern const char *text_end;
|
||||
|
||||
void msg_err(const char *fmt, ...);
|
||||
void msg_errx(const char *fmt, ...);
|
||||
void msg_verbose(int level, const char *fmt, ...);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
static const char *prg_name;
|
||||
static const char *outfile = "out.sym";
|
||||
static int verbose = 0;
|
||||
const char *text_begin = NULL;
|
||||
const char *text_end = NULL;
|
||||
|
||||
static void
|
||||
msg_err_common(const char *fmt, va_list ap)
|
||||
|
|
@ -77,6 +79,15 @@ usage(int retval)
|
|||
else
|
||||
{
|
||||
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);
|
||||
|
|
@ -95,10 +106,11 @@ main(int argc, char **argv)
|
|||
{
|
||||
int c;
|
||||
int status;
|
||||
char *tmp;
|
||||
|
||||
prg_name = basename(argv[0]);
|
||||
|
||||
while ((c = getopt(argc, argv, "hvVo:")) != -1)
|
||||
while ((c = getopt(argc, argv, "hvVo:t:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -114,6 +126,19 @@ main(int argc, char **argv)
|
|||
case 'o':
|
||||
outfile = optarg;
|
||||
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:
|
||||
usage(EXIT_FAILURE);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ print_symbol_section(uint8_t type, uint32_t rel)
|
|||
return;
|
||||
}
|
||||
|
||||
if (rel & (1<<31))
|
||||
if (rel & (1u<<31))
|
||||
{
|
||||
printf("UND ");
|
||||
}
|
||||
|
|
@ -204,9 +204,9 @@ print_symbol_name(uint32_t off)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (off & (1<<31))
|
||||
if (off & (1u<<31))
|
||||
{
|
||||
printf("%s", strtab + (off & ~(1<<31)));
|
||||
printf("%s", strtab + (off & ~(1u<<31)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -230,6 +230,7 @@ print_symbols(void)
|
|||
printf("%-4" PRIu8 " ", symtab[idx].size);
|
||||
print_symbol_section(symtab[idx].type, symtab[idx].reloc);
|
||||
print_symbol_name(symtab[idx].name_off);
|
||||
/*printf(" %" PRIx8, symtab[idx].flags); */
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ SRCS = kernel.asm \
|
|||
bio.inc \
|
||||
$(ASMINCS)
|
||||
|
||||
FAS2SYMFLAGS = -t kmain,kend
|
||||
|
||||
.PHONY: const.inc
|
||||
const.inc: const.inc.in
|
||||
@$(VERSION_SH)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ $(KERNEL).sys $(KERNEL).fas &: $(SRCS)
|
|||
|
||||
$(KERNEL).sym: $(KERNEL).fas
|
||||
$(MSG_CREATE)
|
||||
@$(FAS2SYM) -o $@ $<
|
||||
@$(FAS2SYM) $(FAS2SYMFLAGS) -o $@ $<
|
||||
|
||||
.PHONY: install
|
||||
install: $(DESTDIR)/$(KERNEL).sys $(SYMSDIR)/$(KERNEL).sym
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue