mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-04-12 18:40:23 +08:00
Initial support for ELF64
This commit is contained in:
parent
8d7316a3ff
commit
26d3de3217
@ -52,7 +52,8 @@ X = @EXEEXT@
|
||||
|
||||
NASM = nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) assemble.$(O) \
|
||||
labels.$(O) parser.$(O) outform.$(O) output/outbin.$(O) \
|
||||
output/outaout.$(O) output/outcoff.$(O) output/outelf.$(O) \
|
||||
output/outaout.$(O) output/outcoff.$(O) \
|
||||
output/outelf32.$(O) output/outelf64.$(O) \
|
||||
output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
|
||||
output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
|
||||
preproc.$(O) listing.$(O) eval.$(O)
|
||||
@ -224,7 +225,9 @@ output/outcoff.$(O): output/outcoff.c regs.h outform.h version.h nasmlib.h \
|
||||
nasm.h
|
||||
output/outdbg.$(O): output/outdbg.c regs.h outform.h version.h nasmlib.h \
|
||||
nasm.h
|
||||
output/outelf.$(O): output/outelf.c regs.h outform.h version.h nasmlib.h \
|
||||
output/outelf32.$(O): output/outelf32.c regs.h outform.h version.h nasmlib.h \
|
||||
nasm.h
|
||||
output/outelf64.$(O): output/outelf64.c regs.h outform.h version.h nasmlib.h \
|
||||
nasm.h
|
||||
output/outieee.$(O): output/outieee.c regs.h outform.h version.h nasmlib.h \
|
||||
nasm.h
|
||||
|
12
nasmlib.c
12
nasmlib.c
@ -306,6 +306,18 @@ void fwriteint32_t(int32_t data, FILE * fp)
|
||||
fputc((int)((data >> 24) & 255), fp);
|
||||
}
|
||||
|
||||
void fwriteint64_t(int64_t data, FILE * fp)
|
||||
{
|
||||
fputc((int)(data & 255), fp);
|
||||
fputc((int)((data >> 8) & 255), fp);
|
||||
fputc((int)((data >> 16) & 255), fp);
|
||||
fputc((int)((data >> 24) & 255), fp);
|
||||
fputc((int)((data >> 32) & 255), fp);
|
||||
fputc((int)((data >> 40) & 255), fp);
|
||||
fputc((int)((data >> 48) & 255), fp);
|
||||
fputc((int)((data >> 56) & 255), fp);
|
||||
}
|
||||
|
||||
void standard_extension(char *inname, char *outname, char *extension,
|
||||
efunc error)
|
||||
{
|
||||
|
@ -143,6 +143,7 @@ void standard_extension(char *inname, char *outname, char *extension,
|
||||
*/
|
||||
void fwriteint16_t(int data, FILE * fp);
|
||||
void fwriteint32_t(int32_t data, FILE * fp);
|
||||
void fwriteint64_t(int64_t data, FILE * fp);
|
||||
|
||||
/*
|
||||
* Routines to manage a dynamic random access array of int32_ts which
|
||||
|
37
outform.h
37
outform.h
@ -17,7 +17,7 @@
|
||||
* OF_name -- ensure that output format 'name' is included
|
||||
* OF_NO_name -- remove output format 'name'
|
||||
* OF_DOS -- ensure that 'obj', 'bin' & 'win32' are included.
|
||||
* OF_UNIX -- ensure that 'aout', 'aoutb', 'coff', 'elf' are in.
|
||||
* OF_UNIX -- ensure that 'aout', 'aoutb', 'coff', 'elf32' 'elf64' are in.
|
||||
* OF_OTHERS -- ensure that 'bin', 'as86' & 'rdf' are in.
|
||||
* OF_ALL -- ensure that all formats are included.
|
||||
* note that this doesn't include 'dbg', which is
|
||||
@ -26,7 +26,7 @@
|
||||
*
|
||||
* OF_DEFAULT=of_name -- ensure that 'name' is the default format.
|
||||
*
|
||||
* eg: -DOF_UNIX -DOF_ELF -DOF_DEFAULT=of_elf would be a suitable config
|
||||
* eg: -DOF_UNIX -DOF_ELF32 -DOF_DEFAULT=of_elf32 would be a suitable config
|
||||
* for an average linux system.
|
||||
*
|
||||
* Default config = -DOF_ALL -DOF_DEFAULT=of_bin
|
||||
@ -57,7 +57,7 @@
|
||||
|
||||
/* ====configurable info begins here==== */
|
||||
/* formats configurable:
|
||||
* bin,obj,elf,aout,aoutb,coff,win32,as86,rdf2,macho */
|
||||
* bin,obj,elf32,elf64,aout,aoutb,coff,win32,as86,rdf2,macho */
|
||||
|
||||
/* process options... */
|
||||
|
||||
@ -74,8 +74,11 @@
|
||||
#ifndef OF_OBJ
|
||||
#define OF_OBJ
|
||||
#endif
|
||||
#ifndef OF_ELF
|
||||
#define OF_ELF
|
||||
#ifndef OF_ELF32
|
||||
#define OF_ELF32
|
||||
#endif
|
||||
#ifndef OF_ELF64
|
||||
#define OF_ELF64
|
||||
#endif
|
||||
#ifndef OF_COFF
|
||||
#define OF_COFF
|
||||
@ -132,8 +135,11 @@
|
||||
#ifndef OF_COFF
|
||||
#define OF_COFF
|
||||
#endif
|
||||
#ifndef OF_ELF
|
||||
#define OF_ELF
|
||||
#ifndef OF_ELF32
|
||||
#define OF_ELF32
|
||||
#endif
|
||||
#ifndef OF_ELF64
|
||||
#define OF_ELF64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -162,8 +168,11 @@
|
||||
#ifdef OF_NO_OBJ
|
||||
#undef OF_OBJ
|
||||
#endif
|
||||
#ifdef OF_NO_ELF
|
||||
#undef OF_ELF
|
||||
#ifdef OF_NO_ELF32
|
||||
#undef OF_ELF32
|
||||
#endif
|
||||
#ifdef OF_NO_ELF64
|
||||
#undef OF_ELF64
|
||||
#endif
|
||||
#ifdef OF_NO_AOUT
|
||||
#undef OF_AOUT
|
||||
@ -206,7 +215,8 @@ extern struct ofmt of_bin;
|
||||
extern struct ofmt of_aout;
|
||||
extern struct ofmt of_aoutb;
|
||||
extern struct ofmt of_coff;
|
||||
extern struct ofmt of_elf;
|
||||
extern struct ofmt of_elf32;
|
||||
extern struct ofmt of_elf64;
|
||||
extern struct ofmt of_as86;
|
||||
extern struct ofmt of_obj;
|
||||
extern struct ofmt of_win32;
|
||||
@ -229,8 +239,11 @@ struct ofmt *drivers[] = {
|
||||
#ifdef OF_COFF
|
||||
&of_coff,
|
||||
#endif
|
||||
#ifdef OF_ELF
|
||||
&of_elf,
|
||||
#ifdef OF_ELF32
|
||||
&of_elf32,
|
||||
#endif
|
||||
#ifdef OF_ELF64
|
||||
&of_elf64,
|
||||
#endif
|
||||
#ifdef OF_AS86
|
||||
&of_as86,
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "nasmlib.h"
|
||||
#include "outform.h"
|
||||
|
||||
#ifdef OF_ELF
|
||||
#ifdef OF_ELF32
|
||||
|
||||
/*
|
||||
* Relocation types.
|
||||
@ -106,7 +106,7 @@ static struct Symbol *fwds;
|
||||
|
||||
static char elf_module[FILENAME_MAX];
|
||||
|
||||
extern struct ofmt of_elf;
|
||||
extern struct ofmt of_elf32;
|
||||
|
||||
#define SHN_ABS 0xFFF1
|
||||
#define SHN_COMMON 0xFFF2
|
||||
@ -188,14 +188,14 @@ static int stablen, stabstrlen, stabrellen;
|
||||
|
||||
static struct dfmt df_stabs;
|
||||
|
||||
void stabs_init(struct ofmt *, void *, FILE *, efunc);
|
||||
void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
|
||||
void stabs_deflabel(char *, int32_t, int32_t, int, char *);
|
||||
void stabs_directive(const char *, const char *);
|
||||
void stabs_typevalue(int32_t);
|
||||
void stabs_output(int, void *);
|
||||
void stabs_generate();
|
||||
void stabs_cleanup();
|
||||
void stabs32_init(struct ofmt *, void *, FILE *, efunc);
|
||||
void stabs32_linenum(const char *filename, int32_t linenumber, int32_t);
|
||||
void stabs32_deflabel(char *, int32_t, int32_t, int, char *);
|
||||
void stabs32_directive(const char *, const char *);
|
||||
void stabs32_typevalue(int32_t);
|
||||
void stabs32_output(int, void *);
|
||||
void stabs32_generate();
|
||||
void stabs32_cleanup();
|
||||
|
||||
/* end of stabs debugging stuff */
|
||||
|
||||
@ -230,19 +230,19 @@ static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
|
||||
fwds = NULL;
|
||||
|
||||
elf_gotpc_sect = seg_alloc();
|
||||
ldef("..gotpc", elf_gotpc_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf,
|
||||
ldef("..gotpc", elf_gotpc_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf32,
|
||||
error);
|
||||
elf_gotoff_sect = seg_alloc();
|
||||
ldef("..gotoff", elf_gotoff_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf,
|
||||
ldef("..gotoff", elf_gotoff_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf32,
|
||||
error);
|
||||
elf_got_sect = seg_alloc();
|
||||
ldef("..got", elf_got_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf,
|
||||
ldef("..got", elf_got_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf32,
|
||||
error);
|
||||
elf_plt_sect = seg_alloc();
|
||||
ldef("..plt", elf_plt_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf,
|
||||
ldef("..plt", elf_plt_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf32,
|
||||
error);
|
||||
elf_sym_sect = seg_alloc();
|
||||
ldef("..sym", elf_sym_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf,
|
||||
ldef("..sym", elf_sym_sect + 1, 0L, NULL, FALSE, FALSE, &of_elf32,
|
||||
error);
|
||||
|
||||
def_seg = seg_alloc();
|
||||
@ -272,8 +272,8 @@ static void elf_cleanup(int debuginfo)
|
||||
saa_free(syms);
|
||||
raa_free(bsym);
|
||||
saa_free(strs);
|
||||
if (of_elf.current_dfmt) {
|
||||
of_elf.current_dfmt->cleanup();
|
||||
if (of_elf32.current_dfmt) {
|
||||
of_elf32.current_dfmt->cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,11 +776,11 @@ static void elf_out(int32_t segto, const void *data, uint32_t type,
|
||||
}
|
||||
|
||||
/* again some stabs debugging stuff */
|
||||
if (of_elf.current_dfmt) {
|
||||
if (of_elf32.current_dfmt) {
|
||||
sinfo.offset = s->len;
|
||||
sinfo.section = i;
|
||||
sinfo.name = s->name;
|
||||
of_elf.current_dfmt->debug_output(TY_STABSSYMLIN, &sinfo);
|
||||
of_elf32.current_dfmt->debug_output(TY_STABSSYMLIN, &sinfo);
|
||||
}
|
||||
/* end of debugging stuff */
|
||||
|
||||
@ -931,7 +931,7 @@ static void elf_write(void)
|
||||
* sections `.comment', `.shstrtab', `.symtab' and `.strtab',
|
||||
* then optionally relocation sections for the user sections.
|
||||
*/
|
||||
if (of_elf.current_dfmt == &df_stabs)
|
||||
if (of_elf32.current_dfmt == &df_stabs)
|
||||
nsections = 8;
|
||||
else
|
||||
nsections = 5; /* SHN_UNDEF and the fixed ones */
|
||||
@ -948,7 +948,7 @@ static void elf_write(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (of_elf.current_dfmt == &df_stabs) {
|
||||
if (of_elf32.current_dfmt == &df_stabs) {
|
||||
/* in case the debug information is wanted, just add these three sections... */
|
||||
add_sectname("", ".stab");
|
||||
add_sectname("", ".stabstr");
|
||||
@ -1031,12 +1031,12 @@ static void elf_write(void)
|
||||
elf_section_header(p - shstrtab, 9, 0, sects[i]->rel, TRUE,
|
||||
sects[i]->rellen, nsects + 3, i + 1, 4, 8);
|
||||
}
|
||||
if (of_elf.current_dfmt == &df_stabs) {
|
||||
if (of_elf32.current_dfmt == &df_stabs) {
|
||||
/* for debugging information, create the last three sections
|
||||
which are the .stab , .stabstr and .rel.stab sections respectively */
|
||||
|
||||
/* this function call creates the stab sections in memory */
|
||||
stabs_generate();
|
||||
stabs32_generate();
|
||||
|
||||
if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
|
||||
p += strlen(p) + 1;
|
||||
@ -1230,10 +1230,10 @@ static int32_t elf_segbase(int32_t segment)
|
||||
|
||||
static int elf_directive(char *directive, char *value, int pass)
|
||||
{
|
||||
(void)directive;
|
||||
(void)value;
|
||||
(void)pass;
|
||||
return 0;
|
||||
(void)directive;
|
||||
(void)value;
|
||||
(void)pass;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void elf_filename(char *inname, char *outname, efunc error)
|
||||
@ -1259,22 +1259,22 @@ static int elf_set_info(enum geninfo type, char **val)
|
||||
static struct dfmt df_stabs = {
|
||||
"ELF32 (i386) stabs debug format for Linux",
|
||||
"stabs",
|
||||
stabs_init,
|
||||
stabs_linenum,
|
||||
stabs_deflabel,
|
||||
stabs_directive,
|
||||
stabs_typevalue,
|
||||
stabs_output,
|
||||
stabs_cleanup
|
||||
stabs32_init,
|
||||
stabs32_linenum,
|
||||
stabs32_deflabel,
|
||||
stabs32_directive,
|
||||
stabs32_typevalue,
|
||||
stabs32_output,
|
||||
stabs32_cleanup
|
||||
};
|
||||
|
||||
struct dfmt *elf_debugs_arr[2] = { &df_stabs, NULL };
|
||||
struct dfmt *elf32_debugs_arr[2] = { &df_stabs, NULL };
|
||||
|
||||
struct ofmt of_elf = {
|
||||
struct ofmt of_elf32 = {
|
||||
"ELF32 (i386) object files (e.g. Linux)",
|
||||
"elf",
|
||||
NULL,
|
||||
elf_debugs_arr,
|
||||
elf32_debugs_arr,
|
||||
&null_debug_form,
|
||||
elf_stdmac,
|
||||
elf_init,
|
||||
@ -1290,7 +1290,7 @@ struct ofmt of_elf = {
|
||||
|
||||
/* again, the stabs debugging stuff (code) */
|
||||
|
||||
void stabs_init(struct ofmt *of, void *id, FILE * fp, efunc error)
|
||||
void stabs32_init(struct ofmt *of, void *id, FILE * fp, efunc error)
|
||||
{
|
||||
(void)of;
|
||||
(void)id;
|
||||
@ -1298,10 +1298,9 @@ void stabs_init(struct ofmt *of, void *id, FILE * fp, efunc error)
|
||||
(void)error;
|
||||
}
|
||||
|
||||
void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
|
||||
void stabs32_linenum(const char *filename, int32_t linenumber, int32_t segto)
|
||||
{
|
||||
(void)segto;
|
||||
|
||||
if (!stabs_filename) {
|
||||
stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
|
||||
strcpy(stabs_filename, filename);
|
||||
@ -1321,28 +1320,28 @@ void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
|
||||
currentline = linenumber;
|
||||
}
|
||||
|
||||
void stabs_deflabel(char *name, int32_t segment, int32_t offset, int is_global,
|
||||
void stabs32_deflabel(char *name, int32_t segment, int32_t offset, int is_global,
|
||||
char *special)
|
||||
{
|
||||
(void)name;
|
||||
(void)segment;
|
||||
(void)offset;
|
||||
(void)is_global;
|
||||
(void)special;
|
||||
(void)name;
|
||||
(void)segment;
|
||||
(void)offset;
|
||||
(void)is_global;
|
||||
(void)special;
|
||||
}
|
||||
|
||||
void stabs_directive(const char *directive, const char *params)
|
||||
void stabs32_directive(const char *directive, const char *params)
|
||||
{
|
||||
(void)directive;
|
||||
(void)params;
|
||||
(void)directive;
|
||||
(void)params;
|
||||
}
|
||||
|
||||
void stabs_typevalue(int32_t type)
|
||||
void stabs32_typevalue(int32_t type)
|
||||
{
|
||||
(void)type;
|
||||
(void)type;
|
||||
}
|
||||
|
||||
void stabs_output(int type, void *param)
|
||||
void stabs32_output(int type, void *param)
|
||||
{
|
||||
struct symlininfo *s;
|
||||
struct linelist *el;
|
||||
@ -1382,7 +1381,7 @@ void stabs_output(int type, void *param)
|
||||
|
||||
/* for creating the .stab , .stabstr and .rel.stab sections in memory */
|
||||
|
||||
void stabs_generate(void)
|
||||
void stabs32_generate(void)
|
||||
{
|
||||
int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
|
||||
uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
|
||||
@ -1510,7 +1509,7 @@ void stabs_generate(void)
|
||||
stabstrbuf = ssbuf;
|
||||
}
|
||||
|
||||
void stabs_cleanup(void)
|
||||
void stabs32_cleanup()
|
||||
{
|
||||
struct linelist *ptr, *del;
|
||||
if (!stabslines)
|
1552
output/outelf64.c
Normal file
1552
output/outelf64.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user