1 /* Create new ABS 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_abs_scn = 30 { 31 .data = { 32 .main = { 33 .scn = ASM_ABS_SCN 34 } 35 } 36 }; 37 38 39 AsmSym_t * 40 asm_newabssym (ctx, name, size, value, type, binding) 41 AsmCtx_t *ctx; 42 const char *name; 43 GElf_Xword size; 44 GElf_Addr value; 45 int type; 46 int binding; 47 { 48 AsmSym_t *result; 49 50 if (ctx == NULL) 51 /* Something went wrong before. */ 52 return NULL; 53 54 /* Common symbols are public. Therefore the user must provide a 55 name. */ 56 if (name == NULL) 57 { 58 __libasm_seterrno (ASM_E_INVALID); 59 return NULL; 60 } 61 62 rwlock_wrlock (ctx->lock); 63 64 result = (AsmSym_t *) malloc (sizeof (AsmSym_t)); 65 if (result == NULL) 66 return NULL; 67 68 result->scn = (AsmScn_t *) &__libasm_abs_scn; 69 result->size = size; 70 result->type = type; 71 result->binding = binding; 72 result->symidx = 0; 73 result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0); 74 75 /* The value of an ABS symbol must not be modified. Since there are 76 no subsection and the initial offset of the section is 0 we can 77 get the alignment recorded by storing it into the offset 78 field. */ 79 result->offset = value; 80 81 if (unlikely (ctx->textp)) 82 { 83 /* An absolute symbol can be defined by giving a symbol a 84 specific value. */ 85 if (binding == STB_GLOBAL) 86 fprintf (ctx->out.file, "\t.globl %s\n", name); 87 else if (binding == STB_WEAK) 88 fprintf (ctx->out.file, "\t.weak %s\n", name); 89 90 if (type == STT_OBJECT) 91 fprintf (ctx->out.file, "\t.type %s,@object\n", name); 92 else if (type == STT_FUNC) 93 fprintf (ctx->out.file, "\t.type %s,@function\n", name); 94 95 fprintf (ctx->out.file, "%s = %llu\n", 96 name, (unsigned long long int) value); 97 98 if (size != 0) 99 fprintf (ctx->out.file, "\t.size %s, %llu\n", 100 name, (unsigned long long int) size); 101 } 102 else 103 { 104 /* Put the symbol in the hash table so that we can later find it. */ 105 if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result) 106 != 0) 107 { 108 /* The symbol already exists. */ 109 __libasm_seterrno (ASM_E_DUPLSYM); 110 free (result); 111 result = NULL; 112 } 113 else if (name != NULL && asm_emit_symbol_p (name)) 114 /* Only count non-private symbols. */ 115 ++ctx->nsymbol_tab; 116 } 117 118 rwlock_unlock (ctx->lock); 119 120 return result; 121 } 122