OLD | NEW |
1 /* | 1 /* |
2 * COFF (DJGPP) object format | 2 * COFF (DJGPP) object format |
3 * | 3 * |
4 * Copyright (C) 2002-2007 Peter Johnson | 4 * Copyright (C) 2002-2007 Peter Johnson |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
14 * | 14 * |
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 #include <util.h> | 27 #include <util.h> |
28 #include <time.h> | 28 #include <time.h> |
29 /*@unused@*/ RCSID("$Id: coff-objfmt.c 2347 2010-08-01 17:31:12Z peter $"); | |
30 | 29 |
31 #include <libyasm.h> | 30 #include <libyasm.h> |
32 | 31 |
33 #include "coff-objfmt.h" | 32 #include "coff-objfmt.h" |
34 | 33 |
35 | 34 |
36 #define REGULAR_OUTBUF_SIZE 1024 | 35 #define REGULAR_OUTBUF_SIZE 1024 |
37 | 36 |
38 /* Defining this to 0 sets all section VMA's to 0 rather than as the same as | 37 /* Defining this to 0 sets all section VMA's to 0 rather than as the same as |
39 * the LMA. According to the DJGPP COFF Spec, this should be set to 1 | 38 * the LMA. According to the DJGPP COFF Spec, this should be set to 1 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 yasm_objfmt_base objfmt; /* base structure */ | 175 yasm_objfmt_base objfmt; /* base structure */ |
177 | 176 |
178 unsigned int parse_scnum; /* sect numbering in parser */ | 177 unsigned int parse_scnum; /* sect numbering in parser */ |
179 int win32; /* nonzero for win32/64 output */ | 178 int win32; /* nonzero for win32/64 output */ |
180 int win64; /* nonzero for win64 output */ | 179 int win64; /* nonzero for win64 output */ |
181 | 180 |
182 unsigned int machine; /* COFF machine to use */ | 181 unsigned int machine; /* COFF machine to use */ |
183 | 182 |
184 coff_symrec_data *filesym_data; /* Data for .file symbol */ | 183 coff_symrec_data *filesym_data; /* Data for .file symbol */ |
185 | 184 |
| 185 /* data for .def/.endef and related directives */ |
| 186 coff_symrec_data *def_sym; /* symbol specified by .def */ |
| 187 |
186 /* data for win64 proc_frame and related directives */ | 188 /* data for win64 proc_frame and related directives */ |
187 unsigned long proc_frame; /* Line number of start of proc, or 0 */ | 189 unsigned long proc_frame; /* Line number of start of proc, or 0 */ |
188 unsigned long done_prolog; /* Line number of end of prologue, or 0 */ | 190 unsigned long done_prolog; /* Line number of end of prologue, or 0 */ |
189 /*@null@*/ coff_unwind_info *unwind; /* Unwind info */ | 191 /*@null@*/ coff_unwind_info *unwind; /* Unwind info */ |
| 192 |
| 193 yasm_symrec *ssym_imagebase; /* ..imagebase symbol for win64 */ |
190 } yasm_objfmt_coff; | 194 } yasm_objfmt_coff; |
191 | 195 |
192 typedef struct coff_objfmt_output_info { | 196 typedef struct coff_objfmt_output_info { |
193 yasm_object *object; | 197 yasm_object *object; |
194 yasm_objfmt_coff *objfmt_coff; | 198 yasm_objfmt_coff *objfmt_coff; |
195 yasm_errwarns *errwarns; | 199 yasm_errwarns *errwarns; |
196 /*@dependent@*/ FILE *f; | 200 /*@dependent@*/ FILE *f; |
197 /*@only@*/ unsigned char *buf; | 201 /*@only@*/ unsigned char *buf; |
198 yasm_section *sect; | 202 yasm_section *sect; |
199 /*@dependent@*/ coff_section_data *csd; | 203 /*@dependent@*/ coff_section_data *csd; |
(...skipping 20 matching lines...) Expand all Loading... |
220 coff_symrec_data_print | 224 coff_symrec_data_print |
221 }; | 225 }; |
222 | 226 |
223 /* Bytecode callback function prototypes */ | 227 /* Bytecode callback function prototypes */ |
224 static void win32_sxdata_bc_destroy(void *contents); | 228 static void win32_sxdata_bc_destroy(void *contents); |
225 static void win32_sxdata_bc_print(const void *contents, FILE *f, | 229 static void win32_sxdata_bc_print(const void *contents, FILE *f, |
226 int indent_level); | 230 int indent_level); |
227 static int win32_sxdata_bc_calc_len | 231 static int win32_sxdata_bc_calc_len |
228 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); | 232 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); |
229 static int win32_sxdata_bc_tobytes | 233 static int win32_sxdata_bc_tobytes |
230 (yasm_bytecode *bc, unsigned char **bufp, void *d, | 234 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
231 yasm_output_value_func output_value, | 235 yasm_output_value_func output_value, |
232 /*@null@*/ yasm_output_reloc_func output_reloc); | 236 /*@null@*/ yasm_output_reloc_func output_reloc); |
233 | 237 |
234 /* Bytecode callback structures */ | 238 /* Bytecode callback structures */ |
235 static const yasm_bytecode_callback win32_sxdata_bc_callback = { | 239 static const yasm_bytecode_callback win32_sxdata_bc_callback = { |
236 win32_sxdata_bc_destroy, | 240 win32_sxdata_bc_destroy, |
237 win32_sxdata_bc_print, | 241 win32_sxdata_bc_print, |
238 yasm_bc_finalize_common, | 242 yasm_bc_finalize_common, |
239 NULL, | 243 NULL, |
240 win32_sxdata_bc_calc_len, | 244 win32_sxdata_bc_calc_len, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 YASM_SYM_GLOBAL); | 291 YASM_SYM_GLOBAL); |
288 objfmt_coff->filesym_data = | 292 objfmt_coff->filesym_data = |
289 coff_objfmt_sym_set_data(filesym, COFF_SCL_FILE, 1, | 293 coff_objfmt_sym_set_data(filesym, COFF_SCL_FILE, 1, |
290 COFF_SYMTAB_AUX_FILE); | 294 COFF_SYMTAB_AUX_FILE); |
291 /* Filename is set in coff_objfmt_output */ | 295 /* Filename is set in coff_objfmt_output */ |
292 objfmt_coff->filesym_data->aux[0].fname = NULL; | 296 objfmt_coff->filesym_data->aux[0].fname = NULL; |
293 | 297 |
294 objfmt_coff->proc_frame = 0; | 298 objfmt_coff->proc_frame = 0; |
295 objfmt_coff->done_prolog = 0; | 299 objfmt_coff->done_prolog = 0; |
296 objfmt_coff->unwind = NULL; | 300 objfmt_coff->unwind = NULL; |
| 301 objfmt_coff->ssym_imagebase = NULL; |
297 | 302 |
298 return objfmt_coff; | 303 return objfmt_coff; |
299 } | 304 } |
300 | 305 |
301 static yasm_objfmt * | 306 static yasm_objfmt * |
302 coff_objfmt_create(yasm_object *object) | 307 coff_objfmt_create(yasm_object *object) |
303 { | 308 { |
304 yasm_objfmt_coff *objfmt_coff = coff_common_create(object); | 309 yasm_objfmt_coff *objfmt_coff = coff_common_create(object); |
305 | 310 |
306 if (objfmt_coff) { | 311 if (objfmt_coff) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 "amd64") == 0) { | 378 "amd64") == 0) { |
374 objfmt_coff->machine = COFF_MACHINE_AMD64; | 379 objfmt_coff->machine = COFF_MACHINE_AMD64; |
375 } else { | 380 } else { |
376 yasm_xfree(objfmt_coff); | 381 yasm_xfree(objfmt_coff); |
377 return NULL; | 382 return NULL; |
378 } | 383 } |
379 | 384 |
380 objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt; | 385 objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt; |
381 objfmt_coff->win32 = 1; | 386 objfmt_coff->win32 = 1; |
382 objfmt_coff->win64 = 1; | 387 objfmt_coff->win64 = 1; |
| 388 objfmt_coff->ssym_imagebase = |
| 389 yasm_symtab_define_label(object->symtab, "..imagebase", NULL, 0, 0); |
383 } | 390 } |
384 return (yasm_objfmt *)objfmt_coff; | 391 return (yasm_objfmt *)objfmt_coff; |
385 } | 392 } |
386 | 393 |
387 static void | 394 static void |
388 coff_objfmt_init_new_section(yasm_section *sect, unsigned long line) | 395 coff_objfmt_init_new_section(yasm_section *sect, unsigned long line) |
389 { | 396 { |
390 yasm_object *object = yasm_section_get_object(sect); | 397 yasm_object *object = yasm_section_get_object(sect); |
391 const char *sectname = yasm_section_get_name(sect); | 398 const char *sectname = yasm_section_get_name(sect); |
392 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; | 399 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 return 1; | 487 return 1; |
481 } | 488 } |
482 | 489 |
483 intn_val = 0; | 490 intn_val = 0; |
484 intn_minus = 0; | 491 intn_minus = 0; |
485 if (value->rel) { | 492 if (value->rel) { |
486 yasm_sym_vis vis = yasm_symrec_get_visibility(value->rel); | 493 yasm_sym_vis vis = yasm_symrec_get_visibility(value->rel); |
487 /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel; | 494 /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel; |
488 unsigned long addr; | 495 unsigned long addr; |
489 coff_reloc *reloc; | 496 coff_reloc *reloc; |
| 497 int nobase = info->csd->flags2 & COFF_FLAG_NOBASE; |
490 | 498 |
491 /* Sometimes we want the relocation to be generated against one | 499 /* Sometimes we want the relocation to be generated against one |
492 * symbol but the value generated correspond to a different symbol. | 500 * symbol but the value generated correspond to a different symbol. |
493 * This is done through (sym being referenced) WRT (sym used for | 501 * This is done through (sym being referenced) WRT (sym used for |
494 * reloc). Note both syms need to be in the same section! | 502 * reloc). Note both syms need to be in the same section! |
495 */ | 503 */ |
496 if (value->wrt) { | 504 if (value->wrt && value->wrt == objfmt_coff->ssym_imagebase) |
| 505 nobase = 1; |
| 506 else if (value->wrt) { |
497 /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc; | 507 /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc; |
| 508 |
498 if (!yasm_symrec_get_label(sym, &rel_precbc) | 509 if (!yasm_symrec_get_label(sym, &rel_precbc) |
499 || !yasm_symrec_get_label(value->wrt, &wrt_precbc)) { | 510 || !yasm_symrec_get_label(value->wrt, &wrt_precbc)) { |
500 yasm_error_set(YASM_ERROR_TOO_COMPLEX, | 511 yasm_error_set(YASM_ERROR_TOO_COMPLEX, |
501 N_("coff: wrt expression too complex")); | 512 N_("coff: wrt expression too complex")); |
502 return 1; | 513 return 1; |
503 } | 514 } |
504 dist = yasm_calc_bc_dist(wrt_precbc, rel_precbc); | 515 dist = yasm_calc_bc_dist(wrt_precbc, rel_precbc); |
505 if (!dist) { | 516 if (!dist) { |
506 yasm_error_set(YASM_ERROR_TOO_COMPLEX, | 517 yasm_error_set(YASM_ERROR_TOO_COMPLEX, |
507 N_("coff: cannot wrt across sections")); | 518 N_("coff: cannot wrt across sections")); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 * taken care of by special relocation types. | 573 * taken care of by special relocation types. |
563 */ | 574 */ |
564 if (objfmt_coff->win64 && value->ip_rel) | 575 if (objfmt_coff->win64 && value->ip_rel) |
565 intn_val += bc->len*bc->mult_int; | 576 intn_val += bc->len*bc->mult_int; |
566 else if (objfmt_coff->win32) | 577 else if (objfmt_coff->win32) |
567 intn_val += offset+destsize; | 578 intn_val += offset+destsize; |
568 else | 579 else |
569 intn_minus = bc->offset; | 580 intn_minus = bc->offset; |
570 } | 581 } |
571 | 582 |
572 if (value->seg_of || value->section_rel) { | 583 if (value->seg_of) { |
573 /* Segment or section-relative generation; zero value. */ | 584 /* Segment generation; zero value. */ |
574 intn_val = 0; | 585 intn_val = 0; |
575 intn_minus = 0; | 586 intn_minus = 0; |
576 } | 587 } |
577 | 588 |
578 /* Generate reloc */ | 589 /* Generate reloc */ |
579 reloc = yasm_xmalloc(sizeof(coff_reloc)); | 590 reloc = yasm_xmalloc(sizeof(coff_reloc)); |
580 addr = bc->offset + offset; | 591 addr = bc->offset + offset; |
581 if (COFF_SET_VMA) | 592 if (COFF_SET_VMA) |
582 addr += info->addr; | 593 addr += info->addr; |
583 reloc->reloc.addr = yasm_intnum_create_uint(addr); | 594 reloc->reloc.addr = yasm_intnum_create_uint(addr); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 yasm_internal_error(N_("coff objfmt: unrecognized machine")); | 646 yasm_internal_error(N_("coff objfmt: unrecognized machine")); |
636 } else if (value->section_rel) { | 647 } else if (value->section_rel) { |
637 if (objfmt_coff->machine == COFF_MACHINE_I386) | 648 if (objfmt_coff->machine == COFF_MACHINE_I386) |
638 reloc->type = COFF_RELOC_I386_SECREL; | 649 reloc->type = COFF_RELOC_I386_SECREL; |
639 else if (objfmt_coff->machine == COFF_MACHINE_AMD64) | 650 else if (objfmt_coff->machine == COFF_MACHINE_AMD64) |
640 reloc->type = COFF_RELOC_AMD64_SECREL; | 651 reloc->type = COFF_RELOC_AMD64_SECREL; |
641 else | 652 else |
642 yasm_internal_error(N_("coff objfmt: unrecognized machine")); | 653 yasm_internal_error(N_("coff objfmt: unrecognized machine")); |
643 } else { | 654 } else { |
644 if (objfmt_coff->machine == COFF_MACHINE_I386) { | 655 if (objfmt_coff->machine == COFF_MACHINE_I386) { |
645 if (info->csd->flags2 & COFF_FLAG_NOBASE) | 656 if (nobase) |
646 reloc->type = COFF_RELOC_I386_ADDR32NB; | 657 reloc->type = COFF_RELOC_I386_ADDR32NB; |
647 else | 658 else |
648 reloc->type = COFF_RELOC_I386_ADDR32; | 659 reloc->type = COFF_RELOC_I386_ADDR32; |
649 } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) { | 660 } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) { |
650 if (valsize == 32) { | 661 if (valsize == 32) { |
651 if (info->csd->flags2 & COFF_FLAG_NOBASE) | 662 if (nobase) |
652 reloc->type = COFF_RELOC_AMD64_ADDR32NB; | 663 reloc->type = COFF_RELOC_AMD64_ADDR32NB; |
653 else | 664 else |
654 reloc->type = COFF_RELOC_AMD64_ADDR32; | 665 reloc->type = COFF_RELOC_AMD64_ADDR32; |
655 } else if (valsize == 64) | 666 } else if (valsize == 64) |
656 reloc->type = COFF_RELOC_AMD64_ADDR64; | 667 reloc->type = COFF_RELOC_AMD64_ADDR64; |
657 else { | 668 else { |
658 yasm_error_set(YASM_ERROR_TYPE, | 669 yasm_error_set(YASM_ERROR_TYPE, |
659 N_("coff: invalid relocation size")); | 670 N_("coff: invalid relocation size")); |
660 return 1; | 671 return 1; |
661 } | 672 } |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 data.flags = COFF_STYP_INFO; | 1516 data.flags = COFF_STYP_INFO; |
1506 if (objfmt_coff->win32) | 1517 if (objfmt_coff->win32) |
1507 data.flags |= COFF_STYP_DISCARD | COFF_STYP_READ; | 1518 data.flags |= COFF_STYP_DISCARD | COFF_STYP_READ; |
1508 } else if (objfmt_coff->win64 && strcmp(sectname, ".pdata") == 0) { | 1519 } else if (objfmt_coff->win64 && strcmp(sectname, ".pdata") == 0) { |
1509 data.flags = COFF_STYP_DATA | COFF_STYP_READ; | 1520 data.flags = COFF_STYP_DATA | COFF_STYP_READ; |
1510 align = 4; | 1521 align = 4; |
1511 data.flags2 = COFF_FLAG_NOBASE; | 1522 data.flags2 = COFF_FLAG_NOBASE; |
1512 } else if (objfmt_coff->win64 && strcmp(sectname, ".xdata") == 0) { | 1523 } else if (objfmt_coff->win64 && strcmp(sectname, ".xdata") == 0) { |
1513 data.flags = COFF_STYP_DATA | COFF_STYP_READ; | 1524 data.flags = COFF_STYP_DATA | COFF_STYP_READ; |
1514 align = 8; | 1525 align = 8; |
| 1526 data.flags2 = COFF_FLAG_NOBASE; |
1515 } else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) { | 1527 } else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) { |
1516 data.flags = COFF_STYP_INFO; | 1528 data.flags = COFF_STYP_INFO; |
1517 } else if (strcmp(sectname, ".comment") == 0) { | 1529 } else if (strcmp(sectname, ".comment") == 0) { |
1518 data.flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ; | 1530 data.flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ; |
1519 } else if (yasm__strncasecmp(sectname, ".debug", 6)==0) { | 1531 } else if (yasm__strncasecmp(sectname, ".debug", 6)==0) { |
1520 data.flags = COFF_STYP_DATA | COFF_STYP_DISCARD | COFF_STYP_READ; | 1532 data.flags = COFF_STYP_DATA | COFF_STYP_DISCARD | COFF_STYP_READ; |
1521 align = 1; | 1533 align = 1; |
1522 } else { | 1534 } else { |
1523 /* Default to code, but set a flag so if we get gasflags we can | 1535 /* Default to code, but set a flag so if we get gasflags we can |
1524 * change it (NASM and GAS have different defaults). | 1536 * change it (NASM and GAS have different defaults). |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1587 return retval; | 1599 return retval; |
1588 } | 1600 } |
1589 | 1601 |
1590 static /*@observer@*/ /*@null@*/ yasm_symrec * | 1602 static /*@observer@*/ /*@null@*/ yasm_symrec * |
1591 coff_objfmt_get_special_sym(yasm_object *object, const char *name, | 1603 coff_objfmt_get_special_sym(yasm_object *object, const char *name, |
1592 const char *parser) | 1604 const char *parser) |
1593 { | 1605 { |
1594 return NULL; | 1606 return NULL; |
1595 } | 1607 } |
1596 | 1608 |
| 1609 static /*@observer@*/ /*@null@*/ yasm_symrec * |
| 1610 win64_objfmt_get_special_sym(yasm_object *object, const char *name, |
| 1611 const char *parser) |
| 1612 { |
| 1613 if (yasm__strcasecmp(name, "imagebase") == 0) { |
| 1614 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
| 1615 return objfmt_coff->ssym_imagebase; |
| 1616 } |
| 1617 return NULL; |
| 1618 } |
| 1619 |
1597 static void | 1620 static void |
1598 coff_section_data_destroy(void *data) | 1621 coff_section_data_destroy(void *data) |
1599 { | 1622 { |
1600 yasm_xfree(data); | 1623 yasm_xfree(data); |
1601 } | 1624 } |
1602 | 1625 |
1603 static void | 1626 static void |
1604 coff_section_data_print(void *data, FILE *f, int indent_level) | 1627 coff_section_data_print(void *data, FILE *f, int indent_level) |
1605 { | 1628 { |
1606 coff_section_data *csd = (coff_section_data *)data; | 1629 coff_section_data *csd = (coff_section_data *)data; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 | 1774 |
1752 static int | 1775 static int |
1753 win32_sxdata_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, | 1776 win32_sxdata_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, |
1754 void *add_span_data) | 1777 void *add_span_data) |
1755 { | 1778 { |
1756 bc->len += 4; | 1779 bc->len += 4; |
1757 return 0; | 1780 return 0; |
1758 } | 1781 } |
1759 | 1782 |
1760 static int | 1783 static int |
1761 win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 1784 win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 1785 unsigned char *bufstart, void *d, |
1762 yasm_output_value_func output_value, | 1786 yasm_output_value_func output_value, |
1763 yasm_output_reloc_func output_reloc) | 1787 yasm_output_reloc_func output_reloc) |
1764 { | 1788 { |
1765 yasm_symrec *sym = (yasm_symrec *)bc->contents; | 1789 yasm_symrec *sym = (yasm_symrec *)bc->contents; |
1766 unsigned char *buf = *bufp; | 1790 unsigned char *buf = *bufp; |
1767 coff_symrec_data *csymd; | 1791 coff_symrec_data *csymd; |
1768 | 1792 |
1769 csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb); | 1793 csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb); |
1770 if (!csymd) | 1794 if (!csymd) |
1771 yasm_internal_error(N_("coff: no symbol data for SAFESEH symbol")); | 1795 yasm_internal_error(N_("coff: no symbol data for SAFESEH symbol")); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 } | 1857 } |
1834 yasm_dvs_append(&dvs, | 1858 yasm_dvs_append(&dvs, |
1835 yasm_dv_create_string(yasm__xstrdup(s), strlen(s))); | 1859 yasm_dv_create_string(yasm__xstrdup(s), strlen(s))); |
1836 } while ((vp = yasm_vps_next(vp))); | 1860 } while ((vp = yasm_vps_next(vp))); |
1837 | 1861 |
1838 yasm_section_bcs_append(comment, | 1862 yasm_section_bcs_append(comment, |
1839 yasm_bc_create_data(&dvs, 1, 1, object->arch, line)); | 1863 yasm_bc_create_data(&dvs, 1, 1, object->arch, line)); |
1840 } | 1864 } |
1841 | 1865 |
1842 static void | 1866 static void |
| 1867 dir_secrel32(yasm_object *object, yasm_valparamhead *valparams, |
| 1868 yasm_valparamhead *objext_valparams, unsigned long line) |
| 1869 { |
| 1870 yasm_datavalhead dvs; |
| 1871 yasm_valparam *vp; |
| 1872 |
| 1873 if (!object->cur_section) { |
| 1874 yasm_error_set(YASM_ERROR_SYNTAX, |
| 1875 N_(".secrel32 can only be used inside of a section")); |
| 1876 return; |
| 1877 } |
| 1878 |
| 1879 vp = yasm_vps_first(valparams); |
| 1880 yasm_dvs_initialize(&dvs); |
| 1881 do { |
| 1882 yasm_expr *e = yasm_vp_expr(vp, object->symtab, line); |
| 1883 yasm_dataval *dv; |
| 1884 if (!e) { |
| 1885 yasm_error_set(YASM_ERROR_VALUE, |
| 1886 N_(".secrel32 requires expressions")); |
| 1887 yasm_dvs_delete(&dvs); |
| 1888 return; |
| 1889 } |
| 1890 dv = yasm_dv_create_expr(e); |
| 1891 yasm_dv_get_value(dv)->section_rel = 1; |
| 1892 yasm_dvs_append(&dvs, dv); |
| 1893 } while ((vp = yasm_vps_next(vp))); |
| 1894 |
| 1895 yasm_section_bcs_append(object->cur_section, |
| 1896 yasm_bc_create_data(&dvs, 4, 0, object->arch, line)); |
| 1897 } |
| 1898 |
| 1899 static void |
| 1900 dir_def(yasm_object *object, yasm_valparamhead *valparams, |
| 1901 yasm_valparamhead *objext_valparams, unsigned long line) |
| 1902 { |
| 1903 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
| 1904 yasm_valparam *vp; |
| 1905 const char *symname; |
| 1906 yasm_symrec *sym; |
| 1907 coff_symrec_data *sym_data; |
| 1908 |
| 1909 if (objfmt_coff->def_sym) { |
| 1910 yasm_warn_set(YASM_WARN_GENERAL, |
| 1911 N_(".def pseudo-op used inside of .def/.endef; ignored")); |
| 1912 return; |
| 1913 } |
| 1914 |
| 1915 vp = yasm_vps_first(valparams); |
| 1916 symname = yasm_vp_id(vp); |
| 1917 if (!symname) { |
| 1918 yasm_error_set(YASM_ERROR_SYNTAX, |
| 1919 N_("argument to SAFESEH must be symbol name")); |
| 1920 return; |
| 1921 } |
| 1922 |
| 1923 sym = yasm_symtab_use(object->symtab, symname, line); |
| 1924 sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb); |
| 1925 if (!sym_data) { |
| 1926 sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0, |
| 1927 COFF_SYMTAB_AUX_NONE); |
| 1928 } |
| 1929 objfmt_coff->def_sym = sym_data; |
| 1930 } |
| 1931 |
| 1932 static void |
| 1933 dir_scl(yasm_object *object, yasm_valparamhead *valparams, |
| 1934 yasm_valparamhead *objext_valparams, unsigned long line) |
| 1935 { |
| 1936 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
| 1937 yasm_intnum *intn = NULL; |
| 1938 |
| 1939 if (!objfmt_coff->def_sym) { |
| 1940 yasm_warn_set(YASM_WARN_GENERAL, |
| 1941 N_("%s pseudo-op used outside of .def/.endef; ignored"), |
| 1942 ".scl"); |
| 1943 return; |
| 1944 } |
| 1945 |
| 1946 if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line, |
| 1947 &intn, 0) < 0) |
| 1948 return; |
| 1949 if (!intn) |
| 1950 return; |
| 1951 objfmt_coff->def_sym->sclass = yasm_intnum_get_uint(intn); |
| 1952 yasm_intnum_destroy(intn); |
| 1953 } |
| 1954 |
| 1955 static void |
| 1956 dir_type(yasm_object *object, yasm_valparamhead *valparams, |
| 1957 yasm_valparamhead *objext_valparams, unsigned long line) |
| 1958 { |
| 1959 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
| 1960 yasm_intnum *intn = NULL; |
| 1961 |
| 1962 if (!objfmt_coff->def_sym) { |
| 1963 yasm_warn_set(YASM_WARN_GENERAL, |
| 1964 N_("%s pseudo-op used outside of .def/.endef; ignored"), |
| 1965 ".type"); |
| 1966 return; |
| 1967 } |
| 1968 |
| 1969 if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line, |
| 1970 &intn, 0) < 0) |
| 1971 return; |
| 1972 if (!intn) |
| 1973 return; |
| 1974 objfmt_coff->def_sym->type = yasm_intnum_get_uint(intn); |
| 1975 yasm_intnum_destroy(intn); |
| 1976 } |
| 1977 |
| 1978 static void |
| 1979 dir_endef(yasm_object *object, yasm_valparamhead *valparams, |
| 1980 yasm_valparamhead *objext_valparams, unsigned long line) |
| 1981 { |
| 1982 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
| 1983 if (!objfmt_coff->def_sym) { |
| 1984 yasm_warn_set(YASM_WARN_GENERAL, |
| 1985 N_(".endef pseudo-op used before .def; ignored")); |
| 1986 return; |
| 1987 } |
| 1988 objfmt_coff->def_sym = NULL; |
| 1989 } |
| 1990 |
| 1991 static void |
1843 dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams, | 1992 dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams, |
1844 yasm_valparamhead *objext_valparams, unsigned long line) | 1993 yasm_valparamhead *objext_valparams, unsigned long line) |
1845 { | 1994 { |
1846 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; | 1995 yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt; |
1847 yasm_valparam *vp = yasm_vps_first(valparams); | 1996 yasm_valparam *vp = yasm_vps_first(valparams); |
1848 const char *name = yasm_vp_id(vp); | 1997 const char *name = yasm_vp_id(vp); |
1849 | 1998 |
1850 if (objfmt_coff->proc_frame) { | 1999 if (objfmt_coff->proc_frame) { |
1851 yasm_error_set_xref(objfmt_coff->proc_frame, | 2000 yasm_error_set_xref(objfmt_coff->proc_frame, |
1852 N_("previous procedure started here")); | 2001 N_("previous procedure started here")); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2187 /* Define valid debug formats to use with this object format */ | 2336 /* Define valid debug formats to use with this object format */ |
2188 static const char *coff_objfmt_dbgfmt_keywords[] = { | 2337 static const char *coff_objfmt_dbgfmt_keywords[] = { |
2189 "null", | 2338 "null", |
2190 "dwarf2", | 2339 "dwarf2", |
2191 NULL | 2340 NULL |
2192 }; | 2341 }; |
2193 | 2342 |
2194 static const yasm_directive coff_objfmt_directives[] = { | 2343 static const yasm_directive coff_objfmt_directives[] = { |
2195 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, | 2344 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, |
2196 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, | 2345 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, |
| 2346 { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED }, |
| 2347 { ".endef", "gas", dir_endef, YASM_DIR_ANY }, |
| 2348 { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED }, |
| 2349 { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED }, |
| 2350 { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED }, |
2197 { NULL, NULL, NULL, 0 } | 2351 { NULL, NULL, NULL, 0 } |
2198 }; | 2352 }; |
2199 | 2353 |
2200 /* Define objfmt structure -- see objfmt.h for details */ | 2354 /* Define objfmt structure -- see objfmt.h for details */ |
2201 yasm_objfmt_module yasm_coff_LTX_objfmt = { | 2355 yasm_objfmt_module yasm_coff_LTX_objfmt = { |
2202 "COFF (DJGPP)", | 2356 "COFF (DJGPP)", |
2203 "coff", | 2357 "coff", |
2204 "o", | 2358 "o", |
2205 32, | 2359 32, |
2206 0, | 2360 0, |
(...skipping 14 matching lines...) Expand all Loading... |
2221 static const char *winXX_objfmt_dbgfmt_keywords[] = { | 2375 static const char *winXX_objfmt_dbgfmt_keywords[] = { |
2222 "null", | 2376 "null", |
2223 "dwarf2", | 2377 "dwarf2", |
2224 "cv8", | 2378 "cv8", |
2225 NULL | 2379 NULL |
2226 }; | 2380 }; |
2227 | 2381 |
2228 static const yasm_directive win32_objfmt_directives[] = { | 2382 static const yasm_directive win32_objfmt_directives[] = { |
2229 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, | 2383 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, |
2230 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, | 2384 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, |
| 2385 { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED }, |
| 2386 { ".endef", "gas", dir_endef, YASM_DIR_ANY }, |
| 2387 { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED }, |
| 2388 { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED }, |
| 2389 { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED }, |
2231 { ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED }, | 2390 { ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED }, |
2232 { "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED }, | 2391 { "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED }, |
2233 { ".safeseh", "gas", dir_safeseh, YASM_DIR_ID_REQUIRED }, | 2392 { ".safeseh", "gas", dir_safeseh, YASM_DIR_ID_REQUIRED }, |
2234 { "safeseh", "nasm", dir_safeseh, YASM_DIR_ID_REQUIRED }, | 2393 { "safeseh", "nasm", dir_safeseh, YASM_DIR_ID_REQUIRED }, |
2235 { NULL, NULL, NULL, 0 } | 2394 { NULL, NULL, NULL, 0 } |
2236 }; | 2395 }; |
2237 | 2396 |
2238 static const char *win32_nasm_stdmac[] = { | 2397 static const char *win32_nasm_stdmac[] = { |
2239 "%imacro export 1+.nolist", | 2398 "%imacro export 1+.nolist", |
2240 "[export %1]", | 2399 "[export %1]", |
(...skipping 25 matching lines...) Expand all Loading... |
2266 coff_objfmt_destroy, | 2425 coff_objfmt_destroy, |
2267 coff_objfmt_add_default_section, | 2426 coff_objfmt_add_default_section, |
2268 coff_objfmt_init_new_section, | 2427 coff_objfmt_init_new_section, |
2269 coff_objfmt_section_switch, | 2428 coff_objfmt_section_switch, |
2270 coff_objfmt_get_special_sym | 2429 coff_objfmt_get_special_sym |
2271 }; | 2430 }; |
2272 | 2431 |
2273 static const yasm_directive win64_objfmt_directives[] = { | 2432 static const yasm_directive win64_objfmt_directives[] = { |
2274 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, | 2433 { ".ident", "gas", dir_ident, YASM_DIR_ANY }, |
2275 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, | 2434 { "ident", "nasm", dir_ident, YASM_DIR_ANY }, |
| 2435 { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED }, |
| 2436 { ".endef", "gas", dir_endef, YASM_DIR_ANY }, |
| 2437 { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED }, |
| 2438 { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED }, |
| 2439 { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED }, |
2276 { ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED }, | 2440 { ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED }, |
2277 { "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED }, | 2441 { "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED }, |
2278 { ".proc_frame", "gas", dir_proc_frame, YASM_DIR_ID_REQUIRED }, | 2442 { ".proc_frame", "gas", dir_proc_frame, YASM_DIR_ID_REQUIRED }, |
2279 { "proc_frame", "nasm", dir_proc_frame, YASM_DIR_ID_REQUIRED }, | 2443 { "proc_frame", "nasm", dir_proc_frame, YASM_DIR_ID_REQUIRED }, |
2280 { ".pushreg", "gas", dir_pushreg, YASM_DIR_ARG_REQUIRED }, | 2444 { ".pushreg", "gas", dir_pushreg, YASM_DIR_ARG_REQUIRED }, |
2281 { "pushreg", "nasm", dir_pushreg, YASM_DIR_ARG_REQUIRED }, | 2445 { "pushreg", "nasm", dir_pushreg, YASM_DIR_ARG_REQUIRED }, |
2282 { ".setframe", "gas", dir_setframe, YASM_DIR_ARG_REQUIRED }, | 2446 { ".setframe", "gas", dir_setframe, YASM_DIR_ARG_REQUIRED }, |
2283 { "setframe", "nasm", dir_setframe, YASM_DIR_ARG_REQUIRED }, | 2447 { "setframe", "nasm", dir_setframe, YASM_DIR_ARG_REQUIRED }, |
2284 { ".allocstack", "gas", dir_allocstack, YASM_DIR_ARG_REQUIRED }, | 2448 { ".allocstack", "gas", dir_allocstack, YASM_DIR_ARG_REQUIRED }, |
2285 { "allocstack", "nasm", dir_allocstack, YASM_DIR_ARG_REQUIRED }, | 2449 { "allocstack", "nasm", dir_allocstack, YASM_DIR_ARG_REQUIRED }, |
(...skipping 29 matching lines...) Expand all Loading... |
2315 winXX_objfmt_dbgfmt_keywords, | 2479 winXX_objfmt_dbgfmt_keywords, |
2316 "null", | 2480 "null", |
2317 win64_objfmt_directives, | 2481 win64_objfmt_directives, |
2318 win64_objfmt_stdmacs, | 2482 win64_objfmt_stdmacs, |
2319 win64_objfmt_create, | 2483 win64_objfmt_create, |
2320 coff_objfmt_output, | 2484 coff_objfmt_output, |
2321 coff_objfmt_destroy, | 2485 coff_objfmt_destroy, |
2322 coff_objfmt_add_default_section, | 2486 coff_objfmt_add_default_section, |
2323 coff_objfmt_init_new_section, | 2487 coff_objfmt_init_new_section, |
2324 coff_objfmt_section_switch, | 2488 coff_objfmt_section_switch, |
2325 coff_objfmt_get_special_sym | 2489 win64_objfmt_get_special_sym |
2326 }; | 2490 }; |
2327 yasm_objfmt_module yasm_x64_LTX_objfmt = { | 2491 yasm_objfmt_module yasm_x64_LTX_objfmt = { |
2328 "Win64", | 2492 "Win64", |
2329 "x64", | 2493 "x64", |
2330 "obj", | 2494 "obj", |
2331 64, | 2495 64, |
2332 1, | 2496 1, |
2333 winXX_objfmt_dbgfmt_keywords, | 2497 winXX_objfmt_dbgfmt_keywords, |
2334 "null", | 2498 "null", |
2335 win64_objfmt_directives, | 2499 win64_objfmt_directives, |
2336 win64_objfmt_stdmacs, | 2500 win64_objfmt_stdmacs, |
2337 win64_objfmt_create, | 2501 win64_objfmt_create, |
2338 coff_objfmt_output, | 2502 coff_objfmt_output, |
2339 coff_objfmt_destroy, | 2503 coff_objfmt_destroy, |
2340 coff_objfmt_add_default_section, | 2504 coff_objfmt_add_default_section, |
2341 coff_objfmt_init_new_section, | 2505 coff_objfmt_init_new_section, |
2342 coff_objfmt_section_switch, | 2506 coff_objfmt_section_switch, |
2343 coff_objfmt_get_special_sym | 2507 win64_objfmt_get_special_sym |
2344 }; | 2508 }; |
OLD | NEW |