OLD | NEW |
1 /* | 1 /* |
2 * ELF object format helpers | 2 * ELF object format helpers |
3 * | 3 * |
4 * Copyright (C) 2003-2007 Michael Urman | 4 * Copyright (C) 2003-2007 Michael Urman |
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 | 27 |
28 #include <util.h> | 28 #include <util.h> |
29 /*@unused@*/ RCSID("$Id: elf.c 2040 2008-02-21 08:57:23Z peter $"); | 29 /*@unused@*/ RCSID("$Id: elf.c 2206 2009-07-21 06:48:42Z peter $"); |
30 | 30 |
31 #include <libyasm.h> | 31 #include <libyasm.h> |
32 #define YASM_OBJFMT_ELF_INTERNAL | 32 #define YASM_OBJFMT_ELF_INTERNAL |
33 #include "elf.h" | 33 #include "elf.h" |
34 #include "elf-machine.h" | 34 #include "elf-machine.h" |
35 | 35 |
36 static void elf_section_data_destroy(void *data); | 36 static void elf_section_data_destroy(void *data); |
37 static void elf_secthead_print(void *data, FILE *f, int indent_level); | 37 static void elf_secthead_print(void *data, FILE *f, int indent_level); |
38 | 38 |
39 const yasm_assoc_data_callback elf_section_data = { | 39 const yasm_assoc_data_callback elf_section_data = { |
40 elf_section_data_destroy, | 40 elf_section_data_destroy, |
41 elf_secthead_print | 41 elf_secthead_print |
42 }; | 42 }; |
43 | 43 |
44 static void elf_symrec_data_destroy(/*@only@*/ void *d); | 44 static void elf_symrec_data_destroy(/*@only@*/ void *d); |
45 static void elf_symtab_entry_print(void *data, FILE *f, int indent_level); | 45 static void elf_symtab_entry_print(void *data, FILE *f, int indent_level); |
| 46 static void elf_ssym_symtab_entry_print(void *data, FILE *f, int indent_level); |
46 | 47 |
47 const yasm_assoc_data_callback elf_symrec_data = { | 48 const yasm_assoc_data_callback elf_symrec_data = { |
48 elf_symrec_data_destroy, | 49 elf_symrec_data_destroy, |
49 elf_symtab_entry_print | 50 elf_symtab_entry_print |
50 }; | 51 }; |
51 | 52 |
| 53 const yasm_assoc_data_callback elf_ssym_symrec_data = { |
| 54 elf_symrec_data_destroy, |
| 55 elf_ssym_symtab_entry_print |
| 56 }; |
| 57 |
52 extern elf_machine_handler | 58 extern elf_machine_handler |
53 elf_machine_handler_x86_x86, | 59 elf_machine_handler_x86_x86, |
54 elf_machine_handler_x86_amd64; | 60 elf_machine_handler_x86_amd64; |
55 | 61 |
56 static const elf_machine_handler *elf_machine_handlers[] = | 62 static const elf_machine_handler *elf_machine_handlers[] = |
57 { | 63 { |
58 &elf_machine_handler_x86_x86, | 64 &elf_machine_handler_x86_x86, |
59 &elf_machine_handler_x86_amd64, | 65 &elf_machine_handler_x86_amd64, |
60 NULL | 66 NULL |
61 }; | 67 }; |
(...skipping 23 matching lines...) Expand all Loading... |
85 { | 91 { |
86 /* Allocate "special" syms */ | 92 /* Allocate "special" syms */ |
87 elf_ssyms = | 93 elf_ssyms = |
88 yasm_xmalloc(elf_march->num_ssyms * sizeof(yasm_symrec *)); | 94 yasm_xmalloc(elf_march->num_ssyms * sizeof(yasm_symrec *)); |
89 for (i=0; (unsigned int)i<elf_march->num_ssyms; i++) | 95 for (i=0; (unsigned int)i<elf_march->num_ssyms; i++) |
90 { | 96 { |
91 /* FIXME: misuse of NULL bytecode */ | 97 /* FIXME: misuse of NULL bytecode */ |
92 elf_ssyms[i] = yasm_symtab_define_label(symtab, | 98 elf_ssyms[i] = yasm_symtab_define_label(symtab, |
93 elf_march->ssyms[i].name, | 99 elf_march->ssyms[i].name, |
94 NULL, 0, 0); | 100 NULL, 0, 0); |
| 101 yasm_symrec_add_data(elf_ssyms[i], &elf_ssym_symrec_data, |
| 102 &elf_march->ssyms[i]); |
95 } | 103 } |
96 } | 104 } |
97 | 105 |
98 return elf_march; | 106 return elf_march; |
99 } | 107 } |
100 | 108 |
101 yasm_symrec * | 109 yasm_symrec * |
102 elf_get_special_sym(const char *name, const char *parser) | 110 elf_get_special_sym(const char *name, const char *parser) |
103 { | 111 { |
104 int i; | 112 int i; |
(...skipping 29 matching lines...) Expand all Loading... |
134 } | 142 } |
135 return 0; | 143 return 0; |
136 } | 144 } |
137 | 145 |
138 /* takes ownership of addr */ | 146 /* takes ownership of addr */ |
139 elf_reloc_entry * | 147 elf_reloc_entry * |
140 elf_reloc_entry_create(yasm_symrec *sym, | 148 elf_reloc_entry_create(yasm_symrec *sym, |
141 yasm_symrec *wrt, | 149 yasm_symrec *wrt, |
142 yasm_intnum *addr, | 150 yasm_intnum *addr, |
143 int rel, | 151 int rel, |
144 size_t valsize) | 152 size_t valsize, |
| 153 int is_GOT_sym) |
145 { | 154 { |
146 elf_reloc_entry *entry; | 155 elf_reloc_entry *entry; |
147 | 156 |
148 if (!elf_march->accepts_reloc) | 157 if (!elf_march->accepts_reloc) |
149 yasm_internal_error(N_("Unsupported machine for ELF output")); | 158 yasm_internal_error(N_("Unsupported machine for ELF output")); |
150 | 159 |
151 if (!elf_march->accepts_reloc(valsize, wrt, elf_ssyms)) | 160 if (!elf_march->accepts_reloc(valsize, wrt)) |
152 { | 161 { |
153 if (addr) | 162 if (addr) |
154 yasm_intnum_destroy(addr); | 163 yasm_intnum_destroy(addr); |
155 return NULL; | 164 return NULL; |
156 } | 165 } |
157 | 166 |
158 if (sym == NULL) | 167 if (sym == NULL) |
159 yasm_internal_error("sym is null"); | 168 yasm_internal_error("sym is null"); |
160 | 169 |
161 entry = yasm_xmalloc(sizeof(elf_reloc_entry)); | 170 entry = yasm_xmalloc(sizeof(elf_reloc_entry)); |
162 entry->reloc.sym = sym; | 171 entry->reloc.sym = sym; |
163 entry->reloc.addr = addr; | 172 entry->reloc.addr = addr; |
164 entry->rtype_rel = rel; | 173 entry->rtype_rel = rel; |
165 entry->valsize = valsize; | 174 entry->valsize = valsize; |
166 entry->addend = NULL; | 175 entry->addend = NULL; |
167 entry->wrt = wrt; | 176 entry->wrt = wrt; |
| 177 entry->is_GOT_sym = is_GOT_sym; |
168 | 178 |
169 return entry; | 179 return entry; |
170 } | 180 } |
171 | 181 |
172 void | 182 void |
173 elf_reloc_entry_destroy(void *entry) | 183 elf_reloc_entry_destroy(void *entry) |
174 { | 184 { |
175 if (((elf_reloc_entry*)entry)->addend) | 185 if (((elf_reloc_entry*)entry)->addend) |
176 yasm_intnum_destroy(((elf_reloc_entry*)entry)->addend); | 186 yasm_intnum_destroy(((elf_reloc_entry*)entry)->addend); |
177 yasm_xfree(entry); | 187 yasm_xfree(entry); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 default: fprintf(f, "undef\n"); break; | 353 default: fprintf(f, "undef\n"); break; |
344 } | 354 } |
345 fprintf(f, "%*ssize=", indent_level, ""); | 355 fprintf(f, "%*ssize=", indent_level, ""); |
346 if (entry->xsize) | 356 if (entry->xsize) |
347 yasm_expr_print(entry->xsize, f); | 357 yasm_expr_print(entry->xsize, f); |
348 else | 358 else |
349 fprintf(f, "%ld", entry->size); | 359 fprintf(f, "%ld", entry->size); |
350 fprintf(f, "\n"); | 360 fprintf(f, "\n"); |
351 } | 361 } |
352 | 362 |
| 363 static void |
| 364 elf_ssym_symtab_entry_print(void *data, FILE *f, int indent_level) |
| 365 { |
| 366 /* TODO */ |
| 367 } |
| 368 |
353 elf_symtab_head * | 369 elf_symtab_head * |
354 elf_symtab_create() | 370 elf_symtab_create() |
355 { | 371 { |
356 elf_symtab_head *symtab = yasm_xmalloc(sizeof(elf_symtab_head)); | 372 elf_symtab_head *symtab = yasm_xmalloc(sizeof(elf_symtab_head)); |
357 elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry)); | 373 elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry)); |
358 | 374 |
359 STAILQ_INIT(symtab); | 375 STAILQ_INIT(symtab); |
360 entry->in_table = 1; | 376 entry->in_table = 1; |
361 entry->sym = NULL; | 377 entry->sym = NULL; |
362 entry->sect = NULL; | 378 entry->sect = NULL; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 { | 711 { |
696 size_t prepend_length = strlen(elf_march->reloc_section_prefix); | 712 size_t prepend_length = strlen(elf_march->reloc_section_prefix); |
697 char *sectname = yasm_xmalloc(prepend_length + strlen(basesect) + 1); | 713 char *sectname = yasm_xmalloc(prepend_length + strlen(basesect) + 1); |
698 strcpy(sectname, elf_march->reloc_section_prefix); | 714 strcpy(sectname, elf_march->reloc_section_prefix); |
699 strcat(sectname, basesect); | 715 strcat(sectname, basesect); |
700 return sectname; | 716 return sectname; |
701 } | 717 } |
702 } | 718 } |
703 | 719 |
704 void | 720 void |
705 elf_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc) | 721 elf_handle_reloc_addend(yasm_intnum *intn, |
| 722 elf_reloc_entry *reloc, |
| 723 unsigned long offset) |
706 { | 724 { |
707 if (!elf_march->handle_reloc_addend) | 725 if (!elf_march->handle_reloc_addend) |
708 yasm_internal_error(N_("Unsupported machine for ELF output")); | 726 yasm_internal_error(N_("Unsupported machine for ELF output")); |
709 elf_march->handle_reloc_addend(intn, reloc); | 727 elf_march->handle_reloc_addend(intn, reloc, offset); |
710 } | 728 } |
711 | 729 |
712 unsigned long | 730 unsigned long |
713 elf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab_idx, | 731 elf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab_idx, |
714 yasm_section *sect, elf_secthead *shead, | 732 yasm_section *sect, elf_secthead *shead, |
715 elf_section_index sindex) | 733 elf_section_index sindex) |
716 { | 734 { |
717 unsigned char buf[SHDR_MAXSIZE], *bufp = buf; | 735 unsigned char buf[SHDR_MAXSIZE], *bufp = buf; |
718 | 736 |
719 if (shead == NULL) | 737 if (shead == NULL) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 | 789 |
772 esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data); | 790 esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data); |
773 if (esym) | 791 if (esym) |
774 r_sym = esym->symindex; | 792 r_sym = esym->symindex; |
775 else | 793 else |
776 r_sym = STN_UNDEF; | 794 r_sym = STN_UNDEF; |
777 | 795 |
778 vis = yasm_symrec_get_visibility(reloc->reloc.sym); | 796 vis = yasm_symrec_get_visibility(reloc->reloc.sym); |
779 if (!elf_march->map_reloc_info_to_type) | 797 if (!elf_march->map_reloc_info_to_type) |
780 yasm_internal_error(N_("Unsupported arch/machine for elf output")); | 798 yasm_internal_error(N_("Unsupported arch/machine for elf output")); |
781 r_type = elf_march->map_reloc_info_to_type(reloc, elf_ssyms); | 799 r_type = elf_march->map_reloc_info_to_type(reloc); |
782 | 800 |
783 bufp = buf; | 801 bufp = buf; |
784 if (!elf_march->write_reloc || !elf_march->reloc_entry_size) | 802 if (!elf_march->write_reloc || !elf_march->reloc_entry_size) |
785 yasm_internal_error(N_("Unsupported arch/machine for elf output")); | 803 yasm_internal_error(N_("Unsupported arch/machine for elf output")); |
786 elf_march->write_reloc(bufp, reloc, r_type, r_sym); | 804 elf_march->write_reloc(bufp, reloc, r_type, r_sym); |
787 fwrite(buf, elf_march->reloc_entry_size, 1, f); | 805 fwrite(buf, elf_march->reloc_entry_size, 1, f); |
788 size += elf_march->reloc_entry_size; | 806 size += elf_march->reloc_entry_size; |
789 | 807 |
790 reloc = (elf_reloc_entry *) | 808 reloc = (elf_reloc_entry *) |
791 yasm_section_reloc_next((yasm_reloc *)reloc); | 809 yasm_section_reloc_next((yasm_reloc *)reloc); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 | 950 |
933 if (((unsigned)(bufp - buf)) != elf_march->proghead_size) | 951 if (((unsigned)(bufp - buf)) != elf_march->proghead_size) |
934 yasm_internal_error(N_("ELF program header is not proper length")); | 952 yasm_internal_error(N_("ELF program header is not proper length")); |
935 | 953 |
936 if (fwrite(buf, elf_march->proghead_size, 1, f)) | 954 if (fwrite(buf, elf_march->proghead_size, 1, f)) |
937 return elf_march->proghead_size; | 955 return elf_march->proghead_size; |
938 | 956 |
939 yasm_internal_error(N_("Failed to write ELF program header")); | 957 yasm_internal_error(N_("Failed to write ELF program header")); |
940 return 0; | 958 return 0; |
941 } | 959 } |
OLD | NEW |