1da0c48c4Sopenharmony_ci/* Copyright (C) 2002, 2005 Red Hat, Inc. 2da0c48c4Sopenharmony_ci This file is part of elfutils. 3da0c48c4Sopenharmony_ci Written by Ulrich Drepper <drepper@redhat.com>, 2002. 4da0c48c4Sopenharmony_ci 5da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 6da0c48c4Sopenharmony_ci it under the terms of the GNU General Public License as published by 7da0c48c4Sopenharmony_ci the Free Software Foundation; either version 3 of the License, or 8da0c48c4Sopenharmony_ci (at your option) any later version. 9da0c48c4Sopenharmony_ci 10da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 11da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13da0c48c4Sopenharmony_ci GNU General Public License for more details. 14da0c48c4Sopenharmony_ci 15da0c48c4Sopenharmony_ci You should have received a copy of the GNU General Public License 16da0c48c4Sopenharmony_ci along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17da0c48c4Sopenharmony_ci 18da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 19da0c48c4Sopenharmony_ci# include <config.h> 20da0c48c4Sopenharmony_ci#endif 21da0c48c4Sopenharmony_ci 22da0c48c4Sopenharmony_ci#include <fcntl.h> 23da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(asm) 24da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(ebl) 25da0c48c4Sopenharmony_ci#include <libelf.h> 26da0c48c4Sopenharmony_ci#include <stdio.h> 27da0c48c4Sopenharmony_ci#include <string.h> 28da0c48c4Sopenharmony_ci#include <unistd.h> 29da0c48c4Sopenharmony_ci 30da0c48c4Sopenharmony_ci 31da0c48c4Sopenharmony_cistatic const char fname[] = "asm-tst1-out.o"; 32da0c48c4Sopenharmony_ci 33da0c48c4Sopenharmony_ci 34da0c48c4Sopenharmony_cistatic const GElf_Ehdr expected_ehdr = 35da0c48c4Sopenharmony_ci { 36da0c48c4Sopenharmony_ci .e_ident = { [EI_MAG0] = ELFMAG0, 37da0c48c4Sopenharmony_ci [EI_MAG1] = ELFMAG1, 38da0c48c4Sopenharmony_ci [EI_MAG2] = ELFMAG2, 39da0c48c4Sopenharmony_ci [EI_MAG3] = ELFMAG3, 40da0c48c4Sopenharmony_ci [EI_CLASS] = ELFCLASS32, 41da0c48c4Sopenharmony_ci [EI_DATA] = ELFDATA2LSB, 42da0c48c4Sopenharmony_ci [EI_VERSION] = EV_CURRENT }, 43da0c48c4Sopenharmony_ci .e_type = ET_REL, 44da0c48c4Sopenharmony_ci .e_machine = EM_386, 45da0c48c4Sopenharmony_ci .e_version = EV_CURRENT, 46da0c48c4Sopenharmony_ci .e_shoff = 88, 47da0c48c4Sopenharmony_ci .e_ehsize = sizeof (Elf32_Ehdr), 48da0c48c4Sopenharmony_ci .e_shentsize = sizeof (Elf32_Shdr), 49da0c48c4Sopenharmony_ci .e_shnum = 4, 50da0c48c4Sopenharmony_ci .e_shstrndx = 3 51da0c48c4Sopenharmony_ci }; 52da0c48c4Sopenharmony_ci 53da0c48c4Sopenharmony_ci 54da0c48c4Sopenharmony_cistatic const char *scnnames[4] = 55da0c48c4Sopenharmony_ci { 56da0c48c4Sopenharmony_ci [0] = "", 57da0c48c4Sopenharmony_ci [1] = ".text", 58da0c48c4Sopenharmony_ci [2] = ".data", 59da0c48c4Sopenharmony_ci [3] = ".shstrtab" 60da0c48c4Sopenharmony_ci }; 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ci 63da0c48c4Sopenharmony_ciint 64da0c48c4Sopenharmony_cimain (void) 65da0c48c4Sopenharmony_ci{ 66da0c48c4Sopenharmony_ci AsmCtx_t *ctx; 67da0c48c4Sopenharmony_ci AsmScn_t *scn1; 68da0c48c4Sopenharmony_ci AsmScn_t *scn2; 69da0c48c4Sopenharmony_ci int fd; 70da0c48c4Sopenharmony_ci Elf *elf; 71da0c48c4Sopenharmony_ci GElf_Ehdr ehdr_mem; 72da0c48c4Sopenharmony_ci GElf_Ehdr *ehdr; 73da0c48c4Sopenharmony_ci int result = 0; 74da0c48c4Sopenharmony_ci size_t cnt; 75da0c48c4Sopenharmony_ci 76da0c48c4Sopenharmony_ci elf_version (EV_CURRENT); 77da0c48c4Sopenharmony_ci 78da0c48c4Sopenharmony_ci Ebl *ebl = ebl_openbackend_machine (EM_386); 79da0c48c4Sopenharmony_ci if (ebl == NULL) 80da0c48c4Sopenharmony_ci { 81da0c48c4Sopenharmony_ci puts ("cannot open backend library"); 82da0c48c4Sopenharmony_ci return 1; 83da0c48c4Sopenharmony_ci } 84da0c48c4Sopenharmony_ci 85da0c48c4Sopenharmony_ci ctx = asm_begin (fname, ebl, false); 86da0c48c4Sopenharmony_ci if (ctx == NULL) 87da0c48c4Sopenharmony_ci { 88da0c48c4Sopenharmony_ci printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 89da0c48c4Sopenharmony_ci return 1; 90da0c48c4Sopenharmony_ci } 91da0c48c4Sopenharmony_ci 92da0c48c4Sopenharmony_ci /* Create two sections. */ 93da0c48c4Sopenharmony_ci scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); 94da0c48c4Sopenharmony_ci scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 95da0c48c4Sopenharmony_ci if (scn1 == NULL || scn2 == NULL) 96da0c48c4Sopenharmony_ci { 97da0c48c4Sopenharmony_ci printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 98da0c48c4Sopenharmony_ci asm_abort (ctx); 99da0c48c4Sopenharmony_ci return 1; 100da0c48c4Sopenharmony_ci } 101da0c48c4Sopenharmony_ci 102da0c48c4Sopenharmony_ci /* Special alignment for the .text section. */ 103da0c48c4Sopenharmony_ci if (asm_align (scn1, 32) != 0) 104da0c48c4Sopenharmony_ci { 105da0c48c4Sopenharmony_ci printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 106da0c48c4Sopenharmony_ci result = 1; 107da0c48c4Sopenharmony_ci } 108da0c48c4Sopenharmony_ci 109da0c48c4Sopenharmony_ci /* Create the output file. */ 110da0c48c4Sopenharmony_ci if (asm_end (ctx) != 0) 111da0c48c4Sopenharmony_ci { 112da0c48c4Sopenharmony_ci printf ("cannot create output file: %s\n", asm_errmsg (-1)); 113da0c48c4Sopenharmony_ci asm_abort (ctx); 114da0c48c4Sopenharmony_ci return 1; 115da0c48c4Sopenharmony_ci } 116da0c48c4Sopenharmony_ci 117da0c48c4Sopenharmony_ci /* Check the file. */ 118da0c48c4Sopenharmony_ci fd = open (fname, O_RDONLY); 119da0c48c4Sopenharmony_ci if (fd == -1) 120da0c48c4Sopenharmony_ci { 121da0c48c4Sopenharmony_ci printf ("cannot open generated file: %m\n"); 122da0c48c4Sopenharmony_ci result = 1; 123da0c48c4Sopenharmony_ci goto out; 124da0c48c4Sopenharmony_ci } 125da0c48c4Sopenharmony_ci 126da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_READ, NULL); 127da0c48c4Sopenharmony_ci if (elf == NULL) 128da0c48c4Sopenharmony_ci { 129da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 130da0c48c4Sopenharmony_ci result = 1; 131da0c48c4Sopenharmony_ci goto out_close; 132da0c48c4Sopenharmony_ci } 133da0c48c4Sopenharmony_ci if (elf_kind (elf) != ELF_K_ELF) 134da0c48c4Sopenharmony_ci { 135da0c48c4Sopenharmony_ci puts ("not a valid ELF file"); 136da0c48c4Sopenharmony_ci result = 1; 137da0c48c4Sopenharmony_ci goto out_close2; 138da0c48c4Sopenharmony_ci } 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci ehdr = gelf_getehdr (elf, &ehdr_mem); 141da0c48c4Sopenharmony_ci if (ehdr == NULL) 142da0c48c4Sopenharmony_ci { 143da0c48c4Sopenharmony_ci printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 144da0c48c4Sopenharmony_ci result = 1; 145da0c48c4Sopenharmony_ci goto out_close2; 146da0c48c4Sopenharmony_ci } 147da0c48c4Sopenharmony_ci 148da0c48c4Sopenharmony_ci if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 149da0c48c4Sopenharmony_ci { 150da0c48c4Sopenharmony_ci puts ("ELF header does not match"); 151da0c48c4Sopenharmony_ci result = 1; 152da0c48c4Sopenharmony_ci goto out_close2; 153da0c48c4Sopenharmony_ci } 154da0c48c4Sopenharmony_ci 155da0c48c4Sopenharmony_ci for (cnt = 1; cnt < 4; ++cnt) 156da0c48c4Sopenharmony_ci { 157da0c48c4Sopenharmony_ci Elf_Scn *scn; 158da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 159da0c48c4Sopenharmony_ci GElf_Shdr *shdr; 160da0c48c4Sopenharmony_ci 161da0c48c4Sopenharmony_ci scn = elf_getscn (elf, cnt); 162da0c48c4Sopenharmony_ci if (scn == NULL) 163da0c48c4Sopenharmony_ci { 164da0c48c4Sopenharmony_ci printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); 165da0c48c4Sopenharmony_ci result = 1; 166da0c48c4Sopenharmony_ci continue; 167da0c48c4Sopenharmony_ci } 168da0c48c4Sopenharmony_ci 169da0c48c4Sopenharmony_ci shdr = gelf_getshdr (scn, &shdr_mem); 170da0c48c4Sopenharmony_ci if (shdr == NULL) 171da0c48c4Sopenharmony_ci { 172da0c48c4Sopenharmony_ci printf ("cannot get section header for section %zd: %s\n", 173da0c48c4Sopenharmony_ci cnt, elf_errmsg (-1)); 174da0c48c4Sopenharmony_ci result = 1; 175da0c48c4Sopenharmony_ci continue; 176da0c48c4Sopenharmony_ci } 177da0c48c4Sopenharmony_ci 178da0c48c4Sopenharmony_ci if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 179da0c48c4Sopenharmony_ci scnnames[cnt]) != 0) 180da0c48c4Sopenharmony_ci { 181da0c48c4Sopenharmony_ci printf ("section %zd's name differs: %s vs %s\n", cnt, 182da0c48c4Sopenharmony_ci elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 183da0c48c4Sopenharmony_ci scnnames[cnt]); 184da0c48c4Sopenharmony_ci result = 1; 185da0c48c4Sopenharmony_ci } 186da0c48c4Sopenharmony_ci 187da0c48c4Sopenharmony_ci if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS)) 188da0c48c4Sopenharmony_ci { 189da0c48c4Sopenharmony_ci printf ("section %zd's type differs\n", cnt); 190da0c48c4Sopenharmony_ci result = 1; 191da0c48c4Sopenharmony_ci } 192da0c48c4Sopenharmony_ci 193da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR)) 194da0c48c4Sopenharmony_ci || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 195da0c48c4Sopenharmony_ci || (cnt == 3 && shdr->sh_flags != 0)) 196da0c48c4Sopenharmony_ci { 197da0c48c4Sopenharmony_ci printf ("section %zd's flags differs\n", cnt); 198da0c48c4Sopenharmony_ci result = 1; 199da0c48c4Sopenharmony_ci } 200da0c48c4Sopenharmony_ci 201da0c48c4Sopenharmony_ci if (shdr->sh_addr != 0) 202da0c48c4Sopenharmony_ci { 203da0c48c4Sopenharmony_ci printf ("section %zd's address differs\n", cnt); 204da0c48c4Sopenharmony_ci result = 1; 205da0c48c4Sopenharmony_ci } 206da0c48c4Sopenharmony_ci 207da0c48c4Sopenharmony_ci if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31)) 208da0c48c4Sopenharmony_ci { 209da0c48c4Sopenharmony_ci printf ("section %zd's offset differs\n", cnt); 210da0c48c4Sopenharmony_ci result = 1; 211da0c48c4Sopenharmony_ci } 212da0c48c4Sopenharmony_ci 213da0c48c4Sopenharmony_ci if ((cnt != 3 && shdr->sh_size != 0) 214da0c48c4Sopenharmony_ci || (cnt == 3 && shdr->sh_size != 23)) 215da0c48c4Sopenharmony_ci { 216da0c48c4Sopenharmony_ci printf ("section %zd's size differs\n", cnt); 217da0c48c4Sopenharmony_ci result = 1; 218da0c48c4Sopenharmony_ci } 219da0c48c4Sopenharmony_ci 220da0c48c4Sopenharmony_ci if (shdr->sh_link != 0) 221da0c48c4Sopenharmony_ci { 222da0c48c4Sopenharmony_ci printf ("section %zd's link differs\n", cnt); 223da0c48c4Sopenharmony_ci result = 1; 224da0c48c4Sopenharmony_ci } 225da0c48c4Sopenharmony_ci 226da0c48c4Sopenharmony_ci if (shdr->sh_info != 0) 227da0c48c4Sopenharmony_ci { 228da0c48c4Sopenharmony_ci printf ("section %zd's info differs\n", cnt); 229da0c48c4Sopenharmony_ci result = 1; 230da0c48c4Sopenharmony_ci } 231da0c48c4Sopenharmony_ci 232da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_addralign != 32) 233da0c48c4Sopenharmony_ci || (cnt != 1 && shdr->sh_addralign != 1)) 234da0c48c4Sopenharmony_ci { 235da0c48c4Sopenharmony_ci printf ("section %zd's addralign differs\n", cnt); 236da0c48c4Sopenharmony_ci result = 1; 237da0c48c4Sopenharmony_ci } 238da0c48c4Sopenharmony_ci 239da0c48c4Sopenharmony_ci if (shdr->sh_entsize != 0) 240da0c48c4Sopenharmony_ci { 241da0c48c4Sopenharmony_ci printf ("section %zd's entsize differs\n", cnt); 242da0c48c4Sopenharmony_ci result = 1; 243da0c48c4Sopenharmony_ci } 244da0c48c4Sopenharmony_ci } 245da0c48c4Sopenharmony_ci 246da0c48c4Sopenharmony_ci out_close2: 247da0c48c4Sopenharmony_ci elf_end (elf); 248da0c48c4Sopenharmony_ci out_close: 249da0c48c4Sopenharmony_ci close (fd); 250da0c48c4Sopenharmony_ci out: 251da0c48c4Sopenharmony_ci /* We don't need the file anymore. */ 252da0c48c4Sopenharmony_ci unlink (fname); 253da0c48c4Sopenharmony_ci 254da0c48c4Sopenharmony_ci ebl_closebackend (ebl); 255da0c48c4Sopenharmony_ci 256da0c48c4Sopenharmony_ci return result; 257da0c48c4Sopenharmony_ci} 258