outelf.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:31k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* outelf.c output routines for the Netwide Assembler to produce
  2.  * ELF32 (i386 of course) object file format
  3.  *
  4.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  5.  * Julian Hall. All rights reserved. The software is
  6.  * redistributable under the licence given in the file "Licence"
  7.  * distributed in the NASM archive.
  8.  */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "nasm.h"
  14. #include "nasmlib.h"
  15. #include "outform.h"
  16. #ifdef OF_ELF
  17. /*
  18.  * Relocation types.
  19.  */
  20. #define R_386_32 1        /* ordinary absolute relocation */
  21. #define R_386_PC32 2        /* PC-relative relocation */
  22. #define R_386_GOT32 3        /* an offset into GOT */
  23. #define R_386_PLT32 4        /* a PC-relative offset into PLT */
  24. #define R_386_GOTOFF 9        /* an offset from GOT base */
  25. #define R_386_GOTPC 10        /* a PC-relative offset _to_ GOT */
  26. struct Reloc {
  27.     struct Reloc *next;
  28.     long address;        /* relative to _start_ of section */
  29.     long symbol;        /* ELF symbol info thingy */
  30.     int type;        /* type of relocation */
  31. };
  32. struct Symbol {
  33.     long strpos;        /* string table position of name */
  34.     long section;        /* section ID of the symbol */
  35.     int type;        /* symbol type */
  36.     long value;        /* address, or COMMON variable align */
  37.     long size;        /* size of symbol */
  38.     long globnum;        /* symbol table offset if global */
  39.     struct Symbol *next;        /* list of globals in each section */
  40.     struct Symbol *nextfwd;        /* list of unresolved-size symbols */
  41.     char *name;        /* used temporarily if in above list */
  42. };
  43. #define SHT_PROGBITS 1
  44. #define SHT_NOBITS 8
  45. #define SHF_WRITE 1
  46. #define SHF_ALLOC 2
  47. #define SHF_EXECINSTR 4
  48. struct Section {
  49.     struct SAA *data;
  50.     unsigned long len, size, nrelocs;
  51.     long index;
  52.     int type;        /* SHT_PROGBITS or SHT_NOBITS */
  53.     int align;        /* alignment: power of two */
  54.     unsigned long flags;        /* section flags */
  55.     char *name;
  56.     struct SAA *rel;
  57.     long rellen;
  58.     struct Reloc *head, **tail;
  59.     struct Symbol *gsyms;        /* global symbols in section */
  60. };
  61. #define SECT_DELTA 32
  62. static struct Section **sects;
  63. static int nsects, sectlen;
  64. #define SHSTR_DELTA 256
  65. static char *shstrtab;
  66. static int shstrtablen, shstrtabsize;
  67. static struct SAA *syms;
  68. static unsigned long nlocals, nglobs;
  69. static long def_seg;
  70. static struct RAA *bsym;
  71. static struct SAA *strs;
  72. static unsigned long strslen;
  73. static FILE *elffp;
  74. static efunc error;
  75. static evalfunc evaluate;
  76. static struct Symbol *fwds;
  77. static char elf_module[FILENAME_MAX];
  78. extern struct ofmt of_elf;
  79. #define SHN_ABS 0xFFF1
  80. #define SHN_COMMON 0xFFF2
  81. #define SHN_UNDEF 0
  82. #define SYM_SECTION 0x04
  83. #define SYM_GLOBAL 0x10
  84. #define SYM_DATA 0x01
  85. #define SYM_FUNCTION 0x02
  86. #define GLOBAL_TEMP_BASE 6        /* bigger than any constant sym id */
  87. #define SEG_ALIGN 16        /* alignment of sections in file */
  88. #define SEG_ALIGN_1 (SEG_ALIGN-1)
  89. static const char align_str[SEG_ALIGN] = ""; /* ANSI will pad this with 0s */
  90. #define ELF_MAX_SECTIONS 16        /* really 10, but let's play safe */
  91. static struct ELF_SECTDATA {
  92.     void *data;
  93.     long len;
  94.     int is_saa;
  95. } *elf_sects;
  96. static int elf_nsect;
  97. static long elf_foffs;
  98. static void elf_write(void);
  99. static void elf_sect_write(struct Section *, unsigned char *, unsigned long);
  100. static void elf_section_header (int, int, int, void *, int, long,
  101. int, int, int, int);
  102. static void elf_write_sections (void);
  103. static struct SAA *elf_build_symtab (long *, long *);
  104. static struct SAA *elf_build_reltab (long *, struct Reloc *);
  105. static void add_sectname (char *, char *);
  106. /*
  107.  * Special section numbers which are used to define ELF special
  108.  * symbols, which can be used with WRT to provide PIC relocation
  109.  * types.
  110.  */
  111. static long elf_gotpc_sect, elf_gotoff_sect;
  112. static long elf_got_sect, elf_plt_sect;
  113. static long elf_sym_sect;
  114. static void elf_init(FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval) 
  115. {
  116.     elffp = fp;
  117.     error = errfunc;
  118.     evaluate = eval;
  119.     (void) ldef;        /* placate optimisers */
  120.     sects = NULL;
  121.     nsects = sectlen = 0;
  122.     syms = saa_init((long)sizeof(struct Symbol));
  123.     nlocals = nglobs = 0;
  124.     bsym = raa_init();
  125.     strs = saa_init(1L);
  126.     saa_wbytes (strs, "", 1L);
  127.     saa_wbytes (strs, elf_module, (long)(strlen(elf_module)+1));
  128.     strslen = 2+strlen(elf_module);
  129.     shstrtab = NULL;
  130.     shstrtablen = shstrtabsize = 0;;
  131.     add_sectname ("", "");
  132.     fwds = NULL;
  133.     elf_gotpc_sect = seg_alloc();
  134.     ldef("..gotpc", elf_gotpc_sect+1, 0L, NULL, FALSE, FALSE, &of_elf, error);
  135.     elf_gotoff_sect = seg_alloc();
  136.     ldef("..gotoff", elf_gotoff_sect+1, 0L, NULL, FALSE, FALSE,&of_elf,error);
  137.     elf_got_sect = seg_alloc();
  138.     ldef("..got", elf_got_sect+1, 0L, NULL, FALSE, FALSE, &of_elf, error);
  139.     elf_plt_sect = seg_alloc();
  140.     ldef("..plt", elf_plt_sect+1, 0L, NULL, FALSE, FALSE, &of_elf, error);
  141.     elf_sym_sect = seg_alloc();
  142.     ldef("..sym", elf_sym_sect+1, 0L, NULL, FALSE, FALSE, &of_elf, error);
  143.     def_seg = seg_alloc();
  144. }
  145. static void elf_cleanup(int debuginfo) 
  146. {
  147.     struct Reloc *r;
  148.     int i;
  149.     (void) debuginfo;
  150.     elf_write();
  151.     fclose (elffp);
  152.     for (i=0; i<nsects; i++) {
  153. if (sects[i]->type != SHT_NOBITS)
  154.     saa_free (sects[i]->data);
  155. if (sects[i]->head)
  156.     saa_free (sects[i]->rel);
  157. while (sects[i]->head) {
  158.     r = sects[i]->head;
  159.     sects[i]->head = sects[i]->head->next;
  160.     nasm_free (r);
  161. }
  162.     }
  163.     nasm_free (sects);
  164.     saa_free (syms);
  165.     raa_free (bsym);
  166.     saa_free (strs);
  167. }
  168. static void add_sectname (char *firsthalf, char *secondhalf) 
  169. {
  170.     int len = strlen(firsthalf)+strlen(secondhalf);
  171.     while (shstrtablen + len + 1 > shstrtabsize)
  172. shstrtab = nasm_realloc (shstrtab, (shstrtabsize += SHSTR_DELTA));
  173.     strcpy (shstrtab+shstrtablen, firsthalf);
  174.     strcat (shstrtab+shstrtablen, secondhalf);
  175.     shstrtablen += len+1;
  176. }
  177. static int elf_make_section (char *name, int type, int flags, int align) 
  178. {
  179.     struct Section *s;
  180.     s = nasm_malloc (sizeof(*s));
  181.     if (type != SHT_NOBITS)
  182. s->data = saa_init (1L);
  183.     s->head = NULL;
  184.     s->tail = &s->head;
  185.     s->len = s->size = 0;
  186.     s->nrelocs = 0;
  187.     if (!strcmp(name, ".text"))
  188. s->index = def_seg;
  189.     else
  190. s->index = seg_alloc();
  191.     add_sectname ("", name);
  192.     s->name = nasm_malloc (1+strlen(name));
  193.     strcpy (s->name, name);
  194.     s->type = type;
  195.     s->flags = flags;
  196.     s->align = align;
  197.     s->gsyms = NULL;
  198.     if (nsects >= sectlen)
  199. sects = nasm_realloc (sects, (sectlen += SECT_DELTA)*sizeof(*sects));
  200.     sects[nsects++] = s;
  201.     return nsects-1;
  202. }
  203. static long elf_section_names (char *name, int pass, int *bits) 
  204. {
  205.     char *p;
  206.     int flags_and, flags_or, type, align, i;
  207.     /*
  208.      * Default is 32 bits.
  209.      */
  210.     if (!name) {
  211. *bits = 32;
  212. return def_seg;
  213.     }
  214.     p = name;
  215.     while (*p && !isspace(*p)) p++;
  216.     if (*p) *p++ = '';
  217.     flags_and = flags_or = type = align = 0;
  218.     while (*p && isspace(*p)) p++;
  219.     while (*p) {
  220. char *q = p;
  221. while (*p && !isspace(*p)) p++;
  222. if (*p) *p++ = '';
  223. while (*p && isspace(*p)) p++;
  224. if (!nasm_strnicmp(q, "align=", 6)) {
  225.     align = atoi(q+6);
  226.     if (align == 0)
  227. align = 1;
  228.     if ( (align-1) & align ) {   /* means it's not a power of two */
  229. error (ERR_NONFATAL, "section alignment %d is not"
  230.        " a power of two", align);
  231. align = 1;
  232.     }
  233. } else if (!nasm_stricmp(q, "alloc")) {
  234.     flags_and |= SHF_ALLOC;
  235.     flags_or |= SHF_ALLOC;
  236. } else if (!nasm_stricmp(q, "noalloc")) {
  237.     flags_and |= SHF_ALLOC;
  238.     flags_or &= ~SHF_ALLOC;
  239. } else if (!nasm_stricmp(q, "exec")) {
  240.     flags_and |= SHF_EXECINSTR;
  241.     flags_or |= SHF_EXECINSTR;
  242. } else if (!nasm_stricmp(q, "noexec")) {
  243.     flags_and |= SHF_EXECINSTR;
  244.     flags_or &= ~SHF_EXECINSTR;
  245. } else if (!nasm_stricmp(q, "write")) {
  246.     flags_and |= SHF_WRITE;
  247.     flags_or |= SHF_WRITE;
  248. } else if (!nasm_stricmp(q, "nowrite")) {
  249.     flags_and |= SHF_WRITE;
  250.     flags_or &= ~SHF_WRITE;
  251. } else if (!nasm_stricmp(q, "progbits")) {
  252.     type = SHT_PROGBITS;
  253. } else if (!nasm_stricmp(q, "nobits")) {
  254.     type = SHT_NOBITS;
  255. }
  256.     }
  257.     if (!strcmp(name, ".comment") ||
  258. !strcmp(name, ".shstrtab") ||
  259. !strcmp(name, ".symtab") ||
  260. !strcmp(name, ".strtab")) {
  261. error (ERR_NONFATAL, "attempt to redefine reserved section"
  262.        "name `%s'", name);
  263. return NO_SEG;
  264.     }
  265.     for (i=0; i<nsects; i++)
  266. if (!strcmp(name, sects[i]->name))
  267.     break;
  268.     if (i == nsects) {
  269. if (!strcmp(name, ".text"))
  270.     i = elf_make_section (name, SHT_PROGBITS,
  271.   SHF_ALLOC | SHF_EXECINSTR, 16);
  272. else if (!strcmp(name, ".data"))
  273.     i = elf_make_section (name, SHT_PROGBITS,
  274.   SHF_ALLOC | SHF_WRITE, 4);
  275. else if (!strcmp(name, ".bss"))
  276.     i = elf_make_section (name, SHT_NOBITS,
  277.   SHF_ALLOC | SHF_WRITE, 4);
  278. else
  279.     i = elf_make_section (name, SHT_PROGBITS, SHF_ALLOC, 1);
  280. if (type)
  281.     sects[i]->type = type;
  282. if (align)
  283.     sects[i]->align = align;
  284. sects[i]->flags &= ~flags_and;
  285. sects[i]->flags |= flags_or;
  286.     } else if (pass == 1) {
  287. if (type || align || flags_and)
  288.     error (ERR_WARNING, "section attributes ignored on"
  289.    " redeclaration of section `%s'", name);
  290.     }
  291.     return sects[i]->index;
  292. }
  293. static void elf_deflabel (char *name, long segment, long offset,
  294.    int is_global, char *special) 
  295. {
  296.     int pos = strslen;
  297.     struct Symbol *sym;
  298.     int special_used = FALSE;
  299.     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  300. /*
  301.  * This is a NASM special symbol. We never allow it into
  302.  * the ELF symbol table, even if it's a valid one. If it
  303.  * _isn't_ a valid one, we should barf immediately.
  304.  */
  305. if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
  306.     strcmp(name, "..got") && strcmp(name, "..plt") &&
  307.     strcmp(name, "..sym"))
  308.     error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
  309. return;
  310.     }
  311.     if (is_global == 3) {
  312. struct Symbol **s;
  313. /*
  314.  * Fix up a forward-reference symbol size from the first
  315.  * pass.
  316.  */
  317. for (s = &fwds; *s; s = &(*s)->nextfwd)
  318.     if (!strcmp((*s)->name, name)) {
  319. struct tokenval tokval;
  320. expr *e;
  321. char *p = special;
  322. while (*p && !isspace(*p)) p++;
  323. while (*p && isspace(*p)) p++;
  324. stdscan_reset();
  325. stdscan_bufptr = p;
  326. tokval.t_type = TOKEN_INVALID;
  327. e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
  328. if (e) {
  329.     if (!is_simple(e))
  330. error (ERR_NONFATAL, "cannot use relocatable"
  331.        " expression as symbol size");
  332.     else
  333. (*s)->size = reloc_value(e);
  334. }
  335. /*
  336.  * Remove it from the list of unresolved sizes.
  337.  */
  338. nasm_free ((*s)->name);
  339. *s = (*s)->nextfwd;
  340. return;
  341.     }
  342. return;        /* it wasn't an important one */
  343.     }
  344.     saa_wbytes (strs, name, (long)(1+strlen(name)));
  345.     strslen += 1+strlen(name);
  346.     sym = saa_wstruct (syms);
  347.     sym->strpos = pos;
  348.     sym->type = is_global ? SYM_GLOBAL : 0;
  349.     sym->size = 0;
  350.     if (segment == NO_SEG)
  351. sym->section = SHN_ABS;
  352.     else {
  353. int i;
  354. sym->section = SHN_UNDEF;
  355. if (nsects == 0 && segment == def_seg) {
  356.     int tempint;
  357.     if (segment != elf_section_names (".text", 2, &tempint))
  358. error (ERR_PANIC, "strange segment conditions in ELF driver");
  359.     sym->section = nsects;
  360. } else {
  361.     for (i=0; i<nsects; i++)
  362. if (segment == sects[i]->index) {
  363.     sym->section = i+1;
  364.     break;
  365. }
  366. }
  367.     }
  368.     if (is_global == 2) {
  369. sym->size = offset;
  370. sym->value = 0;
  371. sym->section = SHN_COMMON;
  372. /*
  373.  * We have a common variable. Check the special text to see
  374.  * if it's a valid number and power of two; if so, store it
  375.  * as the alignment for the common variable.
  376.  */
  377. if (special) {
  378.     int err;
  379.     sym->value = readnum (special, &err);
  380.     if (err)
  381. error(ERR_NONFATAL, "alignment constraint `%s' is not a"
  382.       " valid number", special);
  383.     else if ( (sym->value | (sym->value-1)) != 2*sym->value - 1)
  384. error(ERR_NONFATAL, "alignment constraint `%s' is not a"
  385.       " power of two", special);
  386. }
  387. special_used = TRUE;
  388.     } else
  389. sym->value = (sym->section == SHN_UNDEF ? 0 : offset);
  390.     if (sym->type == SYM_GLOBAL) {
  391. /*
  392.  * There's a problem here that needs fixing. 
  393.  * If sym->section == SHN_ABS, then the first line of the
  394.  * else section causes a core dump, because its a reference
  395.  * beyond the end of the section array.
  396.  * This behaviour is exhibited by this code:
  397.  *     GLOBAL crash_nasm
  398.  *     crash_nasm equ 0
  399.  *
  400.  * I'm not sure how to procede, because I haven't got the
  401.  * first clue about how ELF works, so I don't know what to
  402.  * do with it. Furthermore, I'm not sure what the rest of this
  403.  * section of code does. Help?
  404.  *
  405.  * For now, I'll see if doing absolutely nothing with it will
  406.  * work...
  407.  */
  408. if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON)
  409. {
  410.     bsym = raa_write (bsym, segment, nglobs);
  411. }
  412. else if (sym->section != SHN_ABS) 
  413. {
  414.     /*
  415.      * This is a global symbol; so we must add it to the linked
  416.      * list of global symbols in its section. We'll push it on
  417.      * the beginning of the list, because it doesn't matter
  418.      * much which end we put it on and it's easier like this.
  419.      *
  420.      * In addition, we check the special text for symbol
  421.      * type and size information.
  422.      */
  423.     sym->next = sects[sym->section-1]->gsyms;
  424.     sects[sym->section-1]->gsyms = sym;
  425.     if (special) {
  426. int n = strcspn(special, " ");
  427. if (!nasm_strnicmp(special, "function", n))
  428.     sym->type |= SYM_FUNCTION;
  429. else if (!nasm_strnicmp(special, "data", n) ||
  430.  !nasm_strnicmp(special, "object", n))
  431.     sym->type |= SYM_DATA;
  432. else
  433.     error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
  434.   n, special);
  435. if (special[n]) {
  436.     struct tokenval tokval;
  437.     expr *e;
  438.     int fwd = FALSE;
  439.     while (special[n] && isspace(special[n]))
  440. n++;
  441.     /*
  442.      * We have a size expression; attempt to
  443.      * evaluate it.
  444.      */
  445.     stdscan_reset();
  446.     stdscan_bufptr = special+n;
  447.     tokval.t_type = TOKEN_INVALID;
  448.     e = evaluate(stdscan, NULL, &tokval, &fwd, 0, error, NULL);
  449.     if (fwd) {
  450. sym->nextfwd = fwds;
  451. fwds = sym;
  452. sym->name = nasm_strdup(name);
  453.     } else if (e) {
  454. if (!is_simple(e))
  455.     error (ERR_NONFATAL, "cannot use relocatable"
  456.    " expression as symbol size");
  457. else
  458.     sym->size = reloc_value(e);
  459.     }
  460. }
  461. special_used = TRUE;
  462.     }
  463. }
  464. sym->globnum = nglobs;
  465. nglobs++;
  466.     } else
  467. nlocals++;
  468.     if (special && !special_used)
  469. error(ERR_NONFATAL, "no special symbol features supported here");
  470. }
  471. static void elf_add_reloc (struct Section *sect, long segment,
  472.    int type) 
  473. {
  474.     struct Reloc *r;
  475.     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
  476.     sect->tail = &r->next;
  477.     r->next = NULL;
  478.     r->address = sect->len;
  479.     if (segment == NO_SEG)
  480. r->symbol = 2;
  481.     else {
  482. int i;
  483. r->symbol = 0;
  484. for (i=0; i<nsects; i++)
  485.     if (segment == sects[i]->index)
  486. r->symbol = i+3;
  487. if (!r->symbol)
  488.     r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
  489.     }
  490.     r->type = type;
  491.     sect->nrelocs++;
  492. }
  493. /*
  494.  * This routine deals with ..got and ..sym relocations: the more
  495.  * complicated kinds. In shared-library writing, some relocations
  496.  * with respect to global symbols must refer to the precise symbol
  497.  * rather than referring to an offset from the base of the section
  498.  * _containing_ the symbol. Such relocations call to this routine,
  499.  * which searches the symbol list for the symbol in question.
  500.  *
  501.  * R_386_GOT32 references require the _exact_ symbol address to be
  502.  * used; R_386_32 references can be at an offset from the symbol.
  503.  * The boolean argument `exact' tells us this.
  504.  *
  505.  * Return value is the adjusted value of `addr', having become an
  506.  * offset from the symbol rather than the section. Should always be
  507.  * zero when returning from an exact call.
  508.  *
  509.  * Limitation: if you define two symbols at the same place,
  510.  * confusion will occur.
  511.  *
  512.  * Inefficiency: we search, currently, using a linked list which
  513.  * isn't even necessarily sorted.
  514.  */
  515. static long elf_add_gsym_reloc (struct Section *sect,
  516. long segment, long offset,
  517. int type, int exact) 
  518. {
  519.     struct Reloc *r;
  520.     struct Section *s;
  521.     struct Symbol *sym, *sm;
  522.     int i;
  523.     /*
  524.      * First look up the segment/offset pair and find a global
  525.      * symbol corresponding to it. If it's not one of our segments,
  526.      * then it must be an external symbol, in which case we're fine
  527.      * doing a normal elf_add_reloc after first sanity-checking
  528.      * that the offset from the symbol is zero.
  529.      */
  530.     s = NULL;
  531.     for (i=0; i<nsects; i++)
  532. if (segment == sects[i]->index) {
  533.     s = sects[i];
  534.     break;
  535. }
  536.     if (!s) {
  537. if (exact && offset != 0)
  538.     error (ERR_NONFATAL, "unable to find a suitable global symbol"
  539.    " for this reference");
  540. else
  541.     elf_add_reloc (sect, segment, type);
  542. return offset;
  543.     }
  544.     if (exact) {
  545. /*
  546.  * Find a symbol pointing _exactly_ at this one.
  547.  */
  548. for (sym = s->gsyms; sym; sym = sym->next)
  549.     if (sym->value == offset)
  550. break;
  551.     } else {
  552. /*
  553.  * Find the nearest symbol below this one.
  554.  */
  555. sym = NULL;
  556. for (sm = s->gsyms; sm; sm = sm->next)
  557.     if (sm->value <= offset && (!sym || sm->value > sym->value))
  558. sym = sm;
  559.     }
  560.     if (!sym && exact) {
  561. error (ERR_NONFATAL, "unable to find a suitable global symbol"
  562.        " for this reference");
  563. return 0;
  564.     }
  565.     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
  566.     sect->tail = &r->next;
  567.     r->next = NULL;
  568.     r->address = sect->len;
  569.     r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
  570.     r->type = type;
  571.     sect->nrelocs++;
  572.     return offset - sym->value;
  573. }
  574. static void elf_out (long segto, void *data, unsigned long type,
  575.       long segment, long wrt) 
  576. {
  577.     struct Section *s;
  578.     long realbytes = type & OUT_SIZMASK;
  579.     long addr;
  580.     unsigned char mydata[4], *p;
  581.     int i;
  582.     type &= OUT_TYPMASK;
  583.     /*
  584.      * handle absolute-assembly (structure definitions)
  585.      */
  586.     if (segto == NO_SEG) {
  587. if (type != OUT_RESERVE)
  588.     error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  589.    " space");
  590. return;
  591.     }
  592.     s = NULL;
  593.     for (i=0; i<nsects; i++)
  594. if (segto == sects[i]->index) {
  595.     s = sects[i];
  596.     break;
  597. }
  598.     if (!s) {
  599. int tempint;        /* ignored */
  600. if (segto != elf_section_names (".text", 2, &tempint))
  601.     error (ERR_PANIC, "strange segment conditions in ELF driver");
  602. else
  603.     s = sects[nsects-1];
  604.     }
  605.     if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
  606. error(ERR_WARNING, "attempt to initialise memory in"
  607.       " BSS section `%s': ignored", s->name);
  608. if (type == OUT_REL2ADR)
  609.     realbytes = 2;
  610. else if (type == OUT_REL4ADR)
  611.     realbytes = 4;
  612. s->len += realbytes;
  613. return;
  614.     }
  615.     if (type == OUT_RESERVE) {
  616. if (s->type == SHT_PROGBITS) {
  617.     error(ERR_WARNING, "uninitialised space declared in"
  618.   " non-BSS section `%s': zeroing", s->name);
  619.     elf_sect_write (s, NULL, realbytes);
  620. } else
  621.     s->len += realbytes;
  622.     } else if (type == OUT_RAWDATA) {
  623. if (segment != NO_SEG)
  624.     error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
  625. elf_sect_write (s, data, realbytes);
  626.     } else if (type == OUT_ADDRESS) {
  627. addr = *(long *)data;
  628. if (segment != NO_SEG) {
  629.     if (segment % 2) {
  630. error(ERR_NONFATAL, "ELF format does not support"
  631.       " segment base references");
  632.     } else {
  633. if (wrt == NO_SEG) {
  634.     elf_add_reloc (s, segment, R_386_32);
  635. } else if (wrt == elf_gotpc_sect+1) {
  636.     /*
  637.      * The user will supply GOT relative to $$. ELF
  638.      * will let us have GOT relative to $. So we
  639.      * need to fix up the data item by $-$$.
  640.      */
  641.     addr += s->len;
  642.     elf_add_reloc (s, segment, R_386_GOTPC);
  643. } else if (wrt == elf_gotoff_sect+1) {
  644.     elf_add_reloc (s, segment, R_386_GOTOFF);
  645. } else if (wrt == elf_got_sect+1) {
  646.     addr = elf_add_gsym_reloc (s, segment, addr,
  647.        R_386_GOT32, TRUE);
  648. } else if (wrt == elf_sym_sect+1) {
  649.     addr = elf_add_gsym_reloc (s, segment, addr,
  650.        R_386_32, FALSE);
  651. } else if (wrt == elf_plt_sect+1) {
  652.     error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
  653.   "relative PLT references");
  654. } else {
  655.     error (ERR_NONFATAL, "ELF format does not support this"
  656.    " use of WRT");
  657.     wrt = NO_SEG;      /* we can at least _try_ to continue */
  658. }
  659.     }
  660. }
  661. p = mydata;
  662. if (realbytes != 4 && segment != NO_SEG)
  663.     error (ERR_NONFATAL, "ELF format does not support non-32-bit"
  664.    " relocations");
  665. WRITELONG (p, addr);
  666. elf_sect_write (s, mydata, realbytes);
  667.     } else if (type == OUT_REL2ADR) {
  668. error (ERR_NONFATAL, "ELF format does not support 16-bit"
  669.        " relocations");
  670.     } else if (type == OUT_REL4ADR) {
  671. if (segment == segto)
  672.     error(ERR_PANIC, "intra-segment OUT_REL4ADR");
  673. if (segment != NO_SEG && segment % 2) {
  674.     error(ERR_NONFATAL, "ELF format does not support"
  675.   " segment base references");
  676. } else {
  677.     if (wrt == NO_SEG) {
  678. elf_add_reloc (s, segment, R_386_PC32);
  679.     } else if (wrt == elf_plt_sect+1) {
  680. elf_add_reloc (s, segment, R_386_PLT32);
  681.     } else if (wrt == elf_gotpc_sect+1 ||
  682.        wrt == elf_gotoff_sect+1 ||
  683.        wrt == elf_got_sect+1) {
  684. error(ERR_NONFATAL, "ELF format cannot produce PC-"
  685.       "relative GOT references");
  686.     } else {
  687. error (ERR_NONFATAL, "ELF format does not support this"
  688.        " use of WRT");
  689. wrt = NO_SEG;      /* we can at least _try_ to continue */
  690.     }
  691. }
  692. p = mydata;
  693. WRITELONG (p, *(long*)data - realbytes);
  694. elf_sect_write (s, mydata, 4L);
  695.     }
  696. }
  697. static void elf_write(void) 
  698. {
  699.     int nsections, align;
  700.     char *p;
  701.     int commlen;
  702.     char comment[64];
  703.     int i;
  704.     struct SAA *symtab;
  705.     long symtablen, symtablocal;
  706.     /*
  707.      * Work out how many sections we will have. We have SHN_UNDEF,
  708.      * then the flexible user sections, then the four fixed
  709.      * sections `.comment', `.shstrtab', `.symtab' and `.strtab',
  710.      * then optionally relocation sections for the user sections.
  711.      */
  712.     nsections = 5;        /* SHN_UNDEF and the fixed ones */
  713.     add_sectname ("", ".comment");
  714.     add_sectname ("", ".shstrtab");
  715.     add_sectname ("", ".symtab");
  716.     add_sectname ("", ".strtab");
  717.     for (i=0; i<nsects; i++) {
  718. nsections++;        /* for the section itself */
  719. if (sects[i]->head) {
  720.     nsections++;        /* for its relocations */
  721.     add_sectname (".rel", sects[i]->name);
  722. }
  723.     }
  724.     /*
  725.      * Do the comment.
  726.      */
  727.     *comment = '';
  728.     commlen = 2+sprintf(comment+1, "The Netwide Assembler %s", NASM_VER);
  729.     /*
  730.      * Output the ELF header.
  731.      */
  732.     fwrite ("177ELF111", 16, 1, elffp);
  733.     fwriteshort (1, elffp);        /* ET_REL relocatable file */
  734.     fwriteshort (3, elffp);        /* EM_386 processor ID */
  735.     fwritelong (1L, elffp);        /* EV_CURRENT file format version */
  736.     fwritelong (0L, elffp);        /* no entry point */
  737.     fwritelong (0L, elffp);        /* no program header table */
  738.     fwritelong (0x40L, elffp);        /* section headers straight after
  739. * ELF header plus alignment */
  740.     fwritelong (0L, elffp);        /* 386 defines no special flags */
  741.     fwriteshort (0x34, elffp);        /* size of ELF header */
  742.     fwriteshort (0, elffp);        /* no program header table, again */
  743.     fwriteshort (0, elffp);        /* still no program header table */
  744.     fwriteshort (0x28, elffp);        /* size of section header */
  745.     fwriteshort (nsections, elffp);    /* number of sections */
  746.     fwriteshort (nsects+2, elffp);     /* string table section index for
  747. * section header table */
  748.     fwritelong (0L, elffp);        /* align to 0x40 bytes */
  749.     fwritelong (0L, elffp);
  750.     fwritelong (0L, elffp);
  751.     /*
  752.      * Build the symbol table and relocation tables.
  753.      */
  754.     symtab = elf_build_symtab (&symtablen, &symtablocal);
  755.     for (i=0; i<nsects; i++)
  756. if (sects[i]->head)
  757.     sects[i]->rel = elf_build_reltab (&sects[i]->rellen,
  758.       sects[i]->head);
  759.     /*
  760.      * Now output the section header table.
  761.      */
  762.     elf_foffs = 0x40 + 0x28 * nsections;
  763.     align = ((elf_foffs+SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
  764.     elf_foffs += align;
  765.     elf_nsect = 0;
  766.     elf_sects = nasm_malloc(sizeof(*elf_sects) * (2 * nsects + 10));
  767.     elf_section_header (0, 0, 0, NULL, FALSE, 0L, 0, 0, 0, 0); /* SHN_UNDEF */
  768.     p = shstrtab+1;
  769.     for (i=0; i<nsects; i++) {
  770. elf_section_header (p - shstrtab, sects[i]->type, sects[i]->flags,
  771.     (sects[i]->type == SHT_PROGBITS ?
  772.      sects[i]->data : NULL), TRUE,
  773.     sects[i]->len, 0, 0, sects[i]->align, 0);
  774. p += strlen(p)+1;
  775.     }
  776.     elf_section_header (p - shstrtab, 1, 0, comment, FALSE,
  777. (long)commlen, 0, 0, 1, 0);/* .comment */
  778.     p += strlen(p)+1;
  779.     elf_section_header (p - shstrtab, 3, 0, shstrtab, FALSE,
  780. (long)shstrtablen, 0, 0, 1, 0);/* .shstrtab */
  781.     p += strlen(p)+1;
  782.     elf_section_header (p - shstrtab, 2, 0, symtab, TRUE,
  783. symtablen, nsects+4, symtablocal, 4, 16);/* .symtab */
  784.     p += strlen(p)+1;
  785.     elf_section_header (p - shstrtab, 3, 0, strs, TRUE,
  786. strslen, 0, 0, 1, 0);     /* .strtab */
  787.     for (i=0; i<nsects; i++) if (sects[i]->head) {
  788. p += strlen(p)+1;
  789. elf_section_header (p - shstrtab, 9, 0, sects[i]->rel, TRUE,
  790.     sects[i]->rellen, nsects+3, i+1, 4, 8);
  791.     }
  792.     fwrite (align_str, align, 1, elffp);
  793.     /*
  794.      * Now output the sections.
  795.      */
  796.     elf_write_sections();
  797.     nasm_free (elf_sects);
  798.     saa_free (symtab);
  799. }
  800. static struct SAA *elf_build_symtab (long *len, long *local) 
  801. {
  802.     struct SAA *s = saa_init(1L);
  803.     struct Symbol *sym;
  804.     unsigned char entry[16], *p;
  805.     int i;
  806.     *len = *local = 0;
  807.     /*
  808.      * First, an all-zeros entry, required by the ELF spec.
  809.      */
  810.     saa_wbytes (s, NULL, 16L);        /* null symbol table entry */
  811.     *len += 16;
  812.     (*local)++;
  813.     /*
  814.      * Next, an entry for the file name.
  815.      */
  816.     p = entry;
  817.     WRITELONG (p, 1);        /* we know it's 1st thing in strtab */
  818.     WRITELONG (p, 0);        /* no value */
  819.     WRITELONG (p, 0);        /* no size either */
  820.     WRITESHORT (p, 4);        /* type FILE */
  821.     WRITESHORT (p, SHN_ABS);
  822.     saa_wbytes (s, entry, 16L);
  823.     *len += 16;
  824.     (*local)++;
  825.     /*
  826.      * Now some standard symbols defining the segments, for relocation
  827.      * purposes.
  828.      */
  829.     for (i = 1; i <= nsects+1; i++) {
  830. p = entry;
  831. WRITELONG (p, 0);        /* no symbol name */
  832. WRITELONG (p, 0);        /* offset zero */
  833. WRITELONG (p, 0);        /* size zero */
  834. WRITESHORT (p, 3);        /* local section-type thing */
  835. WRITESHORT (p, (i==1 ? SHN_ABS : i-1));   /* the section id */
  836. saa_wbytes (s, entry, 16L);
  837. *len += 16;
  838. (*local)++;
  839.     }
  840.     /*
  841.      * Now the other local symbols.
  842.      */
  843.     saa_rewind (syms);
  844.     while ( (sym = saa_rstruct (syms)) ) {
  845. if (sym->type & SYM_GLOBAL)
  846.     continue;
  847. p = entry;
  848. WRITELONG (p, sym->strpos);
  849. WRITELONG (p, sym->value);
  850. WRITELONG (p, sym->size);
  851. WRITESHORT (p, sym->type);     /* local non-typed thing */
  852. WRITESHORT (p, sym->section);
  853. saa_wbytes (s, entry, 16L);
  854.         *len += 16;
  855. (*local)++;
  856.     }
  857.     /*
  858.      * Now the global symbols.
  859.      */
  860.     saa_rewind (syms);
  861.     while ( (sym = saa_rstruct (syms)) ) {
  862. if (!(sym->type & SYM_GLOBAL))
  863.     continue;
  864. p = entry;
  865. WRITELONG (p, sym->strpos);
  866. WRITELONG (p, sym->value);
  867. WRITELONG (p, sym->size);
  868. WRITESHORT (p, sym->type);     /* global non-typed thing */
  869. WRITESHORT (p, sym->section);
  870. saa_wbytes (s, entry, 16L);
  871. *len += 16;
  872.     }
  873.     return s;
  874. }
  875. static struct SAA *elf_build_reltab (long *len, struct Reloc *r) {
  876.     struct SAA *s;
  877.     unsigned char *p, entry[8];
  878.     if (!r)
  879. return NULL;
  880.     s = saa_init(1L);
  881.     *len = 0;
  882.     while (r) {
  883. long sym = r->symbol;
  884. if (sym >= GLOBAL_TEMP_BASE)
  885.     sym += -GLOBAL_TEMP_BASE + (nsects+3) + nlocals;
  886. p = entry;
  887. WRITELONG (p, r->address);
  888. WRITELONG (p, (sym << 8) + r->type);
  889. saa_wbytes (s, entry, 8L);
  890. *len += 8;
  891. r = r->next;
  892.     }
  893.     return s;
  894. }
  895. static void elf_section_header (int name, int type, int flags,
  896. void *data, int is_saa, long datalen,
  897. int link, int info, int align, int eltsize) 
  898. {
  899.     elf_sects[elf_nsect].data = data;
  900.     elf_sects[elf_nsect].len = datalen;
  901.     elf_sects[elf_nsect].is_saa = is_saa;
  902.     elf_nsect++;
  903.     fwritelong ((long)name, elffp);
  904.     fwritelong ((long)type, elffp);
  905.     fwritelong ((long)flags, elffp);
  906.     fwritelong (0L, elffp);        /* no address, ever, in object files */
  907.     fwritelong (type == 0 ? 0L : elf_foffs, elffp);
  908.     fwritelong (datalen, elffp);
  909.     if (data)
  910. elf_foffs += (datalen+SEG_ALIGN_1) & ~SEG_ALIGN_1;
  911.     fwritelong ((long)link, elffp);
  912.     fwritelong ((long)info, elffp);
  913.     fwritelong ((long)align, elffp);
  914.     fwritelong ((long)eltsize, elffp);
  915. }
  916. static void elf_write_sections (void) 
  917. {
  918.     int i;
  919.     for (i = 0; i < elf_nsect; i++)
  920. if (elf_sects[i].data) {
  921.     long len = elf_sects[i].len;
  922.     long reallen = (len+SEG_ALIGN_1) & ~SEG_ALIGN_1;
  923.     long align = reallen - len;
  924.     if (elf_sects[i].is_saa)
  925. saa_fpwrite (elf_sects[i].data, elffp);
  926.     else
  927. fwrite (elf_sects[i].data, len, 1, elffp);
  928.     fwrite (align_str, align, 1, elffp);
  929. }
  930. }
  931. static void elf_sect_write (struct Section *sect,
  932.      unsigned char *data, unsigned long len) 
  933. {
  934.     saa_wbytes (sect->data, data, len);
  935.     sect->len += len;
  936. }
  937. static long elf_segbase (long segment) 
  938. {
  939.     return segment;
  940. }
  941. static int elf_directive (char *directive, char *value, int pass) 
  942. {
  943.     return 0;
  944. }
  945. static void elf_filename (char *inname, char *outname, efunc error) 
  946. {
  947.     strcpy(elf_module, inname);
  948.     standard_extension (inname, outname, ".o", error);
  949. }
  950. static char *elf_stdmac[] = {
  951.     "%define __SECT__ [section .text]",
  952.     "%macro __NASM_CDecl__ 1",
  953.     "%define $_%1 $%1",
  954.     "%endmacro",
  955.     NULL
  956. };
  957. static int elf_set_info(enum geninfo type, char **val)
  958. {
  959.     return 0;
  960. }
  961. struct ofmt of_elf = {
  962.     "ELF32 (i386) object files (e.g. Linux)",
  963.     "elf",
  964.     NULL,
  965.     null_debug_arr,
  966.     &null_debug_form,
  967.     elf_stdmac,
  968.     elf_init,
  969.     elf_set_info,
  970.     elf_out,
  971.     elf_deflabel,
  972.     elf_section_names,
  973.     elf_segbase,
  974.     elf_directive,
  975.     elf_filename,
  976.     elf_cleanup
  977. };
  978. #endif /* OF_ELF */