feat(tools): fas2dump: generate elf file with symbol table from .fas
This commit is contained in:
parent
ca6e6e9487
commit
81abea70fd
12 changed files with 1320 additions and 25 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -33,6 +33,9 @@ bochsrc.bxrc
|
|||
*.EFI
|
||||
*.fd
|
||||
*.mod
|
||||
*.fas
|
||||
*.sym
|
||||
*.dbg
|
||||
webring.json
|
||||
webring.txt
|
||||
kernel/const.inc
|
||||
|
|
39
bin/fas2sym/buffer.c
Normal file
39
bin/fas2sym/buffer.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fas2sym.h"
|
||||
|
||||
int
|
||||
buffer_put(struct buffer *buff, const uint8_t *data, size_t size,
|
||||
size_t *index)
|
||||
{
|
||||
if (index != NULL)
|
||||
{
|
||||
*index = buff->cnt;
|
||||
}
|
||||
|
||||
while (buff->cap < buff->cnt + size)
|
||||
{
|
||||
buff->cap = (buff->cap == 0 ? 32 : buff->cap * 2);
|
||||
buff->data = (uint8_t *)realloc(buff->data, buff->cap);
|
||||
if (buff->data == NULL)
|
||||
{
|
||||
msg_err(NULL);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buff->data + buff->cnt, data, size);
|
||||
buff->cnt += size;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_cleanup(struct buffer *buff)
|
||||
{
|
||||
buff->cnt = 0;
|
||||
buff->cap = 0;
|
||||
free(buff->data);
|
||||
buff->data = 0;
|
||||
}
|
216
bin/fas2sym/elf.c
Normal file
216
bin/fas2sym/elf.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <elf.h>
|
||||
#include "fas2sym.h"
|
||||
|
||||
enum sections {
|
||||
SEC_NULL = 0,
|
||||
SEC_SHSTRTAB,
|
||||
SEC_STRTAB,
|
||||
SEC_SYMTAB,
|
||||
SEC_END
|
||||
};
|
||||
|
||||
static Elf32_Ehdr elf_ehdr = {
|
||||
{
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
|
||||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
},
|
||||
ET_REL, 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 },
|
||||
/* .shstrtab */
|
||||
{ 1, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
||||
/* .strtab */
|
||||
{ 11, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 },
|
||||
/* .symtab */
|
||||
{
|
||||
19, SHT_SYMTAB, 0, 0, 0, 0,
|
||||
SEC_STRTAB, 0, 4, sizeof(Elf32_Sym)
|
||||
}
|
||||
};
|
||||
|
||||
static struct buffer elf_shstrtab = { 0, 0, NULL };
|
||||
static struct buffer elf_strtab = { 0, 0, NULL };
|
||||
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";
|
||||
|
||||
return (buffer_put(&elf_shstrtab, initial, sizeof(initial), NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
elf_strtab_init(void)
|
||||
{
|
||||
const uint8_t initial[] = "\0";
|
||||
|
||||
return (buffer_put(&elf_strtab, initial, sizeof(initial), NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
elf_symtab_init(void)
|
||||
{
|
||||
const Elf32_Sym initial = { 0, 0, 0, 0, 0, SHN_UNDEF };
|
||||
|
||||
return (buffer_put(&elf_symtab, (uint8_t *)&initial,
|
||||
sizeof(Elf32_Sym), NULL));
|
||||
}
|
||||
|
||||
int
|
||||
elf_init(void)
|
||||
{
|
||||
if (elf_shstrtab_init() != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (elf_strtab_init() != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (elf_symtab_init() != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size,
|
||||
uint8_t info, uint16_t sect)
|
||||
{
|
||||
Elf32_Sym sym = { 0 };
|
||||
|
||||
sym.st_name = name_off;
|
||||
sym.st_value = value;
|
||||
sym.st_size = size;
|
||||
sym.st_info = info;
|
||||
sym.st_shndx = sect;
|
||||
|
||||
msg_verbose(2, "add symbol: %s",
|
||||
(char *)(elf_strtab.data + name_off));
|
||||
|
||||
return (buffer_put(&elf_symtab, (uint8_t *)&sym,
|
||||
sizeof(Elf32_Sym), NULL));
|
||||
}
|
||||
|
||||
int
|
||||
elf_add_str(const char *str, size_t len, size_t *idx)
|
||||
{
|
||||
return (buffer_put(&elf_strtab, (uint8_t *)str, len, idx));
|
||||
}
|
||||
|
||||
static int
|
||||
elf_write_tab(struct buffer *buff, FILE *fp)
|
||||
{
|
||||
if (buff->cnt == 0 || buff->data == NULL)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (fwrite(buff->data, buff->cnt, 1, fp) != 1)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
elf_compute_section_offsets(void)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
offset = sizeof(Elf32_Ehdr);
|
||||
elf_shdrs[SEC_SHSTRTAB].sh_offset = offset;
|
||||
elf_shdrs[SEC_SHSTRTAB].sh_size = elf_shstrtab.cnt;
|
||||
|
||||
offset += elf_shstrtab.cnt;
|
||||
|
||||
elf_shdrs[SEC_STRTAB].sh_offset = offset;
|
||||
elf_shdrs[SEC_STRTAB].sh_size = elf_strtab.cnt;
|
||||
|
||||
offset += elf_strtab.cnt;
|
||||
|
||||
elf_shdrs[SEC_SYMTAB].sh_offset = offset;
|
||||
elf_shdrs[SEC_SYMTAB].sh_size = elf_symtab.cnt;
|
||||
}
|
||||
|
||||
int
|
||||
elf_write(const char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
int status;
|
||||
size_t offset;
|
||||
|
||||
fp = fopen(file, "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
msg_err(file);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
status = -1;
|
||||
|
||||
/* compute section headers offset */
|
||||
elf_ehdr.e_shoff = sizeof(Elf32_Ehdr);
|
||||
elf_ehdr.e_shoff += elf_shstrtab.cnt + elf_strtab.cnt;
|
||||
elf_ehdr.e_shoff += elf_symtab.cnt;
|
||||
|
||||
if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1)
|
||||
{
|
||||
msg_errx("%s: An error occurred while writting elf header", file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (elf_write_tab(&elf_shstrtab, fp) != 0)
|
||||
{
|
||||
msg_errx("%s: An error occured while writting .shstrtab data", file);
|
||||
goto end;
|
||||
}
|
||||
if (elf_write_tab(&elf_strtab, fp) != 0)
|
||||
{
|
||||
msg_errx("%s: An error occured while writting .strtab data", file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (elf_write_tab(&elf_symtab, fp) != 0)
|
||||
{
|
||||
msg_errx("%s: An error occured while writting .symtab data", file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* section headers */
|
||||
elf_compute_section_offsets();
|
||||
/* XXX: fix me */
|
||||
elf_shdrs[SEC_SYMTAB].sh_info = 0; /* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/
|
||||
|
||||
if (fwrite(elf_shdrs, sizeof(Elf32_Shdr), SEC_END, fp) != SEC_END)
|
||||
{
|
||||
msg_errx("%s: An error occured while writting sections headers", file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
end:
|
||||
fclose(fp);
|
||||
return (status);
|
||||
}
|
||||
|
||||
void
|
||||
elf_cleanup(void)
|
||||
{
|
||||
buffer_cleanup(&elf_shstrtab);
|
||||
buffer_cleanup(&elf_strtab);
|
||||
buffer_cleanup(&elf_symtab);
|
||||
}
|
192
bin/fas2sym/fas.c
Normal file
192
bin/fas2sym/fas.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <fas.h>
|
||||
#include <elf.h>
|
||||
#include "fas2sym.h"
|
||||
|
||||
static FAS_Hdr fas_hdr;
|
||||
static char *fas_strtab = NULL;
|
||||
static FAS_Sym *fas_symtab = NULL;
|
||||
static uint8_t *fas_psrc = NULL;
|
||||
static size_t fas_sym_cnt = 0;
|
||||
|
||||
static void
|
||||
pstr2cstr(char *dst, const uint8_t *src)
|
||||
{
|
||||
size_t psz;
|
||||
|
||||
psz = *src++;
|
||||
while (psz > 0)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
psz--;
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
fas_load_table(uint8_t **dest, size_t offset, size_t size, FILE *fp)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
return (0); /* XXX */
|
||||
}
|
||||
|
||||
*dest = (uint8_t *)malloc(size);
|
||||
if (*dest == NULL)
|
||||
{
|
||||
msg_err(NULL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fseek(fp, offset, SEEK_SET) != 0)
|
||||
{
|
||||
msg_err(NULL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fread(*dest, size, 1, fp) != 1)
|
||||
{
|
||||
msg_errx("An unexpected error/eof occured while reading");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fas_load_file(const char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(file, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
msg_err(file);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fread(&fas_hdr, sizeof(FAS_Hdr), 1, fp) != 1)
|
||||
{
|
||||
msg_errx("%s: unexpected error/eof while reading FAS header",
|
||||
file);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fas_hdr.magic != FAS_MAGIC)
|
||||
{
|
||||
msg_errx("%s: invalid magic, got '%08" PRIX32
|
||||
"' instead of '%08" PRIX32 "'",
|
||||
file, (uint32_t)FAS_MAGIC);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fas_load_table((uint8_t **)&fas_strtab, fas_hdr.strtab_off,
|
||||
fas_hdr.strtab_len, fp) != 0)
|
||||
{
|
||||
msg_errx("%s: can't load string table", file);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
if (fas_load_table((uint8_t **)&fas_symtab, fas_hdr.symtab_off,
|
||||
fas_hdr.symtab_len, fp) != 0)
|
||||
{
|
||||
msg_errx("%s: can't load symbol table", file);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
if (fas_load_table(&fas_psrc, fas_hdr.psrc_off, fas_hdr.psrc_len,
|
||||
fp) != 0)
|
||||
{
|
||||
msg_errx("%s: can't load preprocessed sources", file);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
fas_sym_cnt = fas_hdr.symtab_len / sizeof(FAS_Sym);
|
||||
|
||||
msg_verbose(1, "%zu symbol(s) loaded from %s", fas_sym_cnt, file);
|
||||
|
||||
fclose(fp);
|
||||
return (0);
|
||||
|
||||
err_cleanup:
|
||||
fas_cleanup();
|
||||
err:
|
||||
fclose(fp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
fas_export_symbol_name(uint32_t name_off)
|
||||
{
|
||||
size_t idx = 0;
|
||||
char *ptr;
|
||||
char name[256] = { 0 };
|
||||
|
||||
if (name_off == 0)
|
||||
{
|
||||
return (0); /* anonymous symbol */
|
||||
}
|
||||
|
||||
if (name_off & (1<<31)) /* if in fas strtab */
|
||||
{
|
||||
ptr = fas_strtab + (name_off & ~(1<<31)); /* XXX */
|
||||
}
|
||||
else /* otherwhise it's in psrc */
|
||||
{
|
||||
pstr2cstr(name, fas_psrc + name_off);
|
||||
ptr = name;
|
||||
}
|
||||
|
||||
if (elf_add_str(ptr, strlen(ptr) + 1, &idx) != 0)
|
||||
{
|
||||
/* error occured */
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (idx);
|
||||
}
|
||||
|
||||
void
|
||||
fas_export_symbols(void)
|
||||
{
|
||||
size_t idx;
|
||||
char *name_ptr;
|
||||
size_t name_idx;
|
||||
|
||||
/* export file name symbol */
|
||||
name_ptr = fas_strtab + fas_hdr.ifnm_off;
|
||||
elf_add_str(name_ptr, strlen(name_ptr) + 1, &name_idx);
|
||||
elf_add_symbol(name_idx, 0, 0, ELF32_ST_INFO(STB_LOCAL, STT_FILE),
|
||||
SHN_ABS);
|
||||
|
||||
/* export other symbol */
|
||||
for (idx = 0; idx < fas_sym_cnt; idx++)
|
||||
{
|
||||
if ((fas_symtab[idx].flags & FAS_SYM_DEF) == 0 ||
|
||||
fas_symtab[idx].flags & FAS_SYM_ASM_TIME)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
name_idx = fas_export_symbol_name(fas_symtab[idx].name_off);
|
||||
|
||||
elf_add_symbol(name_idx, fas_symtab[idx].value, 0,
|
||||
ELF32_ST_INFO(STB_LOCAL, STT_OBJECT), SHN_ABS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fas_cleanup(void)
|
||||
{
|
||||
free(fas_psrc);
|
||||
fas_psrc = NULL;
|
||||
free(fas_symtab);
|
||||
fas_symtab = NULL;
|
||||
free(fas_strtab);
|
||||
fas_strtab = NULL;
|
||||
}
|
37
bin/fas2sym/fas2sym.h
Normal file
37
bin/fas2sym/fas2sym.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef FAS2SYM_H
|
||||
# define FAS2SYM_H 1
|
||||
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <stdarg.h>
|
||||
|
||||
struct buffer {
|
||||
size_t cap;
|
||||
size_t cnt;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
/* buffer.c */
|
||||
int buffer_put(struct buffer *buff, const uint8_t *data,
|
||||
size_t size, size_t *index);
|
||||
void buffer_cleanup(struct buffer *buff);
|
||||
|
||||
/* fas.c */
|
||||
int fas_load_file(const char *file);
|
||||
void fas_export_symbols(void);
|
||||
void fas_cleanup(void);
|
||||
|
||||
/* elf.c */
|
||||
int elf_init(void);
|
||||
int elf_add_str(const char *str, size_t len, size_t *idx);
|
||||
int elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size,
|
||||
uint8_t info, uint16_t sect);
|
||||
int elf_write(const char *file);
|
||||
void elf_cleanup(void);
|
||||
|
||||
/* main.c */
|
||||
void msg_err(const char *fmt, ...);
|
||||
void msg_errx(const char *fmt, ...);
|
||||
void msg_verbose(int level, const char *fmt, ...);
|
||||
|
||||
#endif /* !FAS2SYM_H */
|
152
bin/fas2sym/main.c
Normal file
152
bin/fas2sym/main.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include "fas2sym.h"
|
||||
|
||||
static const char *prg_name;
|
||||
static const char *outfile = "out.sym";
|
||||
static int verbose = 0;
|
||||
|
||||
static void
|
||||
msg_err_common(const char *fmt, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "%s: ", prg_name);
|
||||
if (fmt)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
msg_errx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
msg_err_common(fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
msg_err(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
msg_err_common(fmt, ap);
|
||||
if (fmt)
|
||||
{
|
||||
fprintf(stderr, ": ");
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", strerror(errno));
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
msg_verbose(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (level <= verbose)
|
||||
{
|
||||
vprintf(fmt, ap);
|
||||
printf("\n");
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(int retval)
|
||||
{
|
||||
if (retval == EXIT_FAILURE)
|
||||
{
|
||||
fprintf(stderr, "Try '%s -h' for more information.\n",
|
||||
prg_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Usage: %s [-o OUTPUT] file\n", prg_name);
|
||||
}
|
||||
|
||||
exit(retval);
|
||||
}
|
||||
|
||||
static void
|
||||
version(void)
|
||||
{
|
||||
printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int status;
|
||||
|
||||
prg_name = basename(argv[0]);
|
||||
|
||||
while ((c = getopt(argc, argv, "hvVo:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
usage(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'V':
|
||||
version();
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
usage(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fas_load_file(argv[optind]) != 0)
|
||||
{
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
status = EXIT_FAILURE;
|
||||
|
||||
if (elf_init() != 0)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fas_export_symbols();
|
||||
|
||||
if (elf_write(outfile) != 0)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = EXIT_SUCCESS;
|
||||
cleanup:
|
||||
elf_cleanup();
|
||||
fas_cleanup();
|
||||
|
||||
return (status);
|
||||
}
|
338
bin/fasdump/main.c
Normal file
338
bin/fasdump/main.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <fas.h>
|
||||
|
||||
struct buff {
|
||||
size_t size;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
static char *prg_name = "fasdump";
|
||||
static struct fas_header hdr;
|
||||
static struct buff strtab = { 0, NULL };
|
||||
static struct buff symtab = { 0, NULL };
|
||||
static struct buff psrc = { 0, NULL };
|
||||
static struct buff asmdmp = { 0, NULL };
|
||||
static struct buff sectab = { 0, NULL };
|
||||
static struct buff symref = { 0, NULL };
|
||||
|
||||
static void
|
||||
version(void)
|
||||
{
|
||||
printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(int retval)
|
||||
{
|
||||
if (retval == EXIT_FAILURE)
|
||||
{
|
||||
fprintf(stderr, "Try '%s -h' for more informations.", prg_name);
|
||||
}
|
||||
|
||||
exit(retval);
|
||||
}
|
||||
|
||||
static int
|
||||
readall(uint8_t *dest, size_t size, FILE *fp)
|
||||
{
|
||||
size_t total;
|
||||
size_t byte_read;
|
||||
|
||||
total = 0;
|
||||
do
|
||||
{
|
||||
byte_read = fread(dest + total, 1, size - total, fp);
|
||||
if (byte_read == 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
total += byte_read;
|
||||
}
|
||||
while (total < size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
load_table(struct buff *dst, size_t off, size_t len, FILE *fp)
|
||||
{
|
||||
dst->size = len;
|
||||
if (len == 0)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
dst->data = (uint8_t *)malloc(len);
|
||||
if (dst->data == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fseek(fp, off, SEEK_SET) != 0)
|
||||
{
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (readall(dst->data, len, fp) != 0)
|
||||
{
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
clean_up:
|
||||
free(dst->data);
|
||||
dst->size = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
read_header(FILE *fp)
|
||||
{
|
||||
if (readall((uint8_t *)&hdr, sizeof(struct fas_header), fp) != 0)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (hdr.magic != FAS_MAGIC)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
strtab_get(size_t off)
|
||||
{
|
||||
if (off > strtab.size)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (strtab.data + off);
|
||||
}
|
||||
|
||||
static void
|
||||
print_header(void)
|
||||
{
|
||||
printf("FAS Header:\n");
|
||||
printf(" Magic: %X\n", hdr.magic);
|
||||
printf(" Fasm version: %d.%d\n", hdr.ver_major,
|
||||
hdr.ver_minor);
|
||||
printf(" Length: %hu\n", hdr.length);
|
||||
printf(" Input file: %s\n", strtab_get(hdr.ifnm_off));
|
||||
printf(" Output file: %s\n", strtab_get(hdr.ofnm_off));
|
||||
printf(" String table offset: 0x%08X\n", hdr.strtab_off);
|
||||
printf(" String table length: %u\n", hdr.strtab_len);
|
||||
printf(" Symbol table offset: 0x%08X\n", hdr.symtab_off);
|
||||
printf(" Symbol table length: %u\n", hdr.symtab_len);
|
||||
printf(" ASM dump offset: 0x%08X\n", hdr.asmdmp_off);
|
||||
printf(" ASM dump length: %d\n", hdr.asmdmp_len);
|
||||
printf(" Section table offset: 0x%08X\n", hdr.sectab_off);
|
||||
printf(" Section table length: %d\n", hdr.sectab_len);
|
||||
printf(" Symref table offset: 0x%08X\n", hdr.symref_off);
|
||||
printf(" Symref table length: %d\n", hdr.symref_len);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_sections(void)
|
||||
{
|
||||
size_t seccnt;
|
||||
size_t idx;
|
||||
uint32_t *sec;
|
||||
|
||||
seccnt = sectab.size / sizeof(uint32_t);
|
||||
sec = (uint32_t *)sectab.data;
|
||||
printf("Section names:\n");
|
||||
for (idx = 0; idx < seccnt; idx++)
|
||||
{
|
||||
printf(" %s\n", strtab_get(sec[idx]));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pstr2cstr(char *dst, const char *src)
|
||||
{
|
||||
size_t plen;
|
||||
|
||||
plen = *src++;
|
||||
|
||||
while (plen > 0)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
plen--;
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
print_sym_name(uint32_t off)
|
||||
{
|
||||
char name_str[255] = {0};
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (off & (1<<31))
|
||||
{
|
||||
strncpy(name_str, strtab_get(off & ~(1<<31)), 255);
|
||||
name_str[254] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
pstr2cstr(name_str, psrc.data + off);
|
||||
}
|
||||
|
||||
printf("%s", name_str);
|
||||
}
|
||||
|
||||
static void
|
||||
print_sym_section(uint8_t type, uint32_t rel)
|
||||
{
|
||||
if (type == FAS_ABS)
|
||||
{
|
||||
printf("ABS ");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rel & (1<<31))
|
||||
{
|
||||
printf("UND ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%-3" PRIu32 " %-2" PRIu8 " ", rel, type);
|
||||
}
|
||||
}
|
||||
/*
|
||||
static const char *
|
||||
get_symbol_type(uint8_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FAS_ABS:
|
||||
return ("ABS");
|
||||
case FAS_REL_32:
|
||||
return ("REL_32");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ("???");
|
||||
}
|
||||
*/
|
||||
static void
|
||||
print_symbols(void)
|
||||
{
|
||||
size_t symcnt;
|
||||
size_t idx;
|
||||
struct fas_symbol *sym;
|
||||
|
||||
printf("Symbol table:\n");
|
||||
symcnt = symtab.size / sizeof(struct fas_symbol);
|
||||
sym = (struct fas_symbol *)symtab.data;
|
||||
|
||||
printf(" Num: Value Size Ndx Name\n");
|
||||
|
||||
for (idx = 0; idx < symcnt; idx++)
|
||||
{
|
||||
printf("%6d: ", idx);
|
||||
printf("0x%016" PRIx64 " ", sym[idx].value);
|
||||
printf("%-4" PRIu8 " ", sym[idx].size);
|
||||
//printf("%s ", get_symbol_type(sym[idx].type));
|
||||
print_sym_section(sym[idx].type, sym[idx].reloc);
|
||||
print_sym_name(sym[idx].name_off);
|
||||
printf("\n");
|
||||
/*
|
||||
printf("\t %04" PRIx16 " : ", sym[idx].flags);
|
||||
if (sym[idx].flags & FAS_SYM_DEF) printf("DEF ");
|
||||
if (sym[idx].flags & FAS_SYM_ASM_TIME) printf("ASM_TIME ");
|
||||
if (sym[idx].flags & FAS_SYM_NOT_FWD_REF) printf("NOT_FWD ");
|
||||
if (sym[idx].flags & FAS_SYM_USED) printf("USED ");
|
||||
if (sym[idx].flags & FAS_SYM_PRD_USED) printf("PRD_USED ");
|
||||
if (sym[idx].flags & FAS_SYM_LPRD_USED) printf("LPRD_USED ");
|
||||
if (sym[idx].flags & FAS_SYM_PRD_DEF) printf("PRD_DEF ");
|
||||
if (sym[idx].flags & FAS_SYM_LPRD_DEF) printf("LPRD_DEF ");
|
||||
if (sym[idx].flags & FAS_SYM_OPT_ADJ) printf("OPT_ADJ ");
|
||||
if (sym[idx].flags & FAS_SYM_TWO_CMPLMNT) printf("TWO_CMPLMNT ");
|
||||
if (sym[idx].flags & FAS_SYM_MARKER) printf("MARKER ");
|
||||
printf("\n");
|
||||
*/
|
||||
/*printf("%X\n", sym[idx].value);*/
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_asm_dump(void)
|
||||
{
|
||||
struct fas_asmdmp *dmp;
|
||||
|
||||
dmp = (struct fas_asmdmp *)asmdmp.data;
|
||||
printf(" 0x%" PRIx32 " 0x%" PRIx64 "\n", dmp->of_off, dmp->addr);
|
||||
}
|
||||
|
||||
static int
|
||||
process_file(char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(fname, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
read_header(fp);
|
||||
load_table(&strtab, hdr.strtab_off, hdr.strtab_len, fp);
|
||||
load_table(&symtab, hdr.symtab_off, hdr.symtab_len, fp);
|
||||
load_table(&psrc, hdr.psrc_off, hdr.psrc_len, fp);
|
||||
load_table(&asmdmp, hdr.asmdmp_off, hdr.asmdmp_len, fp);
|
||||
load_table(§ab, hdr.sectab_off, hdr.sectab_len, fp);
|
||||
|
||||
print_header();
|
||||
print_sections();
|
||||
print_symbols();
|
||||
print_asm_dump();
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
while ((argc > 1) && (argv[1][0] == '-'))
|
||||
{
|
||||
switch (argv[1][1])
|
||||
{
|
||||
case 'h':
|
||||
usage(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'V':
|
||||
version();
|
||||
break;
|
||||
default:
|
||||
usage(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (argc <= 1) usage(EXIT_FAILURE);
|
||||
|
||||
return (process_file(argv[1]));
|
||||
}
|
|
@ -98,7 +98,7 @@ _start:
|
|||
|
||||
jmp .skip_fat
|
||||
|
||||
; fallback to fat12
|
||||
; fallback to fat12
|
||||
; for now fat12 is asumed
|
||||
.fat_fallback:
|
||||
mov si, szMsgFatFallback
|
||||
|
@ -129,7 +129,7 @@ _start:
|
|||
xor bx, bx
|
||||
|
||||
call disk_read_sectors
|
||||
|
||||
|
||||
; load stage 2
|
||||
mov ax, KERNEL_PRELOAD/0x10
|
||||
mov es, ax
|
||||
|
@ -146,7 +146,7 @@ _start:
|
|||
call boot_info_print_mmap
|
||||
|
||||
; video information
|
||||
;call video_setup
|
||||
call video_setup
|
||||
|
||||
; load GDT and enter Protected-Mode
|
||||
lgdt [gdt_ptr]
|
||||
|
|
|
@ -6,7 +6,7 @@ struc VesaInfo
|
|||
.Version dw ?
|
||||
.OEMNamePtr dd ?
|
||||
.Capabilities dd ?
|
||||
.VideoModesPtr dw ?
|
||||
.VideoModesPtr dd ?
|
||||
.CountOf64KBlocks dw ?
|
||||
.OEMSoftwareRevision dw ?
|
||||
.OEMVendorNamePtr dd ?
|
||||
|
@ -28,7 +28,7 @@ struc VesaModeInfo
|
|||
.WindowPositioning dd ?
|
||||
.BytesPerScanLine dw ?
|
||||
|
||||
; --
|
||||
; --
|
||||
.Width dw ?
|
||||
.Height dw ?
|
||||
.WidthChar db ?
|
||||
|
@ -72,11 +72,11 @@ video_setup:
|
|||
jne .err
|
||||
cmp [vesa_block_buffer.Signature], 'VESA'
|
||||
jne .err
|
||||
|
||||
push [vesa_block_buffer.OEMProductNamePtr]
|
||||
push [vesa_block_buffer.OEMVendorNamePtr]
|
||||
push [vesa_block_buffer.CountOf64KBlocks]
|
||||
push [vesa_block_buffer.OEMNamePtr]
|
||||
; XXX: fix me
|
||||
push word [vesa_block_buffer.OEMProductNamePtr]
|
||||
push word [vesa_block_buffer.OEMVendorNamePtr]
|
||||
push word [vesa_block_buffer.CountOf64KBlocks]
|
||||
push word [vesa_block_buffer.OEMNamePtr]
|
||||
xor ecx, ecx
|
||||
mov cx, [vesa_block_buffer.Version]
|
||||
push ecx
|
||||
|
@ -84,7 +84,7 @@ video_setup:
|
|||
call bios_log
|
||||
|
||||
mov di, vesa_info_block_buffer
|
||||
mov bx, [vesa_block_buffer.VideoModesPtr]
|
||||
mov ebx, [vesa_block_buffer.VideoModesPtr]
|
||||
mov cx, [bx]
|
||||
cmp cx, 0xFFFF
|
||||
je .err
|
||||
|
@ -110,6 +110,7 @@ vesa_block_buffer VesaInfo
|
|||
vesa_info_block_buffer VesaModeInfo
|
||||
|
||||
szMsgVesaInfo db "Version: %x", CR, LF, "OEM Name: %s", CR, LF, "Total Memory: %d", CR, LF, "Vendor name: %s", CR, LF, "Product name: %s", 0
|
||||
szMsgVesaModeInfo db "%dx%dx%d", CR, LF, 0
|
||||
szMsgDetectVideo db "Fetch video information.", 0
|
||||
szMsgFramebuffer db "Fb: %x", 0
|
||||
szMsgErrorVesa db "Failed to detect VBE mode", 0
|
||||
|
|
192
include/elf.h
192
include/elf.h
|
@ -1,23 +1,189 @@
|
|||
#ifndef ELF_H
|
||||
# define ELF_H 1
|
||||
|
||||
/* spec: https://refspecs.linuxfoundation.org/elf/elf.pdf
|
||||
* elf(5)
|
||||
*/
|
||||
# include <stdint.h>
|
||||
|
||||
# define ELF_MAG0 0x7F
|
||||
# define ELF_MAG1 0x45
|
||||
# define ELF_MAG2 0x4C
|
||||
# define ELF_MAG3 0x46
|
||||
# define ELFMAG0 0x7F
|
||||
# define ELFMAG1 0x45
|
||||
# define ELFMAG2 0x4C
|
||||
# define ELFMAG3 0x46
|
||||
|
||||
# define EI_NIDENT 16
|
||||
# define EI_MAG0 0
|
||||
# define EI_MAG1 1
|
||||
# define EI_MAG2 2
|
||||
# define EI_MAG3 3
|
||||
# define EI_CLASS 4
|
||||
# define EI_DATA 5
|
||||
# define EI_VERSION 6
|
||||
# define EI_PAD 7
|
||||
# define EI_NIDENT 16
|
||||
|
||||
struct elf_header
|
||||
{
|
||||
uint8_t e_ident[EI_NIDENT];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
};
|
||||
# define ET_NONE 0
|
||||
# define ET_REL 1
|
||||
# define ET_EXEC 2
|
||||
# define ET_DYN 3
|
||||
# define ET_CORE 4
|
||||
# define ET_LOPROC 0xFF00
|
||||
# define ET_HIPROC 0xFFFF
|
||||
|
||||
/* TODO */
|
||||
# define EM_NONE 0
|
||||
# define EM_M32 1
|
||||
# define EM_SPARC 2
|
||||
# define EM_386 3
|
||||
# define EM_68K 4
|
||||
# define EM_88K 5
|
||||
# define EM_860 7
|
||||
# define EM_MIPS 8
|
||||
# define EM_MIPS_RS4_BE 10
|
||||
|
||||
# define EV_NONE 0
|
||||
# define EV_CURRENT 1
|
||||
|
||||
# define ELFCLASSNONE 0
|
||||
# define ELFCLASS32 1
|
||||
# define ELFCLASS64 2
|
||||
|
||||
# define ELFDATANONE 0
|
||||
# define ELFDATA2LSB 1
|
||||
# define ELFDATA2MSB 2
|
||||
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
# define SHN_UNDEF 0
|
||||
# define SHN_LORESERVE 0xFF00
|
||||
# define SHN_LOPROC 0xFF00
|
||||
# define SHN_HIPROC 0xFF1F
|
||||
# define SHN_ABS 0xFFF1
|
||||
# define SHN_COMMON 0xFFF2
|
||||
# define SHN_HIRESERVE 0xFFFF
|
||||
|
||||
# define SHT_NULL 0
|
||||
# define SHT_PROGBITS 1
|
||||
# define SHT_SYMTAB 2
|
||||
# define SHT_STRTAB 3
|
||||
# define SHT_RELA 4
|
||||
# define SHT_HASH 5
|
||||
# define SHT_DYNAMIC 6
|
||||
# define SHT_NOTE 7
|
||||
# define SHT_NOBITS 8
|
||||
# define SHT_REL 9
|
||||
# define SHT_SHLIB 10
|
||||
# define SHT_DYNSYM 11
|
||||
# define SHT_LOPROC 0x70000000
|
||||
# define SHT_HIPROC 0x7FFFFFFF
|
||||
# define SHT_LOUSER 0x80000000
|
||||
# define SHT_HIUSER 0xFFFFFFFF
|
||||
|
||||
# define SHF_WRITE 0x1
|
||||
# define SHF_ALLOC 0x2
|
||||
# define SHF_EXECINSTR 0x4
|
||||
# define SHF_MASKPROC 0xF0000000
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
# define STN_UNDER 0
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
uint8_t st_info;
|
||||
uint8_t st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
# define ELF32_ST_BIND(x) ((x)>>4)
|
||||
# define ELF32_ST_TYPE(x) ((x)&0xf)
|
||||
# define ELF32_ST_INFO(b, t) (((b)<<4)+((t)&0xf))
|
||||
|
||||
# define STB_LOCAL 0
|
||||
# define STB_GLOBAL 1
|
||||
# define STB_WEAK 2
|
||||
# define STB_LOPROC 13
|
||||
# define STB_HIPROC 15
|
||||
|
||||
# define STT_NOTYPE 0
|
||||
# define STT_OBJECT 1
|
||||
# define STT_FUNC 2
|
||||
# define STT_SECTION 3
|
||||
# define STT_FILE 4
|
||||
# define STT_LOPROC 13
|
||||
# define STT_HIPROC 15
|
||||
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
# define ELF32_R_SYM(x) ((x)>>8)
|
||||
# define ELF32_R_TYPE(x) ((uint8_t)(i));
|
||||
# define ELF32_R_INFO(s,t) (((s)<<8)+(uint8_t)(t))
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
# define PT_NULL 0
|
||||
# define PT_LOAD 1
|
||||
# define PT_DYNAMIC 2
|
||||
# define PT_INTERP 3
|
||||
# define PT_NOTE 4
|
||||
# define PT_SHLIB 5
|
||||
# define PT_PHDR 6
|
||||
# define PT_LOPROC 0x70000000
|
||||
# define PT_HIPROC 0x7FFFFFFF
|
||||
|
||||
# define PF_X 0x1
|
||||
# define PF_W 0x2
|
||||
# define PF_R 0x4
|
||||
# define PF_MASKPROC 0xF0000000
|
||||
|
||||
#endif /* !ELF_H */
|
||||
|
|
140
include/fas.h
Normal file
140
include/fas.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
#ifndef FAS_H
|
||||
# define FAS_H 1
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
# define FAS_MAGIC 0x1A736166
|
||||
|
||||
typedef struct fas_header
|
||||
{
|
||||
uint32_t magic;
|
||||
uint8_t ver_major;
|
||||
uint8_t ver_minor;
|
||||
uint16_t length;
|
||||
uint32_t ifnm_off;
|
||||
uint32_t ofnm_off;
|
||||
uint32_t strtab_off;
|
||||
uint32_t strtab_len;
|
||||
uint32_t symtab_off;
|
||||
uint32_t symtab_len;
|
||||
uint32_t psrc_off;
|
||||
uint32_t psrc_len;
|
||||
uint32_t asmdmp_off;
|
||||
uint32_t asmdmp_len;
|
||||
uint32_t sectab_off;
|
||||
uint32_t sectab_len;
|
||||
uint32_t symref_off;
|
||||
uint32_t symref_len;
|
||||
} FAS_Hdr;
|
||||
|
||||
# define FAS_SYM_DEF 0x001
|
||||
# define FAS_SYM_ASM_TIME 0x002
|
||||
# define FAS_SYM_NOT_FWD_REF 0x004
|
||||
# define FAS_SYM_USED 0x008
|
||||
# define FAS_SYM_PRD_USED 0x010
|
||||
# define FAS_SYM_LPRD_USED 0x020
|
||||
# define FAS_SYM_PRD_DEF 0x040
|
||||
# define FAS_SYM_LPRD_DEF 0x080
|
||||
# define FAS_SYM_OPT_ADJ 0x100
|
||||
# define FAS_SYM_TWO_CMPLMNT 0x200
|
||||
# define FAS_SYM_MARKER 0x400
|
||||
|
||||
enum fas_symbol_type
|
||||
{
|
||||
FAS_ABS,
|
||||
FAS_REL_SEG,
|
||||
FAS_REL_32,
|
||||
FAS_REL_R_32,
|
||||
FAS_REL_64,
|
||||
FAS_GOT_32,
|
||||
FAS_PLT_32,
|
||||
FAS_PLT_R_32
|
||||
};
|
||||
|
||||
|
||||
typedef struct fas_symbol
|
||||
{
|
||||
uint64_t value;
|
||||
uint16_t flags;
|
||||
uint8_t size;
|
||||
uint8_t type;
|
||||
uint32_t ext_SIB;
|
||||
uint16_t pass_ldef;
|
||||
uint16_t pass_lused;
|
||||
uint32_t reloc;
|
||||
uint32_t name_off;
|
||||
uint32_t psrc_line_off;
|
||||
} FAS_Sym;
|
||||
|
||||
struct fas_psrc_line
|
||||
{
|
||||
uint32_t from;
|
||||
uint32_t lineno;
|
||||
uint32_t src_off;
|
||||
uint32_t macro_off;
|
||||
uint8_t tokens[];
|
||||
};
|
||||
|
||||
enum fas_code
|
||||
{
|
||||
FAS_CODE_16 = 16,
|
||||
FAS_CODE_32 = 32,
|
||||
FAS_CODE_64 = 64
|
||||
};
|
||||
|
||||
struct fas_asmdmp
|
||||
{
|
||||
uint32_t of_off;
|
||||
uint32_t psrc_line_off;
|
||||
uint64_t addr;
|
||||
uint32_t ext_SIB;
|
||||
uint32_t reloc;
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint8_t virt;
|
||||
uint8_t high;
|
||||
};
|
||||
|
||||
enum fas_register
|
||||
{
|
||||
FAS_REG_BX = 0x23,
|
||||
FAS_REG_BP = 0x25,
|
||||
FAS_REG_SI = 0x26,
|
||||
FAS_REG_DI = 0x27,
|
||||
FAS_REG_EAX = 0x40,
|
||||
FAS_REG_ECX = 0x41,
|
||||
FAS_REG_EDX = 0x42,
|
||||
FAS_REG_EBX = 0x43,
|
||||
FAS_REG_ESP = 0x44,
|
||||
FAS_REG_EBP = 0x45,
|
||||
FAS_REG_ESI = 0x46,
|
||||
FAS_REG_EDI = 0x47,
|
||||
FAS_REG_R8D = 0x48,
|
||||
FAS_REG_R9D = 0x49,
|
||||
FAS_REG_R10D = 0x4A,
|
||||
FAS_REG_R11D = 0x4B,
|
||||
FAS_REG_R12D = 0x4C,
|
||||
FAS_REG_R13D = 0x4D,
|
||||
FAS_REG_R14D = 0x4E,
|
||||
FAS_REG_R15D = 0x4F,
|
||||
FAS_REG_RAX = 0x80,
|
||||
FAS_REG_RCX = 0x81,
|
||||
FAS_REG_RDX = 0x82,
|
||||
FAS_REG_RBX = 0x83,
|
||||
FAS_REG_RSP = 0x84,
|
||||
FAS_REG_RBP = 0x85,
|
||||
FAS_REG_RSI = 0x86,
|
||||
FAS_REG_RDI = 0x87,
|
||||
FAS_REG_R8 = 0x88,
|
||||
FAS_REG_R9 = 0x89,
|
||||
FAS_REG_R10 = 0x8A,
|
||||
FAS_REG_R11 = 0x8B,
|
||||
FAS_REG_R12 = 0x8C,
|
||||
FAS_REG_R13 = 0x8D,
|
||||
FAS_REG_R14 = 0x8E,
|
||||
FAS_REG_R15 = 0x8F,
|
||||
FAS_REG_EIP = 0x94,
|
||||
FAS_REG_RIP = 0x98,
|
||||
};
|
||||
|
||||
#endif /* !FAS_H */
|
|
@ -1,4 +1,9 @@
|
|||
TARGET = ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) elf2coff$(EXEXT) ar$(EXEXT) ranlib$(EXEXT)
|
||||
TARGET = ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) \
|
||||
elf2coff$(EXEXT) ar$(EXEXT) ranlib$(EXEXT) \
|
||||
fasdump$(EXEXT) fas2sym$(EXEXT)
|
||||
|
||||
FAS2SYM_SRCS = main.c fas.c elf.c buffer.c
|
||||
FAS2SYM_OBJS = $(addprefix ../bin/fas2sym/, $(FAS2SYM_SRCS:.c=.o))
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET)
|
||||
|
@ -21,6 +26,12 @@ ranlib$(EXEXT): ../bin/ranlib/main.c ../bin/ar/archive.c
|
|||
ar$(EXEXT): ../bin/ar/main.c
|
||||
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
fasdump$(EXEXT): ../bin/fasdump/main.c
|
||||
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
fas2sym$(EXEXT): $(FAS2SYM_OBJS)
|
||||
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
.PHONY: install
|
||||
install: $(TARGET)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue