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-tst2-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 = 96, 47da0c48c4Sopenharmony_ci .e_ehsize = sizeof (Elf32_Ehdr), 48da0c48c4Sopenharmony_ci .e_shentsize = sizeof (Elf32_Shdr), 49da0c48c4Sopenharmony_ci .e_shnum = 3, 50da0c48c4Sopenharmony_ci .e_shstrndx = 2 51da0c48c4Sopenharmony_ci }; 52da0c48c4Sopenharmony_ci 53da0c48c4Sopenharmony_ci 54da0c48c4Sopenharmony_cistatic const char *scnnames[3] = 55da0c48c4Sopenharmony_ci { 56da0c48c4Sopenharmony_ci [0] = "", 57da0c48c4Sopenharmony_ci [1] = ".data", 58da0c48c4Sopenharmony_ci [2] = ".shstrtab" 59da0c48c4Sopenharmony_ci }; 60da0c48c4Sopenharmony_ci 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ciint 63da0c48c4Sopenharmony_cimain (void) 64da0c48c4Sopenharmony_ci{ 65da0c48c4Sopenharmony_ci AsmCtx_t *ctx; 66da0c48c4Sopenharmony_ci AsmScn_t *scn1; 67da0c48c4Sopenharmony_ci AsmScn_t *scn2; 68da0c48c4Sopenharmony_ci int result = 0; 69da0c48c4Sopenharmony_ci int fd; 70da0c48c4Sopenharmony_ci Elf *elf; 71da0c48c4Sopenharmony_ci GElf_Ehdr ehdr_mem; 72da0c48c4Sopenharmony_ci GElf_Ehdr *ehdr; 73da0c48c4Sopenharmony_ci size_t cnt; 74da0c48c4Sopenharmony_ci 75da0c48c4Sopenharmony_ci elf_version (EV_CURRENT); 76da0c48c4Sopenharmony_ci 77da0c48c4Sopenharmony_ci Ebl *ebl = ebl_openbackend_machine (EM_386); 78da0c48c4Sopenharmony_ci if (ebl == NULL) 79da0c48c4Sopenharmony_ci { 80da0c48c4Sopenharmony_ci puts ("cannot open backend library"); 81da0c48c4Sopenharmony_ci return 1; 82da0c48c4Sopenharmony_ci } 83da0c48c4Sopenharmony_ci 84da0c48c4Sopenharmony_ci ctx = asm_begin (fname, ebl, false); 85da0c48c4Sopenharmony_ci if (ctx == NULL) 86da0c48c4Sopenharmony_ci { 87da0c48c4Sopenharmony_ci printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 88da0c48c4Sopenharmony_ci return 1; 89da0c48c4Sopenharmony_ci } 90da0c48c4Sopenharmony_ci 91da0c48c4Sopenharmony_ci /* Create two sections. */ 92da0c48c4Sopenharmony_ci scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 93da0c48c4Sopenharmony_ci scn2 = asm_newsubscn (scn1, 1); 94da0c48c4Sopenharmony_ci if (scn1 == NULL || scn2 == NULL) 95da0c48c4Sopenharmony_ci { 96da0c48c4Sopenharmony_ci printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 97da0c48c4Sopenharmony_ci asm_abort (ctx); 98da0c48c4Sopenharmony_ci return 1; 99da0c48c4Sopenharmony_ci } 100da0c48c4Sopenharmony_ci 101da0c48c4Sopenharmony_ci /* Special alignment for the .text section. */ 102da0c48c4Sopenharmony_ci if (asm_align (scn1, 16) != 0) 103da0c48c4Sopenharmony_ci { 104da0c48c4Sopenharmony_ci printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 105da0c48c4Sopenharmony_ci result = 1; 106da0c48c4Sopenharmony_ci } 107da0c48c4Sopenharmony_ci 108da0c48c4Sopenharmony_ci /* Add a few strings. */ 109da0c48c4Sopenharmony_ci if (asm_addstrz (scn1, "one", 4) != 0) 110da0c48c4Sopenharmony_ci { 111da0c48c4Sopenharmony_ci printf ("cannot insert first string: %s\n", asm_errmsg (-1)); 112da0c48c4Sopenharmony_ci result = 1; 113da0c48c4Sopenharmony_ci } 114da0c48c4Sopenharmony_ci if (asm_addstrz (scn2, "three", 0) != 0) 115da0c48c4Sopenharmony_ci { 116da0c48c4Sopenharmony_ci printf ("cannot insert second string: %s\n", asm_errmsg (-1)); 117da0c48c4Sopenharmony_ci result = 1; 118da0c48c4Sopenharmony_ci } 119da0c48c4Sopenharmony_ci if (asm_addstrz (scn1, "two", 4) != 0) 120da0c48c4Sopenharmony_ci { 121da0c48c4Sopenharmony_ci printf ("cannot insert third string: %s\n", asm_errmsg (-1)); 122da0c48c4Sopenharmony_ci result = 1; 123da0c48c4Sopenharmony_ci } 124da0c48c4Sopenharmony_ci 125da0c48c4Sopenharmony_ci /* Create the output file. */ 126da0c48c4Sopenharmony_ci if (asm_end (ctx) != 0) 127da0c48c4Sopenharmony_ci { 128da0c48c4Sopenharmony_ci printf ("cannot create output file: %s\n", asm_errmsg (-1)); 129da0c48c4Sopenharmony_ci asm_abort (ctx); 130da0c48c4Sopenharmony_ci return 1; 131da0c48c4Sopenharmony_ci } 132da0c48c4Sopenharmony_ci 133da0c48c4Sopenharmony_ci /* Check the file. */ 134da0c48c4Sopenharmony_ci fd = open (fname, O_RDONLY); 135da0c48c4Sopenharmony_ci if (fd == -1) 136da0c48c4Sopenharmony_ci { 137da0c48c4Sopenharmony_ci printf ("cannot open generated file: %m\n"); 138da0c48c4Sopenharmony_ci result = 1; 139da0c48c4Sopenharmony_ci goto out; 140da0c48c4Sopenharmony_ci } 141da0c48c4Sopenharmony_ci 142da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_READ, NULL); 143da0c48c4Sopenharmony_ci if (elf == NULL) 144da0c48c4Sopenharmony_ci { 145da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 146da0c48c4Sopenharmony_ci result = 1; 147da0c48c4Sopenharmony_ci goto out_close; 148da0c48c4Sopenharmony_ci } 149da0c48c4Sopenharmony_ci if (elf_kind (elf) != ELF_K_ELF) 150da0c48c4Sopenharmony_ci { 151da0c48c4Sopenharmony_ci puts ("not a valid ELF file"); 152da0c48c4Sopenharmony_ci result = 1; 153da0c48c4Sopenharmony_ci goto out_close2; 154da0c48c4Sopenharmony_ci } 155da0c48c4Sopenharmony_ci 156da0c48c4Sopenharmony_ci ehdr = gelf_getehdr (elf, &ehdr_mem); 157da0c48c4Sopenharmony_ci if (ehdr == NULL) 158da0c48c4Sopenharmony_ci { 159da0c48c4Sopenharmony_ci printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 160da0c48c4Sopenharmony_ci result = 1; 161da0c48c4Sopenharmony_ci goto out_close2; 162da0c48c4Sopenharmony_ci } 163da0c48c4Sopenharmony_ci 164da0c48c4Sopenharmony_ci if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 165da0c48c4Sopenharmony_ci { 166da0c48c4Sopenharmony_ci puts ("ELF header does not match"); 167da0c48c4Sopenharmony_ci result = 1; 168da0c48c4Sopenharmony_ci goto out_close2; 169da0c48c4Sopenharmony_ci } 170da0c48c4Sopenharmony_ci 171da0c48c4Sopenharmony_ci for (cnt = 1; cnt < 3; ++cnt) 172da0c48c4Sopenharmony_ci { 173da0c48c4Sopenharmony_ci Elf_Scn *scn; 174da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 175da0c48c4Sopenharmony_ci GElf_Shdr *shdr; 176da0c48c4Sopenharmony_ci 177da0c48c4Sopenharmony_ci scn = elf_getscn (elf, cnt); 178da0c48c4Sopenharmony_ci if (scn == NULL) 179da0c48c4Sopenharmony_ci { 180da0c48c4Sopenharmony_ci printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); 181da0c48c4Sopenharmony_ci result = 1; 182da0c48c4Sopenharmony_ci continue; 183da0c48c4Sopenharmony_ci } 184da0c48c4Sopenharmony_ci 185da0c48c4Sopenharmony_ci shdr = gelf_getshdr (scn, &shdr_mem); 186da0c48c4Sopenharmony_ci if (shdr == NULL) 187da0c48c4Sopenharmony_ci { 188da0c48c4Sopenharmony_ci printf ("cannot get section header for section %zd: %s\n", 189da0c48c4Sopenharmony_ci cnt, elf_errmsg (-1)); 190da0c48c4Sopenharmony_ci result = 1; 191da0c48c4Sopenharmony_ci continue; 192da0c48c4Sopenharmony_ci } 193da0c48c4Sopenharmony_ci 194da0c48c4Sopenharmony_ci if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 195da0c48c4Sopenharmony_ci scnnames[cnt]) != 0) 196da0c48c4Sopenharmony_ci { 197da0c48c4Sopenharmony_ci printf ("section %zd's name differs: %s vs %s\n", cnt, 198da0c48c4Sopenharmony_ci elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 199da0c48c4Sopenharmony_ci scnnames[cnt]); 200da0c48c4Sopenharmony_ci result = 1; 201da0c48c4Sopenharmony_ci } 202da0c48c4Sopenharmony_ci 203da0c48c4Sopenharmony_ci if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS)) 204da0c48c4Sopenharmony_ci { 205da0c48c4Sopenharmony_ci printf ("section %zd's type differs\n", cnt); 206da0c48c4Sopenharmony_ci result = 1; 207da0c48c4Sopenharmony_ci } 208da0c48c4Sopenharmony_ci 209da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 210da0c48c4Sopenharmony_ci || (cnt == 2 && shdr->sh_flags != 0)) 211da0c48c4Sopenharmony_ci { 212da0c48c4Sopenharmony_ci printf ("section %zd's flags differs\n", cnt); 213da0c48c4Sopenharmony_ci result = 1; 214da0c48c4Sopenharmony_ci } 215da0c48c4Sopenharmony_ci 216da0c48c4Sopenharmony_ci if (shdr->sh_addr != 0) 217da0c48c4Sopenharmony_ci { 218da0c48c4Sopenharmony_ci printf ("section %zd's address differs\n", cnt); 219da0c48c4Sopenharmony_ci result = 1; 220da0c48c4Sopenharmony_ci } 221da0c48c4Sopenharmony_ci 222da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15)) 223da0c48c4Sopenharmony_ci || (cnt == 2 224da0c48c4Sopenharmony_ci && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15) 225da0c48c4Sopenharmony_ci + strlen ("one") + 1 226da0c48c4Sopenharmony_ci + strlen ("two") + 1 227da0c48c4Sopenharmony_ci + strlen ("three") + 1))) 228da0c48c4Sopenharmony_ci { 229da0c48c4Sopenharmony_ci printf ("section %zd's offset differs\n", cnt); 230da0c48c4Sopenharmony_ci result = 1; 231da0c48c4Sopenharmony_ci } 232da0c48c4Sopenharmony_ci 233da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1 234da0c48c4Sopenharmony_ci + strlen ("two") + 1 235da0c48c4Sopenharmony_ci + strlen ("three") + 1)) 236da0c48c4Sopenharmony_ci || (cnt == 2 && shdr->sh_size != 17)) 237da0c48c4Sopenharmony_ci { 238da0c48c4Sopenharmony_ci printf ("section %zd's size differs\n", cnt); 239da0c48c4Sopenharmony_ci result = 1; 240da0c48c4Sopenharmony_ci } 241da0c48c4Sopenharmony_ci 242da0c48c4Sopenharmony_ci if (shdr->sh_link != 0) 243da0c48c4Sopenharmony_ci { 244da0c48c4Sopenharmony_ci printf ("section %zd's link differs\n", cnt); 245da0c48c4Sopenharmony_ci result = 1; 246da0c48c4Sopenharmony_ci } 247da0c48c4Sopenharmony_ci 248da0c48c4Sopenharmony_ci if (shdr->sh_info != 0) 249da0c48c4Sopenharmony_ci { 250da0c48c4Sopenharmony_ci printf ("section %zd's info differs\n", cnt); 251da0c48c4Sopenharmony_ci result = 1; 252da0c48c4Sopenharmony_ci } 253da0c48c4Sopenharmony_ci 254da0c48c4Sopenharmony_ci if ((cnt == 1 && shdr->sh_addralign != 16) 255da0c48c4Sopenharmony_ci || (cnt != 1 && shdr->sh_addralign != 1)) 256da0c48c4Sopenharmony_ci { 257da0c48c4Sopenharmony_ci printf ("section %zd's addralign differs\n", cnt); 258da0c48c4Sopenharmony_ci result = 1; 259da0c48c4Sopenharmony_ci } 260da0c48c4Sopenharmony_ci 261da0c48c4Sopenharmony_ci if (shdr->sh_entsize != 0) 262da0c48c4Sopenharmony_ci { 263da0c48c4Sopenharmony_ci printf ("section %zd's entsize differs\n", cnt); 264da0c48c4Sopenharmony_ci result = 1; 265da0c48c4Sopenharmony_ci } 266da0c48c4Sopenharmony_ci } 267da0c48c4Sopenharmony_ci 268da0c48c4Sopenharmony_ci out_close2: 269da0c48c4Sopenharmony_ci elf_end (elf); 270da0c48c4Sopenharmony_ci out_close: 271da0c48c4Sopenharmony_ci close (fd); 272da0c48c4Sopenharmony_ci out: 273da0c48c4Sopenharmony_ci /* We don't need the file anymore. */ 274da0c48c4Sopenharmony_ci unlink (fname); 275da0c48c4Sopenharmony_ci 276da0c48c4Sopenharmony_ci ebl_closebackend (ebl); 277da0c48c4Sopenharmony_ci 278da0c48c4Sopenharmony_ci return result; 279da0c48c4Sopenharmony_ci} 280