| 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 |