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 <libasm.h> 16 #include <libelf.h> 17 #include <stdio.h> 18 #include <string.h> 19 #include <unistd.h> 20 21 22 static const char fname[] = "asm-tst1-out.o"; 23 24 25 static const GElf_Ehdr expected_ehdr = 26 { 27 .e_ident = { [EI_MAG0] = ELFMAG0, 28 [EI_MAG1] = ELFMAG1, 29 [EI_MAG2] = ELFMAG2, 30 [EI_MAG3] = ELFMAG3, 31 [EI_CLASS] = ELFCLASS32, 32 [EI_DATA] = ELFDATA2LSB, 33 [EI_VERSION] = EV_CURRENT }, 34 .e_type = ET_REL, 35 .e_machine = EM_386, 36 .e_version = EV_CURRENT, 37 .e_shoff = 88, 38 .e_ehsize = sizeof (Elf32_Ehdr), 39 .e_shentsize = sizeof (Elf32_Shdr), 40 .e_shnum = 4, 41 .e_shstrndx = 3 42 }; 43 44 45 static const char *scnnames[4] = 46 { 47 [0] = "", 48 [1] = ".text", 49 [2] = ".data", 50 [3] = ".shstrtab" 51 }; 52 53 54 int 55 main (void) 56 { 57 AsmCtx_t *ctx; 58 AsmScn_t *scn1; 59 AsmScn_t *scn2; 60 int fd; 61 Elf *elf; 62 GElf_Ehdr ehdr_mem; 63 GElf_Ehdr *ehdr; 64 int result = 0; 65 size_t cnt; 66 67 elf_version (EV_CURRENT); 68 69 ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB); 70 if (ctx == NULL) 71 { 72 printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 73 return 1; 74 } 75 76 /* Create two sections. */ 77 scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); 78 scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 79 if (scn1 == NULL || scn2 == NULL) 80 { 81 printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 82 asm_abort (ctx); 83 return 1; 84 } 85 86 /* Special alignment for the .text section. */ 87 if (asm_align (scn1, 32) != 0) 88 { 89 printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 90 result = 1; 91 } 92 93 /* Create the output file. */ 94 if (asm_end (ctx) != 0) 95 { 96 printf ("cannot create output file: %s\n", asm_errmsg (-1)); 97 asm_abort (ctx); 98 return 1; 99 } 100 101 /* Check the file. */ 102 fd = open (fname, O_RDONLY); 103 if (fd == -1) 104 { 105 printf ("cannot open generated file: %m\n"); 106 result = 1; 107 goto out; 108 } 109 110 elf = elf_begin (fd, ELF_C_READ, NULL); 111 if (elf == NULL) 112 { 113 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 114 result = 1; 115 goto out_close; 116 } 117 if (elf_kind (elf) != ELF_K_ELF) 118 { 119 puts ("not a valid ELF file"); 120 result = 1; 121 goto out_close2; 122 } 123 124 ehdr = gelf_getehdr (elf, &ehdr_mem); 125 if (ehdr == NULL) 126 { 127 printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 128 result = 1; 129 goto out_close2; 130 } 131 132 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 133 { 134 puts ("ELF header does not match"); 135 result = 1; 136 goto out_close2; 137 } 138 139 for (cnt = 1; cnt < 4; ++cnt) 140 { 141 Elf_Scn *scn; 142 GElf_Shdr shdr_mem; 143 GElf_Shdr *shdr; 144 145 scn = elf_getscn (elf, cnt); 146 if (scn == NULL) 147 { 148 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1)); 149 result = 1; 150 continue; 151 } 152 153 shdr = gelf_getshdr (scn, &shdr_mem); 154 if (shdr == NULL) 155 { 156 printf ("cannot get section header for section %Zd: %s\n", 157 cnt, elf_errmsg (-1)); 158 result = 1; 159 continue; 160 } 161 162 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 163 scnnames[cnt]) != 0) 164 { 165 printf ("section %Zd's name differs: %s vs %s\n", cnt, 166 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 167 scnnames[cnt]); 168 result = 1; 169 } 170 171 if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS)) 172 { 173 printf ("section %Zd's type differs\n", cnt); 174 result = 1; 175 } 176 177 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR)) 178 || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 179 || (cnt == 3 && shdr->sh_flags != 0)) 180 { 181 printf ("section %Zd's flags differs\n", cnt); 182 result = 1; 183 } 184 185 if (shdr->sh_addr != 0) 186 { 187 printf ("section %Zd's address differs\n", cnt); 188 result = 1; 189 } 190 191 if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31)) 192 { 193 printf ("section %Zd's offset differs\n", cnt); 194 result = 1; 195 } 196 197 if ((cnt != 3 && shdr->sh_size != 0) 198 || (cnt == 3 && shdr->sh_size != 23)) 199 { 200 printf ("section %Zd's size differs\n", cnt); 201 result = 1; 202 } 203 204 if (shdr->sh_link != 0) 205 { 206 printf ("section %Zd's link differs\n", cnt); 207 result = 1; 208 } 209 210 if (shdr->sh_info != 0) 211 { 212 printf ("section %Zd's info differs\n", cnt); 213 result = 1; 214 } 215 216 if ((cnt == 1 && shdr->sh_addralign != 32) 217 || (cnt != 1 && shdr->sh_addralign != 1)) 218 { 219 printf ("section %Zd's addralign differs\n", cnt); 220 result = 1; 221 } 222 223 if (shdr->sh_entsize != 0) 224 { 225 printf ("section %Zd's entsize differs\n", cnt); 226 result = 1; 227 } 228 } 229 230 out_close2: 231 elf_end (elf); 232 out_close: 233 close (fd); 234 out: 235 /* We don't need the file anymore. */ 236 unlink (fname); 237 238 return result; 239 } 240