OLD | NEW |
1 /* | 1 /* |
2 * Flat-format binary object format | 2 * Flat-format binary 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 /*@unused@*/ RCSID("$Id: bin-objfmt.c 2166 2009-01-02 08:33:21Z peter $"); | 28 /*@unused@*/ RCSID("$Id: bin-objfmt.c 2310 2010-03-28 19:28:54Z peter $"); |
29 | 29 |
30 #ifdef HAVE_UNISTD_H | 30 #ifdef HAVE_UNISTD_H |
31 #include <unistd.h> | 31 #include <unistd.h> |
32 #endif | 32 #endif |
33 #include <libyasm.h> | 33 #include <libyasm.h> |
34 | 34 |
35 | 35 |
36 #define REGULAR_OUTBUF_SIZE 1024 | 36 #define REGULAR_OUTBUF_SIZE 1024 |
37 | 37 |
38 typedef struct bin_section_data { | 38 typedef struct bin_section_data { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 yasm_objfmt_bin *objfmt_bin = yasm_xmalloc(sizeof(yasm_objfmt_bin)); | 106 yasm_objfmt_bin *objfmt_bin = yasm_xmalloc(sizeof(yasm_objfmt_bin)); |
107 objfmt_bin->objfmt.module = &yasm_bin_LTX_objfmt; | 107 objfmt_bin->objfmt.module = &yasm_bin_LTX_objfmt; |
108 | 108 |
109 objfmt_bin->map_flags = NO_MAP; | 109 objfmt_bin->map_flags = NO_MAP; |
110 objfmt_bin->map_filename = NULL; | 110 objfmt_bin->map_filename = NULL; |
111 objfmt_bin->org = NULL; | 111 objfmt_bin->org = NULL; |
112 | 112 |
113 return (yasm_objfmt *)objfmt_bin; | 113 return (yasm_objfmt *)objfmt_bin; |
114 } | 114 } |
115 | 115 |
116 typedef TAILQ_HEAD(, bin_group) bin_groups; | 116 typedef TAILQ_HEAD(bin_group_head, bin_group) bin_groups; |
117 | 117 |
118 typedef struct bin_group { | 118 typedef struct bin_group { |
119 TAILQ_ENTRY(bin_group) link; | 119 TAILQ_ENTRY(bin_group) link; |
120 yasm_section *section; | 120 yasm_section *section; |
121 bin_section_data *bsd; | 121 bin_section_data *bsd; |
122 | 122 |
123 /* Groups that (in parallel) logically come immediately after this | 123 /* Groups that (in parallel) logically come immediately after this |
124 * group's section. | 124 * group's section. |
125 */ | 125 */ |
126 bin_groups follow_groups; | 126 bin_groups follow_groups; |
(...skipping 24 matching lines...) Expand all Loading... |
151 if (group->section == section) | 151 if (group->section == section) |
152 return group; | 152 return group; |
153 /* Recurse to loop through follow groups */ | 153 /* Recurse to loop through follow groups */ |
154 found = find_group_by_section(&group->follow_groups, section); | 154 found = find_group_by_section(&group->follow_groups, section); |
155 if (found) | 155 if (found) |
156 return found; | 156 return found; |
157 } | 157 } |
158 return NULL; | 158 return NULL; |
159 } | 159 } |
160 | 160 |
| 161 #if 0 |
| 162 /* Debugging function */ |
161 static void | 163 static void |
162 print_groups(const bin_groups *groups, int indent_level) | 164 print_groups(const bin_groups *groups, int indent_level) |
163 { | 165 { |
164 bin_group *group; | 166 bin_group *group; |
165 TAILQ_FOREACH(group, groups, link) { | 167 TAILQ_FOREACH(group, groups, link) { |
166 printf("%*sSection `%s':\n", indent_level, "", | 168 printf("%*sSection `%s':\n", indent_level, "", |
167 yasm_section_get_name(group->section)); | 169 yasm_section_get_name(group->section)); |
168 bin_section_data_print(group->bsd, stdout, indent_level+1); | 170 bin_section_data_print(group->bsd, stdout, indent_level+1); |
169 if (!TAILQ_EMPTY(&group->follow_groups)) { | 171 if (!TAILQ_EMPTY(&group->follow_groups)) { |
170 printf("%*sFollowing groups:\n", indent_level, ""); | 172 printf("%*sFollowing groups:\n", indent_level, ""); |
171 print_groups(&group->follow_groups, indent_level+1); | 173 print_groups(&group->follow_groups, indent_level+1); |
172 } | 174 } |
173 } | 175 } |
174 } | 176 } |
| 177 #endif |
175 | 178 |
176 static void | 179 static void |
177 bin_group_destroy(/*@only@*/ bin_group *group) | 180 bin_group_destroy(/*@only@*/ bin_group *group) |
178 { | 181 { |
179 bin_group *follow, *group_temp; | 182 bin_group *follow, *group_temp; |
180 TAILQ_FOREACH_SAFE(follow, &group->follow_groups, link, group_temp) | 183 TAILQ_FOREACH_SAFE(follow, &group->follow_groups, link, group_temp) |
181 bin_group_destroy(follow); | 184 bin_group_destroy(follow); |
182 yasm_xfree(group); | 185 yasm_xfree(group); |
183 } | 186 } |
184 | 187 |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 strcat(symname, suffix); | 1381 strcat(symname, suffix); |
1379 | 1382 |
1380 bsymd->section = sect; | 1383 bsymd->section = sect; |
1381 bsymd->which = which; | 1384 bsymd->which = which; |
1382 | 1385 |
1383 sym = yasm_symtab_declare(symtab, symname, YASM_SYM_EXTERN, line); | 1386 sym = yasm_symtab_declare(symtab, symname, YASM_SYM_EXTERN, line); |
1384 yasm_xfree(symname); | 1387 yasm_xfree(symname); |
1385 yasm_symrec_add_data(sym, &bin_symrec_data_cb, bsymd); | 1388 yasm_symrec_add_data(sym, &bin_symrec_data_cb, bsymd); |
1386 } | 1389 } |
1387 | 1390 |
1388 static bin_section_data * | 1391 static void |
1389 bin_objfmt_init_new_section(yasm_object *object, yasm_section *sect, | 1392 bin_objfmt_init_new_section(yasm_section *sect, unsigned long line) |
1390 const char *sectname, unsigned long line) | |
1391 { | 1393 { |
| 1394 yasm_object *object = yasm_section_get_object(sect); |
| 1395 const char *sectname = yasm_section_get_name(sect); |
1392 /*yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;*/ | 1396 /*yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;*/ |
1393 bin_section_data *data; | 1397 bin_section_data *data; |
1394 | 1398 |
1395 data = yasm_xmalloc(sizeof(bin_section_data)); | 1399 data = yasm_xmalloc(sizeof(bin_section_data)); |
1396 data->bss = 0; | 1400 data->bss = 0; |
1397 data->align = NULL; | 1401 data->align = NULL; |
1398 data->valign = NULL; | 1402 data->valign = NULL; |
1399 data->start = NULL; | 1403 data->start = NULL; |
1400 data->vstart = NULL; | 1404 data->vstart = NULL; |
1401 data->follows = NULL; | 1405 data->follows = NULL; |
1402 data->vfollows = NULL; | 1406 data->vfollows = NULL; |
1403 data->istart = NULL; | 1407 data->istart = NULL; |
1404 data->ivstart = NULL; | 1408 data->ivstart = NULL; |
1405 data->length = NULL; | 1409 data->length = NULL; |
1406 yasm_section_add_data(sect, &bin_section_data_cb, data); | 1410 yasm_section_add_data(sect, &bin_section_data_cb, data); |
1407 | 1411 |
1408 define_section_symbol(object->symtab, sect, sectname, ".start", | 1412 define_section_symbol(object->symtab, sect, sectname, ".start", |
1409 SSYM_START, line); | 1413 SSYM_START, line); |
1410 define_section_symbol(object->symtab, sect, sectname, ".vstart", | 1414 define_section_symbol(object->symtab, sect, sectname, ".vstart", |
1411 SSYM_VSTART, line); | 1415 SSYM_VSTART, line); |
1412 define_section_symbol(object->symtab, sect, sectname, ".length", | 1416 define_section_symbol(object->symtab, sect, sectname, ".length", |
1413 SSYM_LENGTH, line); | 1417 SSYM_LENGTH, line); |
1414 | |
1415 return data; | |
1416 } | 1418 } |
1417 | 1419 |
1418 static yasm_section * | 1420 static yasm_section * |
1419 bin_objfmt_add_default_section(yasm_object *object) | 1421 bin_objfmt_add_default_section(yasm_object *object) |
1420 { | 1422 { |
1421 yasm_section *retval; | 1423 yasm_section *retval; |
1422 int isnew; | 1424 int isnew; |
1423 | 1425 |
1424 retval = yasm_object_get_general(object, ".text", 0, 1, 0, &isnew, 0); | 1426 retval = yasm_object_get_general(object, ".text", 0, 1, 0, &isnew, 0); |
1425 if (isnew) { | 1427 if (isnew) |
1426 bin_objfmt_init_new_section(object, retval, ".text", 0); | |
1427 yasm_section_set_default(retval, 1); | 1428 yasm_section_set_default(retval, 1); |
1428 } | |
1429 return retval; | 1429 return retval; |
1430 } | 1430 } |
1431 | 1431 |
| 1432 /* GAS-style flags */ |
| 1433 static int |
| 1434 bin_helper_gasflags(void *obj, yasm_valparam *vp, unsigned long line, void *d, |
| 1435 /*@unused@*/ uintptr_t arg) |
| 1436 { |
| 1437 /* TODO */ |
| 1438 return 0; |
| 1439 } |
| 1440 |
1432 static /*@observer@*/ /*@null@*/ yasm_section * | 1441 static /*@observer@*/ /*@null@*/ yasm_section * |
1433 bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, | 1442 bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, |
1434 /*@unused@*/ /*@null@*/ | 1443 /*@unused@*/ /*@null@*/ |
1435 yasm_valparamhead *objext_valparams, | 1444 yasm_valparamhead *objext_valparams, |
1436 unsigned long line) | 1445 unsigned long line) |
1437 { | 1446 { |
1438 yasm_valparam *vp; | 1447 yasm_valparam *vp; |
1439 yasm_section *retval; | 1448 yasm_section *retval; |
1440 int isnew; | 1449 int isnew; |
1441 int flags_override = 0; | 1450 int flags_override = 0; |
(...skipping 28 matching lines...) Expand all Loading... |
1470 offsetof(struct bin_section_switch_data, bss), 1 }, | 1479 offsetof(struct bin_section_switch_data, bss), 1 }, |
1471 { "progbits", 0, yasm_dir_helper_flag_set, | 1480 { "progbits", 0, yasm_dir_helper_flag_set, |
1472 offsetof(struct bin_section_switch_data, bss), 0 }, | 1481 offsetof(struct bin_section_switch_data, bss), 0 }, |
1473 { "code", 0, yasm_dir_helper_flag_set, | 1482 { "code", 0, yasm_dir_helper_flag_set, |
1474 offsetof(struct bin_section_switch_data, code), 1 }, | 1483 offsetof(struct bin_section_switch_data, code), 1 }, |
1475 { "data", 0, yasm_dir_helper_flag_set, | 1484 { "data", 0, yasm_dir_helper_flag_set, |
1476 offsetof(struct bin_section_switch_data, code), 0 }, | 1485 offsetof(struct bin_section_switch_data, code), 0 }, |
1477 { "execute", 0, yasm_dir_helper_flag_set, | 1486 { "execute", 0, yasm_dir_helper_flag_set, |
1478 offsetof(struct bin_section_switch_data, code), 1 }, | 1487 offsetof(struct bin_section_switch_data, code), 1 }, |
1479 { "noexecute", 0, yasm_dir_helper_flag_set, | 1488 { "noexecute", 0, yasm_dir_helper_flag_set, |
1480 offsetof(struct bin_section_switch_data, code), 0 } | 1489 offsetof(struct bin_section_switch_data, code), 0 }, |
| 1490 { "gasflags", 1, bin_helper_gasflags, 0, 0 } |
1481 }; | 1491 }; |
1482 | 1492 |
1483 vp = yasm_vps_first(valparams); | 1493 vp = yasm_vps_first(valparams); |
1484 sectname = yasm_vp_string(vp); | 1494 sectname = yasm_vp_string(vp); |
1485 if (!sectname) | 1495 if (!sectname) |
1486 return NULL; | 1496 return NULL; |
1487 vp = yasm_vps_next(vp); | 1497 vp = yasm_vps_next(vp); |
1488 | 1498 |
1489 retval = yasm_object_find_general(object, sectname); | 1499 retval = yasm_object_find_general(object, sectname); |
1490 if (retval) { | 1500 if (retval) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 N_("argument to `%s' is not a power of two"), | 1558 N_("argument to `%s' is not a power of two"), |
1549 "valign"); | 1559 "valign"); |
1550 return NULL; | 1560 return NULL; |
1551 } | 1561 } |
1552 } else | 1562 } else |
1553 data.valign = bsd ? bsd->valign : NULL; | 1563 data.valign = bsd ? bsd->valign : NULL; |
1554 | 1564 |
1555 retval = yasm_object_get_general(object, sectname, 0, (int)data.code, | 1565 retval = yasm_object_get_general(object, sectname, 0, (int)data.code, |
1556 (int)data.bss, &isnew, line); | 1566 (int)data.bss, &isnew, line); |
1557 | 1567 |
1558 if (isnew) | 1568 bsd = yasm_section_get_data(retval, &bin_section_data_cb); |
1559 bsd = bin_objfmt_init_new_section(object, retval, sectname, line); | |
1560 else | |
1561 bsd = yasm_section_get_data(retval, &bin_section_data_cb); | |
1562 | 1569 |
1563 if (isnew || yasm_section_is_default(retval)) { | 1570 if (isnew || yasm_section_is_default(retval)) { |
1564 yasm_section_set_default(retval, 0); | 1571 yasm_section_set_default(retval, 0); |
1565 } | 1572 } |
1566 | 1573 |
1567 /* Update section flags */ | 1574 /* Update section flags */ |
1568 bsd->bss = data.bss; | 1575 bsd->bss = data.bss; |
1569 bsd->align = data.align; | 1576 bsd->align = data.align; |
1570 bsd->valign = data.valign; | 1577 bsd->valign = data.valign; |
1571 bsd->start = data.start; | 1578 bsd->start = data.start; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1800 16, | 1807 16, |
1801 0, | 1808 0, |
1802 bin_objfmt_dbgfmt_keywords, | 1809 bin_objfmt_dbgfmt_keywords, |
1803 "null", | 1810 "null", |
1804 bin_objfmt_directives, | 1811 bin_objfmt_directives, |
1805 bin_objfmt_stdmacs, | 1812 bin_objfmt_stdmacs, |
1806 bin_objfmt_create, | 1813 bin_objfmt_create, |
1807 bin_objfmt_output, | 1814 bin_objfmt_output, |
1808 bin_objfmt_destroy, | 1815 bin_objfmt_destroy, |
1809 bin_objfmt_add_default_section, | 1816 bin_objfmt_add_default_section, |
| 1817 bin_objfmt_init_new_section, |
1810 bin_objfmt_section_switch, | 1818 bin_objfmt_section_switch, |
1811 bin_objfmt_get_special_sym | 1819 bin_objfmt_get_special_sym |
1812 }; | 1820 }; |
1813 | 1821 |
1814 #define EXE_HEADER_SIZE 0x200 | 1822 #define EXE_HEADER_SIZE 0x200 |
1815 | 1823 |
1816 /* DOS .EXE binaries are just raw binaries with a header */ | 1824 /* DOS .EXE binaries are just raw binaries with a header */ |
1817 yasm_objfmt_module yasm_dosexe_LTX_objfmt; | 1825 yasm_objfmt_module yasm_dosexe_LTX_objfmt; |
1818 | 1826 |
1819 static yasm_objfmt * | 1827 static yasm_objfmt * |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 16, | 1960 16, |
1953 0, | 1961 0, |
1954 bin_objfmt_dbgfmt_keywords, | 1962 bin_objfmt_dbgfmt_keywords, |
1955 "null", | 1963 "null", |
1956 bin_objfmt_directives, | 1964 bin_objfmt_directives, |
1957 bin_objfmt_stdmacs, | 1965 bin_objfmt_stdmacs, |
1958 dosexe_objfmt_create, | 1966 dosexe_objfmt_create, |
1959 dosexe_objfmt_output, | 1967 dosexe_objfmt_output, |
1960 bin_objfmt_destroy, | 1968 bin_objfmt_destroy, |
1961 bin_objfmt_add_default_section, | 1969 bin_objfmt_add_default_section, |
| 1970 bin_objfmt_init_new_section, |
1962 bin_objfmt_section_switch, | 1971 bin_objfmt_section_switch, |
1963 bin_objfmt_get_special_sym | 1972 bin_objfmt_get_special_sym |
1964 }; | 1973 }; |
OLD | NEW |