1 /* Create new COMMON symbol. 2 Copyright (C) 2002 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) redhat.com>, 2002. 4 5 This program is Open Source software; you can redistribute it and/or 6 modify it under the terms of the Open Software License version 1.0 as 7 published by the Open Source Initiative. 8 9 You should have received a copy of the Open Software License along 10 with this program; if not, you may obtain a copy of the Open Software 11 License version 1.0 from http://www.opensource.org/licenses/osl.php or 12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13 3001 King Ranch Road, Ukiah, CA 95482. */ 14 15 #ifdef HAVE_CONFIG_H 16 # include <config.h> 17 #endif 18 19 #include <inttypes.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include <libasmP.h> 25 #include <system.h> 26 27 28 /* Object for special COMMON section. */ 29 static const AsmScn_t __libasm_com_scn = 30 { 31 .data = { 32 .main = { 33 .scn = ASM_COM_SCN 34 } 35 } 36 }; 37 38 39 AsmSym_t * 40 asm_newcomsym (ctx, name, size, align) 41 AsmCtx_t *ctx; 42 const char *name; 43 GElf_Xword size; 44 GElf_Addr align; 45 { 46 AsmSym_t *result; 47 48 if (ctx == NULL) 49 /* Something went wrong before. */ 50 return NULL; 51 52 /* Common symbols are public. Therefore the user must provide a 53 name. */ 54 if (name == NULL) 55 { 56 __libasm_seterrno (ASM_E_INVALID); 57 return NULL; 58 } 59 60 rwlock_wrlock (ctx->lock); 61 62 result = (AsmSym_t *) malloc (sizeof (AsmSym_t)); 63 if (result == NULL) 64 return NULL; 65 66 result->scn = (AsmScn_t *) &__libasm_com_scn; 67 result->size = size; 68 /* XXX Do we have to allow a different type? */ 69 result->type = STT_OBJECT; 70 /* XXX Do we have to allow a different binding? */ 71 result->binding = STB_GLOBAL; 72 result->symidx = 0; 73 result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0); 74 75 /* The value of a COM symbol is the alignment. Since there are no 76 subsection and the initial offset of the section is 0 we can get 77 the alignment recorded by storing it into the offset field. */ 78 result->offset = align; 79 80 if (unlikely (ctx->textp)) 81 fprintf (ctx->out.file, "\t.comm %s, %" PRIuMAX ", %" PRIuMAX "\n", 82 name, (uintmax_t) size, (uintmax_t) align); 83 else 84 { 85 /* Put the symbol in the hash table so that we can later find it. */ 86 if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result) 87 != 0) 88 { 89 /* The symbol already exists. */ 90 __libasm_seterrno (ASM_E_DUPLSYM); 91 free (result); 92 result = NULL; 93 } 94 else if (name != NULL && asm_emit_symbol_p (name)) 95 /* Only count non-private symbols. */ 96 ++ctx->nsymbol_tab; 97 } 98 99 rwlock_unlock (ctx->lock); 100 101 return result; 102 } 103