Home | History | Annotate | Download | only in src
      1 /* Macros to enable writing native and generic ELF access code.
      2    Copyright (C) 2003 Red Hat, Inc.
      3    This file is part of elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 2003.
      5 
      6    This file is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    elfutils is distributed in the hope that it will be useful, but
     12    WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18 
     19 #ifdef HAVE_CONFIG_H
     20 # include <config.h>
     21 #endif
     22 
     23 #include <libebl.h>
     24 
     25 
     26 /* By default the linker is handling all architectures.  But it can
     27    be configured to be a native-only linker.  */
     28 #if NATIVE_ELF == 32
     29 /* 32-bit only.  */
     30 # define XElf_Ehdr Elf32_Ehdr
     31 # define XElf_Shdr Elf32_Shdr
     32 # define XElf_Off Elf32_Off
     33 # define XElf_Addr Elf32_Addr
     34 # define XElf_Half Elf32_Half
     35 # define XElf_Word Elf32_Word
     36 # define XElf_Xword Elf32_Word
     37 # define XElf_Sxword Elf32_Sword
     38 # define XElf_Versym Elf32_Versym
     39 # define XElf_Sym Elf32_Sym
     40 # define XElf_Rel Elf32_Rel
     41 # define XElf_Rela Elf32_Rela
     42 
     43 # define XElf_Ehdr_vardef(name) Elf32_Ehdr *name
     44 # define xelf_getehdr(elf, name) name = elf32_getehdr (elf)
     45 # define xelf_getehdr_copy(elf, name, copy) \
     46   (copy) = *(name = elf32_getehdr (elf))
     47 # define xelf_newehdr(elf, klass) elf32_newehdr (elf)
     48 # define xelf_update_ehdr(elf, ehdr) \
     49   /* nothing */ ((void) (elf), (void) (ehdr), 1)
     50 
     51 # define xelf_getclass(elf) ELFCLASS32
     52 
     53 # define XElf_Phdr_vardef(name) Elf32_Phdr *name
     54 # define xelf_newphdr(elf, n) elf32_newphdr (elf, n)
     55 # define xelf_getphdr(elf, idx, name) name = elf32_getphdr (elf) + idx
     56 # define xelf_getphdr_ptr(elf, idx, name) name = elf32_getphdr (elf) + idx
     57 # define xelf_update_phdr(elf, idx, phdr) \
     58   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
     59 
     60 # define XElf_Shdr_vardef(name) Elf32_Shdr *name
     61 # define xelf_getshdr(scn, name) name = elf32_getshdr (scn)
     62 # define xelf_getshdr_copy(scn, name, copy) \
     63   (copy) = *(name = elf32_getshdr (scn))
     64 # define xelf_update_shdr(scn, shdr) \
     65   /* nothing */ ((void) (scn), (void) (shdr), 1)
     66 
     67 # define XElf_Sym_vardef(name) Elf32_Sym *name
     68 # define xelf_getsym(data, idx, name) \
     69   name = &((Elf32_Sym *) (data)->d_buf)[idx]
     70 # define xelf_getsym_ptr(data, idx, name) \
     71   name = &((Elf32_Sym *) (data)->d_buf)[idx]
     72 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
     73   (name1 = &((Elf32_Sym *) ((data)->d_buf))[idx]);			      \
     74   name2 = (unlikely ((ndxdata) != NULL)					      \
     75 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
     76 # define xelf_update_sym(data, idx, sym) \
     77   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
     78 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
     79   if (datachanged)							      \
     80     ((Elf32_Sym *) ((data)->d_buf))[idx] = *name1;			      \
     81   if (unlikely (ndxdata != NULL))					      \
     82     ((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2
     83 
     84 # define XElf_Versym_vardef(name) Elf32_Versym name
     85 # define xelf_getversym_copy(data, idx, name) \
     86   (name = ((Elf32_Versym *) ((data)->d_buf))[idx], &name)
     87 
     88 # define XElf_Dyn_vardef(name) Elf32_Dyn *name
     89 # define xelf_getdyn(data, idx, name) \
     90   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
     91 # define xelf_getdyn_ptr(data, idx, name) \
     92   name = &((Elf32_Dyn *) ((data)->d_buf))[idx]
     93 # define xelf_update_dyn(data, idx, name) \
     94   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
     95 
     96 # define XElf_Rel_vardef(name) Elf32_Rel *name
     97 # define xelf_getrel(data, idx, name) \
     98   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
     99 # define xelf_getrel_ptr(data, idx, name) \
    100   name = &((Elf32_Rel *) ((data)->d_buf))[idx]
    101 # define xelf_update_rel(data, idx, name) \
    102   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    103 
    104 # define XElf_Rela_vardef(name) Elf32_Rela *name
    105 # define xelf_getrela(data, idx, name) \
    106   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
    107 # define xelf_getrela_ptr(data, idx, name) \
    108   name = &((Elf32_Rela *) ((data)->d_buf))[idx]
    109 # define xelf_update_rela(data, idx, name) \
    110   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    111 
    112 # define XElf_Verdef_vardef(name) Elf32_Verdef *name
    113 # define xelf_getverdef(data, offset, name) \
    114   name = ((Elf32_Verdef *) ((char *) ((data)->d_buf) + (offset)))
    115 
    116 # define XElf_Verdaux_vardef(name) Elf32_Verdaux *name
    117 # define xelf_getverdaux(data, offset, name) \
    118   name = ((Elf32_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
    119 
    120 # define XELF_ST_TYPE(info) ELF32_ST_TYPE (info)
    121 # define XELF_ST_BIND(info) ELF32_ST_BIND (info)
    122 # define XELF_ST_INFO(bind, type) ELF32_ST_INFO (bind, type)
    123 # define XELF_ST_VISIBILITY(info) ELF32_ST_VISIBILITY (info)
    124 
    125 # define XELF_R_SYM(info) ELF32_R_SYM (info)
    126 # define XELF_R_TYPE(info) ELF32_R_TYPE (info)
    127 # define XELF_R_INFO(sym, type) ELF32_R_INFO (sym, type)
    128 
    129 # define xelf_fsize(elf, type, cnt) \
    130   (__builtin_constant_p (type)						      \
    131    ? ({ size_t fsize;							      \
    132         switch (type)							      \
    133 	  {								      \
    134 	  case ELF_T_BYTE: fsize = 1; break;				      \
    135 	  case ELF_T_ADDR: fsize = sizeof (Elf32_Addr); break;		      \
    136 	  case ELF_T_DYN: fsize = sizeof (Elf32_Dyn); break;		      \
    137 	  case ELF_T_EHDR: fsize = sizeof (Elf32_Ehdr); break;		      \
    138 	  case ELF_T_HALF: fsize = sizeof (Elf32_Half); break;		      \
    139 	  case ELF_T_OFF: fsize = sizeof (Elf32_Off); break;		      \
    140 	  case ELF_T_PHDR: fsize = sizeof (Elf32_Phdr); break;		      \
    141 	  case ELF_T_RELA: fsize = sizeof (Elf32_Rela); break;		      \
    142 	  case ELF_T_REL: fsize = sizeof (Elf32_Rel); break;		      \
    143 	  case ELF_T_SHDR: fsize = sizeof (Elf32_Shdr); break;		      \
    144 	  case ELF_T_SWORD: fsize = sizeof (Elf32_Sword); break;	      \
    145 	  case ELF_T_SYM: fsize = sizeof (Elf32_Sym); break;		      \
    146 	  case ELF_T_WORD: fsize = sizeof (Elf32_Word); break;		      \
    147 	  case ELF_T_XWORD: fsize = sizeof (Elf32_Xword); break;	      \
    148 	  case ELF_T_SXWORD: fsize = sizeof (Elf32_Sxword); break;	      \
    149 	  case ELF_T_VDEF: fsize = sizeof (Elf32_Verdef); break;	      \
    150 	  case ELF_T_VDAUX: fsize = sizeof (Elf32_Verdaux); break;	      \
    151 	  case ELF_T_VNEED: fsize = sizeof (Elf32_Verneed); break;	      \
    152 	  case ELF_T_VNAUX: fsize = sizeof (Elf32_Vernaux); break;	      \
    153 	  case ELF_T_NHDR: fsize = sizeof (Elf32_Nhdr); break;		      \
    154 	  case ELF_T_SYMINFO: fsize = sizeof (Elf32_Syminfo); break;	      \
    155 	  case ELF_T_MOVE: fsize = sizeof (Elf32_Move); break;		      \
    156           default: fsize = 0; break;					      \
    157 	  }								      \
    158         fsize * (cnt); })						      \
    159    : gelf_fsize (elf, type, cnt, EV_CURRENT))
    160 #elif NATIVE_ELF == 64
    161 /* 64-bit only.  */
    162 # define XElf_Ehdr Elf64_Ehdr
    163 # define XElf_Shdr Elf64_Shdr
    164 # define XElf_Addr Elf64_Addr
    165 # define XElf_Half Elf64_Half
    166 # define XElf_Off Elf64_Off
    167 # define XElf_Word Elf64_Word
    168 # define XElf_Xword Elf64_Xword
    169 # define XElf_Sxword Elf64_Sxword
    170 # define XElf_Versym Elf64_Versym
    171 # define XElf_Sym Elf64_Sym
    172 # define XElf_Rel Elf64_Rel
    173 # define XElf_Rela Elf64_Rela
    174 
    175 # define XElf_Ehdr_vardef(name) Elf64_Ehdr *name
    176 # define xelf_getehdr(elf, name) name = elf64_getehdr (elf)
    177 # define xelf_getehdr_copy(elf, name, copy) \
    178   (copy) = *(name = elf64_getehdr (elf))
    179 # define xelf_newehdr(elf, klass) elf64_newehdr (elf)
    180 # define xelf_update_ehdr(elf, ehdr) \
    181   /* nothing */ ((void) (elf), (void) (ehdr), 1)
    182 
    183 # define xelf_getclass(elf) ELFCLASS32
    184 
    185 # define XElf_Phdr_vardef(name) Elf64_Phdr *name
    186 # define xelf_newphdr(elf, n) elf64_newphdr (elf, n)
    187 # define xelf_getphdr(elf, idx, name) name = elf64_getphdr (elf) + idx
    188 # define xelf_getphdr_ptr(elf, idx, name) name = elf64_getphdr (elf) + idx
    189 # define xelf_update_phdr(elf, idx, phdr) \
    190   /* nothing */ ((void) (elf), (void) (idx), (void) (phdr), 1)
    191 
    192 # define XElf_Shdr_vardef(name) Elf64_Shdr *name
    193 # define xelf_getshdr(scn, name) name = elf64_getshdr (scn)
    194 # define xelf_getshdr_copy(scn, name, copy) \
    195   (copy) = *(name = elf64_getshdr (scn))
    196 # define xelf_update_shdr(scn, shdr) \
    197   /* nothing */ ((void) (scn), (void) (shdr), 1)
    198 
    199 # define XElf_Sym_vardef(name) Elf64_Sym *name
    200 # define xelf_getsym(data, idx, name) \
    201   name = &((Elf64_Sym *) (data)->d_buf)[idx]
    202 # define xelf_getsym_ptr(data, idx, name) \
    203   name = &((Elf64_Sym *) (data)->d_buf)[idx]
    204 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
    205   (name1 = &((Elf64_Sym *) ((data)->d_buf))[idx]);			      \
    206   name2 = (unlikely ((ndxdata) != NULL)					      \
    207 	   ? ((Elf32_Word *) ((ndxdata)->d_buf))[idx] : 0)
    208 # define xelf_update_sym(data, idx, sym) \
    209   /* nothing */ ((void) (data), (void) (idx), (void) (sym), 1)
    210 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
    211   if (datachanged)							      \
    212     ((Elf64_Sym *) ((data)->d_buf))[idx] = *name1;			      \
    213   if (ndxdata != NULL)							      \
    214     (((Elf32_Word *) ((ndxdata)->d_buf))[idx] = name2)
    215 
    216 # define XElf_Versym_vardef(name) Elf64_Versym name
    217 # define xelf_getversym_copy(data, idx, name) \
    218   (name = ((Elf64_Versym *) ((data)->d_buf))[idx], (&name))
    219 
    220 # define XElf_Dyn_vardef(name) Elf64_Dyn *name
    221 # define xelf_getdyn(data, idx, name) \
    222   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
    223 # define xelf_getdyn_ptr(data, idx, name) \
    224   name = &((Elf64_Dyn *) ((data)->d_buf))[idx]
    225 # define xelf_update_dyn(data, idx, name) \
    226   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    227 
    228 # define XElf_Rel_vardef(name) Elf64_Rel *name
    229 # define xelf_getrel(data, idx, name) \
    230   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
    231 # define xelf_getrel_ptr(data, idx, name) \
    232   name = &((Elf64_Rel *) ((data)->d_buf))[idx]
    233 # define xelf_update_rel(data, idx, name) \
    234   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    235 
    236 # define XElf_Rela_vardef(name) Elf64_Rela *name
    237 # define xelf_getrela(data, idx, name) \
    238   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
    239 # define xelf_getrela_ptr(data, idx, name) \
    240   name = &((Elf64_Rela *) ((data)->d_buf))[idx]
    241 # define xelf_update_rela(data, idx, name) \
    242   /* nothing */ ((void) (data), (void) (idx), (void) (name), 1)
    243 
    244 # define XElf_Verdef_vardef(name) Elf64_Verdef *name
    245 # define xelf_getverdef(data, offset, name) \
    246   name = ((Elf64_Verdef *) ((char *) ((data)->d_buf) + (offset)))
    247 
    248 # define XElf_Verdaux_vardef(name) Elf64_Verdaux *name
    249 # define xelf_getverdaux(data, offset, name) \
    250   name = ((Elf64_Verdaux *) ((char *) ((data)->d_buf) + (offset)))
    251 
    252 # define XELF_ST_TYPE(info) ELF64_ST_TYPE (info)
    253 # define XELF_ST_BIND(info) ELF64_ST_BIND (info)
    254 # define XELF_ST_INFO(bind, type) ELF64_ST_INFO (bind, type)
    255 # define XELF_ST_VISIBILITY(info) ELF64_ST_VISIBILITY (info)
    256 
    257 # define XELF_R_SYM(info) ELF64_R_SYM (info)
    258 # define XELF_R_TYPE(info) ELF64_R_TYPE (info)
    259 # define XELF_R_INFO(sym, type) ELF64_R_INFO (sym, type)
    260 
    261 # define xelf_fsize(elf, type, cnt) \
    262   (__builtin_constant_p (type)						      \
    263    ? ({ size_t fsize;							      \
    264         switch (type)							      \
    265 	  {								      \
    266 	  case ELF_T_BYTE: fsize = 1; break;				      \
    267 	  case ELF_T_ADDR: fsize = sizeof (Elf64_Addr); break;		      \
    268 	  case ELF_T_DYN: fsize = sizeof (Elf64_Dyn); break;		      \
    269 	  case ELF_T_EHDR: fsize = sizeof (Elf64_Ehdr); break;		      \
    270 	  case ELF_T_HALF: fsize = sizeof (Elf64_Half); break;		      \
    271 	  case ELF_T_OFF: fsize = sizeof (Elf64_Off); break;		      \
    272 	  case ELF_T_PHDR: fsize = sizeof (Elf64_Phdr); break;		      \
    273 	  case ELF_T_RELA: fsize = sizeof (Elf64_Rela); break;		      \
    274 	  case ELF_T_REL: fsize = sizeof (Elf64_Rel); break;		      \
    275 	  case ELF_T_SHDR: fsize = sizeof (Elf64_Shdr); break;		      \
    276 	  case ELF_T_SWORD: fsize = sizeof (Elf64_Sword); break;	      \
    277 	  case ELF_T_SYM: fsize = sizeof (Elf64_Sym); break;		      \
    278 	  case ELF_T_WORD: fsize = sizeof (Elf64_Word); break;		      \
    279 	  case ELF_T_XWORD: fsize = sizeof (Elf64_Xword); break;	      \
    280 	  case ELF_T_SXWORD: fsize = sizeof (Elf64_Sxword); break;	      \
    281 	  case ELF_T_VDEF: fsize = sizeof (Elf64_Verdef); break;	      \
    282 	  case ELF_T_VDAUX: fsize = sizeof (Elf64_Verdaux); break;	      \
    283 	  case ELF_T_VNEED: fsize = sizeof (Elf64_Verneed); break;	      \
    284 	  case ELF_T_VNAUX: fsize = sizeof (Elf64_Vernaux); break;	      \
    285 	  case ELF_T_NHDR: fsize = sizeof (Elf64_Nhdr); break;		      \
    286 	  case ELF_T_SYMINFO: fsize = sizeof (Elf64_Syminfo); break;	      \
    287 	  case ELF_T_MOVE: fsize = sizeof (Elf64_Move); break;		      \
    288           default: fsize = 0; break;					      \
    289 	  }								      \
    290         fsize * (cnt); })						      \
    291    : gelf_fsize (elf, type, cnt, EV_CURRENT))
    292 #else
    293 # include <gelf.h>
    294 
    295 /* Generic linker.  */
    296 # define XElf_Ehdr GElf_Ehdr
    297 # define XElf_Shdr GElf_Shdr
    298 # define XElf_Addr GElf_Addr
    299 # define XElf_Half GElf_Half
    300 # define XElf_Off GElf_Off
    301 # define XElf_Word GElf_Word
    302 # define XElf_Xword GElf_Xword
    303 # define XElf_Sxword GElf_Sxword
    304 # define XElf_Versym GElf_Versym
    305 # define XElf_Sym GElf_Sym
    306 # define XElf_Rel GElf_Rel
    307 # define XElf_Rela GElf_Rela
    308 
    309 # define XElf_Ehdr_vardef(name) GElf_Ehdr name##_mem; GElf_Ehdr *name
    310 # define xelf_getehdr(elf, name) name = gelf_getehdr (elf, &name##_mem)
    311 # define xelf_getehdr_copy(elf, name, copy) \
    312   name = gelf_getehdr (elf, &(copy))
    313 # define xelf_newehdr(elf, klass) gelf_newehdr (elf, klass)
    314 # define xelf_update_ehdr(elf, ehdr) gelf_update_ehdr (elf, ehdr)
    315 
    316 # define xelf_getclass(elf) gelf_getclass (elf)
    317 
    318 # define XElf_Phdr_vardef(name) GElf_Phdr name##_mem; GElf_Phdr *name
    319 # define xelf_newphdr(elf, n) gelf_newphdr (elf, n)
    320 # define xelf_getphdr(elf, idx, name) \
    321   name = gelf_getphdr (elf, idx, &name##_mem)
    322 # define xelf_getphdr_ptr(elf, idx, name) \
    323   name = &name##_mem
    324 # define xelf_update_phdr(elf, idx, phdr) \
    325   gelf_update_phdr (elf, idx, phdr)
    326 
    327 # define XElf_Shdr_vardef(name) GElf_Shdr name##_mem; GElf_Shdr *name
    328 # define xelf_getshdr(scn, name) name = gelf_getshdr (scn, &name##_mem)
    329 # define xelf_getshdr_copy(scn, name, copy) \
    330   name = gelf_getshdr (scn, &(copy))
    331 # define xelf_update_shdr(scn, shdr) gelf_update_shdr (scn, shdr)
    332 
    333 # define XElf_Sym_vardef(name) GElf_Sym name##_mem; GElf_Sym *name
    334 # define xelf_getsym(data, idx, name) \
    335   name = gelf_getsym (data, idx, &name##_mem)
    336 # define xelf_getsym_ptr(data, idx, name) \
    337   name = &name##_mem
    338 # define xelf_getsymshndx(data, ndxdata, idx, name1, name2) \
    339   name1 = gelf_getsymshndx (data, ndxdata, idx, &name1##_mem, &(name2))
    340 # define xelf_update_sym(data, idx, sym) gelf_update_sym (data, idx, sym)
    341 # define xelf_update_symshndx(data, ndxdata, idx, name1, name2, datachanged) \
    342   gelf_update_symshndx (data, ndxdata, idx, name1, name2)
    343 
    344 # define XElf_Versym_vardef(name) GElf_Versym name
    345 # define xelf_getversym_copy(data, idx, name) \
    346   gelf_getversym (data, idx, &name)
    347 
    348 # define XElf_Dyn_vardef(name) GElf_Dyn name##_mem; GElf_Dyn *name
    349 # define xelf_getdyn(data, idx, name) \
    350   name = gelf_getdyn (data, idx, &name##_mem)
    351 # define xelf_getdyn_ptr(data, idx, name) \
    352   name = &name##_mem
    353 # define xelf_update_dyn(data, idx, name) \
    354   gelf_update_dyn (data, idx, name)
    355 
    356 # define XElf_Rel_vardef(name) GElf_Rel name##_mem; GElf_Rel *name
    357 # define xelf_getrel(data, idx, name) \
    358   name = gelf_getrel (data, idx, &name##_mem)
    359 # define xelf_getrel_ptr(data, idx, name) \
    360   name = &name##_mem
    361 # define xelf_update_rel(data, idx, name) \
    362   gelf_update_rel (data, idx, name)
    363 
    364 # define XElf_Rela_vardef(name) GElf_Rela name##_mem; GElf_Rela *name
    365 # define xelf_getrela(data, idx, name) \
    366   name = gelf_getrela (data, idx, &name##_mem)
    367 # define xelf_getrela_ptr(data, idx, name) \
    368   name = &name##_mem
    369 # define xelf_update_rela(data, idx, name) \
    370   gelf_update_rela (data, idx, name)
    371 
    372 # define XElf_Verdef_vardef(name) GElf_Verdef name##_mem; GElf_Verdef *name
    373 # define xelf_getverdef(data, offset, name) \
    374   name = gelf_getverdef (data, offset, &name##_mem)
    375 
    376 # define XElf_Verdaux_vardef(name) GElf_Verdaux name##_mem; GElf_Verdaux *name
    377 # define xelf_getverdaux(data, offset, name) \
    378   name = gelf_getverdaux (data, offset, &name##_mem)
    379 
    380 # define XELF_ST_TYPE(info) GELF_ST_TYPE (info)
    381 # define XELF_ST_BIND(info) GELF_ST_BIND (info)
    382 # define XELF_ST_INFO(bind, type) GELF_ST_INFO (bind, type)
    383 # define XELF_ST_VISIBILITY(info) GELF_ST_VISIBILITY (info)
    384 
    385 # define XELF_R_SYM(info) GELF_R_SYM (info)
    386 # define XELF_R_TYPE(info) GELF_R_TYPE (info)
    387 # define XELF_R_INFO(sym, type) GELF_R_INFO (sym, type)
    388 
    389 # define xelf_fsize(elf, type, cnt) \
    390   gelf_fsize (elf, type, cnt, EV_CURRENT)
    391 #endif
    392