1 /* Copyright (C) 2002 Red Hat, Inc. 2 Written by Ulrich Drepper <drepper (at) redhat.com>, 2002. 3 4 This program is Open Source software; you can redistribute it and/or 5 modify it under the terms of the Open Software License version 1.0 as 6 published by the Open Source Initiative. 7 8 You should have received a copy of the Open Software License along 9 with this program; if not, you may obtain a copy of the Open Software 10 License version 1.0 from http://www.opensource.org/licenses/osl.php or 11 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 12 3001 King Ranch Road, Ukiah, CA 95482. */ 13 14 #include <fcntl.h> 15 #include <inttypes.h> 16 #include <libasm.h> 17 #include <libelf.h> 18 #include <stdio.h> 19 #include <unistd.h> 20 21 22 static const char fname[] = "asm-tst7-out.o"; 23 24 25 int 26 main (void) 27 { 28 int result = 0; 29 size_t cnt; 30 AsmCtx_t *ctx; 31 Elf *elf; 32 int fd; 33 34 elf_version (EV_CURRENT); 35 36 ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB); 37 if (ctx == NULL) 38 { 39 printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 40 return 1; 41 } 42 43 if (asm_newcomsym (ctx, "commsym", 4, 16) == NULL) 44 { 45 printf ("cannot create common symbol: %s\n", asm_errmsg (-1)); 46 asm_abort (ctx); 47 return 1; 48 } 49 50 /* Create the output file. */ 51 if (asm_end (ctx) != 0) 52 { 53 printf ("cannot create output file: %s\n", asm_errmsg (-1)); 54 asm_abort (ctx); 55 return 1; 56 } 57 58 /* Check the file. */ 59 fd = open (fname, O_RDONLY); 60 if (fd == -1) 61 { 62 printf ("cannot open generated file: %m\n"); 63 result = 1; 64 goto out; 65 } 66 67 elf = elf_begin (fd, ELF_C_READ, NULL); 68 if (elf == NULL) 69 { 70 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 71 result = 1; 72 goto out_close; 73 } 74 if (elf_kind (elf) != ELF_K_ELF) 75 { 76 puts ("not a valid ELF file"); 77 result = 1; 78 goto out_close2; 79 } 80 81 for (cnt = 1; 1; ++cnt) 82 { 83 Elf_Scn *scn; 84 GElf_Shdr shdr_mem; 85 GElf_Shdr *shdr; 86 87 scn = elf_getscn (elf, cnt); 88 if (scn == NULL) 89 { 90 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1)); 91 result = 1; 92 continue; 93 } 94 95 shdr = gelf_getshdr (scn, &shdr_mem); 96 if (shdr == NULL) 97 { 98 printf ("cannot get section header for section %Zd: %s\n", 99 cnt, elf_errmsg (-1)); 100 result = 1; 101 continue; 102 } 103 /* We are looking for the symbol table. */ 104 if (shdr->sh_type != SHT_SYMTAB) 105 continue; 106 107 for (cnt = 1; cnt< (shdr->sh_size 108 / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT)); 109 ++cnt) 110 { 111 GElf_Sym sym_mem; 112 GElf_Sym *sym; 113 114 if (cnt > 1) 115 { 116 puts ("too many symbol"); 117 result = 1; 118 break; 119 } 120 121 sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem); 122 if (sym == NULL) 123 { 124 printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1)); 125 result = 1; 126 } 127 else 128 { 129 if (sym->st_shndx != SHN_COMMON) 130 { 131 printf ("expected common symbol, got section %u\n", 132 (unsigned int) sym->st_shndx); 133 result = 1; 134 } 135 136 if (sym->st_value != 16) 137 { 138 printf ("requested alignment 16, is %" PRIuMAX "\n", 139 (uintmax_t) sym->st_value); 140 result = 1; 141 } 142 143 if (sym->st_size != 4) 144 { 145 printf ("requested size 4, is %" PRIuMAX "\n", 146 (uintmax_t) sym->st_value); 147 result = 1; 148 } 149 } 150 } 151 152 break; 153 } 154 155 out_close2: 156 elf_end (elf); 157 out_close: 158 close (fd); 159 out: 160 /* We don't need the file anymore. */ 161 unlink (fname); 162 163 return result; 164 } 165